All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.dist.graphology.umd.min.js.map Maven / Gradle / Ivy

The newest version!
{"version":3,"file":"graphology.umd.min.js","sources":["../src/utils.js","../../../node_modules/events/events.js","../../../node_modules/obliterator/iterator.js","../../../node_modules/obliterator/support.js","../../../node_modules/obliterator/iter.js","../../../node_modules/obliterator/take.js","../src/errors.js","../src/data.js","../src/attributes/nodes.js","../src/attributes/edges.js","../../../node_modules/obliterator/chain.js","../src/iteration/edges.js","../src/iteration/neighbors.js","../src/iteration/adjacency.js","../src/serialization.js","../src/graph.js","../src/classes.js"],"sourcesContent":["/**\n * Graphology Utilities\n * =====================\n *\n * Collection of helpful functions used by the implementation.\n */\n\n/**\n * Object.assign-like polyfill.\n *\n * @param  {object} target       - First object.\n * @param  {object} [...objects] - Objects to merge.\n * @return {object}\n */\nfunction assignPolyfill() {\n  const target = arguments[0];\n\n  for (let i = 1, l = arguments.length; i < l; i++) {\n    if (!arguments[i]) continue;\n\n    for (const k in arguments[i]) target[k] = arguments[i][k];\n  }\n\n  return target;\n}\n\nlet assign = assignPolyfill;\n\nif (typeof Object.assign === 'function') assign = Object.assign;\n\nexport {assign};\n\n/**\n * Function returning the first matching edge for given path.\n * Note: this function does not check the existence of source & target. This\n * must be performed by the caller.\n *\n * @param  {Graph}  graph  - Target graph.\n * @param  {any}    source - Source node.\n * @param  {any}    target - Target node.\n * @param  {string} type   - Type of the edge (mixed, directed or undirected).\n * @return {string|null}\n */\nexport function getMatchingEdge(graph, source, target, type) {\n  const sourceData = graph._nodes.get(source);\n\n  let edge = null;\n\n  if (!sourceData) return edge;\n\n  if (type === 'mixed') {\n    edge =\n      (sourceData.out && sourceData.out[target]) ||\n      (sourceData.undirected && sourceData.undirected[target]);\n  } else if (type === 'directed') {\n    edge = sourceData.out && sourceData.out[target];\n  } else {\n    edge = sourceData.undirected && sourceData.undirected[target];\n  }\n\n  return edge;\n}\n\n/**\n * Checks whether the given value is a plain object.\n *\n * @param  {mixed}   value - Target value.\n * @return {boolean}\n */\nexport function isPlainObject(value) {\n  // NOTE: as per https://github.com/graphology/graphology/issues/149\n  // this function has been loosened not to reject object instances\n  // coming from other JavaScript contexts. It has also been chosen\n  // not to improve it to avoid obvious false positives and avoid\n  // taking a performance hit. People should really use TypeScript\n  // if they want to avoid feeding subtly irrelvant attribute objects.\n  return typeof value === 'object' && value !== null;\n}\n\n/**\n * Checks whether the given object is empty.\n *\n * @param  {object}  o - Target Object.\n * @return {boolean}\n */\nexport function isEmpty(o) {\n  let k;\n\n  for (k in o) return false;\n\n  return true;\n}\n\n/**\n * Creates a \"private\" property for the given member name by concealing it\n * using the `enumerable` option.\n *\n * @param {object} target - Target object.\n * @param {string} name   - Member name.\n */\nexport function privateProperty(target, name, value) {\n  Object.defineProperty(target, name, {\n    enumerable: false,\n    configurable: false,\n    writable: true,\n    value\n  });\n}\n\n/**\n * Creates a read-only property for the given member name & the given getter.\n *\n * @param {object}   target - Target object.\n * @param {string}   name   - Member name.\n * @param {mixed}    value  - The attached getter or fixed value.\n */\nexport function readOnlyProperty(target, name, value) {\n  const descriptor = {\n    enumerable: true,\n    configurable: true\n  };\n\n  if (typeof value === 'function') {\n    descriptor.get = value;\n  } else {\n    descriptor.value = value;\n    descriptor.writable = false;\n  }\n\n  Object.defineProperty(target, name, descriptor);\n}\n\n/**\n * Returns whether the given object constitute valid hints.\n *\n * @param {object} hints - Target object.\n */\nexport function validateHints(hints) {\n  if (!isPlainObject(hints)) return false;\n\n  if (hints.attributes && !Array.isArray(hints.attributes)) return false;\n\n  return true;\n}\n\n/**\n * Creates a function generating incremental ids for edges.\n *\n * @return {function}\n */\nexport function incrementalIdStartingFromRandomByte() {\n  let i = Math.floor(Math.random() * 256) & 0xff;\n\n  return () => {\n    return i++;\n  };\n}\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nvar R = typeof Reflect === 'object' ? Reflect : null\nvar ReflectApply = R && typeof R.apply === 'function'\n  ? R.apply\n  : function ReflectApply(target, receiver, args) {\n    return Function.prototype.apply.call(target, receiver, args);\n  }\n\nvar ReflectOwnKeys\nif (R && typeof R.ownKeys === 'function') {\n  ReflectOwnKeys = R.ownKeys\n} else if (Object.getOwnPropertySymbols) {\n  ReflectOwnKeys = function ReflectOwnKeys(target) {\n    return Object.getOwnPropertyNames(target)\n      .concat(Object.getOwnPropertySymbols(target));\n  };\n} else {\n  ReflectOwnKeys = function ReflectOwnKeys(target) {\n    return Object.getOwnPropertyNames(target);\n  };\n}\n\nfunction ProcessEmitWarning(warning) {\n  if (console && console.warn) console.warn(warning);\n}\n\nvar NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {\n  return value !== value;\n}\n\nfunction EventEmitter() {\n  EventEmitter.init.call(this);\n}\nmodule.exports = EventEmitter;\nmodule.exports.once = once;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._eventsCount = 0;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nvar defaultMaxListeners = 10;\n\nfunction checkListener(listener) {\n  if (typeof listener !== 'function') {\n    throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n  }\n}\n\nObject.defineProperty(EventEmitter, 'defaultMaxListeners', {\n  enumerable: true,\n  get: function() {\n    return defaultMaxListeners;\n  },\n  set: function(arg) {\n    if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {\n      throw new RangeError('The value of \"defaultMaxListeners\" is out of range. It must be a non-negative number. Received ' + arg + '.');\n    }\n    defaultMaxListeners = arg;\n  }\n});\n\nEventEmitter.init = function() {\n\n  if (this._events === undefined ||\n      this._events === Object.getPrototypeOf(this)._events) {\n    this._events = Object.create(null);\n    this._eventsCount = 0;\n  }\n\n  this._maxListeners = this._maxListeners || undefined;\n};\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {\n  if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {\n    throw new RangeError('The value of \"n\" is out of range. It must be a non-negative number. Received ' + n + '.');\n  }\n  this._maxListeners = n;\n  return this;\n};\n\nfunction _getMaxListeners(that) {\n  if (that._maxListeners === undefined)\n    return EventEmitter.defaultMaxListeners;\n  return that._maxListeners;\n}\n\nEventEmitter.prototype.getMaxListeners = function getMaxListeners() {\n  return _getMaxListeners(this);\n};\n\nEventEmitter.prototype.emit = function emit(type) {\n  var args = [];\n  for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);\n  var doError = (type === 'error');\n\n  var events = this._events;\n  if (events !== undefined)\n    doError = (doError && events.error === undefined);\n  else if (!doError)\n    return false;\n\n  // If there is no 'error' event listener then throw.\n  if (doError) {\n    var er;\n    if (args.length > 0)\n      er = args[0];\n    if (er instanceof Error) {\n      // Note: The comments on the `throw` lines are intentional, they show\n      // up in Node's output if this results in an unhandled exception.\n      throw er; // Unhandled 'error' event\n    }\n    // At least give some kind of context to the user\n    var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));\n    err.context = er;\n    throw err; // Unhandled 'error' event\n  }\n\n  var handler = events[type];\n\n  if (handler === undefined)\n    return false;\n\n  if (typeof handler === 'function') {\n    ReflectApply(handler, this, args);\n  } else {\n    var len = handler.length;\n    var listeners = arrayClone(handler, len);\n    for (var i = 0; i < len; ++i)\n      ReflectApply(listeners[i], this, args);\n  }\n\n  return true;\n};\n\nfunction _addListener(target, type, listener, prepend) {\n  var m;\n  var events;\n  var existing;\n\n  checkListener(listener);\n\n  events = target._events;\n  if (events === undefined) {\n    events = target._events = Object.create(null);\n    target._eventsCount = 0;\n  } else {\n    // To avoid recursion in the case that type === \"newListener\"! Before\n    // adding it to the listeners, first emit \"newListener\".\n    if (events.newListener !== undefined) {\n      target.emit('newListener', type,\n                  listener.listener ? listener.listener : listener);\n\n      // Re-assign `events` because a newListener handler could have caused the\n      // this._events to be assigned to a new object\n      events = target._events;\n    }\n    existing = events[type];\n  }\n\n  if (existing === undefined) {\n    // Optimize the case of one listener. Don't need the extra array object.\n    existing = events[type] = listener;\n    ++target._eventsCount;\n  } else {\n    if (typeof existing === 'function') {\n      // Adding the second element, need to change to array.\n      existing = events[type] =\n        prepend ? [listener, existing] : [existing, listener];\n      // If we've already got an array, just append.\n    } else if (prepend) {\n      existing.unshift(listener);\n    } else {\n      existing.push(listener);\n    }\n\n    // Check for listener leak\n    m = _getMaxListeners(target);\n    if (m > 0 && existing.length > m && !existing.warned) {\n      existing.warned = true;\n      // No error code for this since it is a Warning\n      // eslint-disable-next-line no-restricted-syntax\n      var w = new Error('Possible EventEmitter memory leak detected. ' +\n                          existing.length + ' ' + String(type) + ' listeners ' +\n                          'added. Use emitter.setMaxListeners() to ' +\n                          'increase limit');\n      w.name = 'MaxListenersExceededWarning';\n      w.emitter = target;\n      w.type = type;\n      w.count = existing.length;\n      ProcessEmitWarning(w);\n    }\n  }\n\n  return target;\n}\n\nEventEmitter.prototype.addListener = function addListener(type, listener) {\n  return _addListener(this, type, listener, false);\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.prependListener =\n    function prependListener(type, listener) {\n      return _addListener(this, type, listener, true);\n    };\n\nfunction onceWrapper() {\n  if (!this.fired) {\n    this.target.removeListener(this.type, this.wrapFn);\n    this.fired = true;\n    if (arguments.length === 0)\n      return this.listener.call(this.target);\n    return this.listener.apply(this.target, arguments);\n  }\n}\n\nfunction _onceWrap(target, type, listener) {\n  var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };\n  var wrapped = onceWrapper.bind(state);\n  wrapped.listener = listener;\n  state.wrapFn = wrapped;\n  return wrapped;\n}\n\nEventEmitter.prototype.once = function once(type, listener) {\n  checkListener(listener);\n  this.on(type, _onceWrap(this, type, listener));\n  return this;\n};\n\nEventEmitter.prototype.prependOnceListener =\n    function prependOnceListener(type, listener) {\n      checkListener(listener);\n      this.prependListener(type, _onceWrap(this, type, listener));\n      return this;\n    };\n\n// Emits a 'removeListener' event if and only if the listener was removed.\nEventEmitter.prototype.removeListener =\n    function removeListener(type, listener) {\n      var list, events, position, i, originalListener;\n\n      checkListener(listener);\n\n      events = this._events;\n      if (events === undefined)\n        return this;\n\n      list = events[type];\n      if (list === undefined)\n        return this;\n\n      if (list === listener || list.listener === listener) {\n        if (--this._eventsCount === 0)\n          this._events = Object.create(null);\n        else {\n          delete events[type];\n          if (events.removeListener)\n            this.emit('removeListener', type, list.listener || listener);\n        }\n      } else if (typeof list !== 'function') {\n        position = -1;\n\n        for (i = list.length - 1; i >= 0; i--) {\n          if (list[i] === listener || list[i].listener === listener) {\n            originalListener = list[i].listener;\n            position = i;\n            break;\n          }\n        }\n\n        if (position < 0)\n          return this;\n\n        if (position === 0)\n          list.shift();\n        else {\n          spliceOne(list, position);\n        }\n\n        if (list.length === 1)\n          events[type] = list[0];\n\n        if (events.removeListener !== undefined)\n          this.emit('removeListener', type, originalListener || listener);\n      }\n\n      return this;\n    };\n\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\n\nEventEmitter.prototype.removeAllListeners =\n    function removeAllListeners(type) {\n      var listeners, events, i;\n\n      events = this._events;\n      if (events === undefined)\n        return this;\n\n      // not listening for removeListener, no need to emit\n      if (events.removeListener === undefined) {\n        if (arguments.length === 0) {\n          this._events = Object.create(null);\n          this._eventsCount = 0;\n        } else if (events[type] !== undefined) {\n          if (--this._eventsCount === 0)\n            this._events = Object.create(null);\n          else\n            delete events[type];\n        }\n        return this;\n      }\n\n      // emit removeListener for all listeners on all events\n      if (arguments.length === 0) {\n        var keys = Object.keys(events);\n        var key;\n        for (i = 0; i < keys.length; ++i) {\n          key = keys[i];\n          if (key === 'removeListener') continue;\n          this.removeAllListeners(key);\n        }\n        this.removeAllListeners('removeListener');\n        this._events = Object.create(null);\n        this._eventsCount = 0;\n        return this;\n      }\n\n      listeners = events[type];\n\n      if (typeof listeners === 'function') {\n        this.removeListener(type, listeners);\n      } else if (listeners !== undefined) {\n        // LIFO order\n        for (i = listeners.length - 1; i >= 0; i--) {\n          this.removeListener(type, listeners[i]);\n        }\n      }\n\n      return this;\n    };\n\nfunction _listeners(target, type, unwrap) {\n  var events = target._events;\n\n  if (events === undefined)\n    return [];\n\n  var evlistener = events[type];\n  if (evlistener === undefined)\n    return [];\n\n  if (typeof evlistener === 'function')\n    return unwrap ? [evlistener.listener || evlistener] : [evlistener];\n\n  return unwrap ?\n    unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);\n}\n\nEventEmitter.prototype.listeners = function listeners(type) {\n  return _listeners(this, type, true);\n};\n\nEventEmitter.prototype.rawListeners = function rawListeners(type) {\n  return _listeners(this, type, false);\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n  if (typeof emitter.listenerCount === 'function') {\n    return emitter.listenerCount(type);\n  } else {\n    return listenerCount.call(emitter, type);\n  }\n};\n\nEventEmitter.prototype.listenerCount = listenerCount;\nfunction listenerCount(type) {\n  var events = this._events;\n\n  if (events !== undefined) {\n    var evlistener = events[type];\n\n    if (typeof evlistener === 'function') {\n      return 1;\n    } else if (evlistener !== undefined) {\n      return evlistener.length;\n    }\n  }\n\n  return 0;\n}\n\nEventEmitter.prototype.eventNames = function eventNames() {\n  return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];\n};\n\nfunction arrayClone(arr, n) {\n  var copy = new Array(n);\n  for (var i = 0; i < n; ++i)\n    copy[i] = arr[i];\n  return copy;\n}\n\nfunction spliceOne(list, index) {\n  for (; index + 1 < list.length; index++)\n    list[index] = list[index + 1];\n  list.pop();\n}\n\nfunction unwrapListeners(arr) {\n  var ret = new Array(arr.length);\n  for (var i = 0; i < ret.length; ++i) {\n    ret[i] = arr[i].listener || arr[i];\n  }\n  return ret;\n}\n\nfunction once(emitter, name) {\n  return new Promise(function (resolve, reject) {\n    function errorListener(err) {\n      emitter.removeListener(name, resolver);\n      reject(err);\n    }\n\n    function resolver() {\n      if (typeof emitter.removeListener === 'function') {\n        emitter.removeListener('error', errorListener);\n      }\n      resolve([].slice.call(arguments));\n    };\n\n    eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });\n    if (name !== 'error') {\n      addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });\n    }\n  });\n}\n\nfunction addErrorHandlerIfEventEmitter(emitter, handler, flags) {\n  if (typeof emitter.on === 'function') {\n    eventTargetAgnosticAddListener(emitter, 'error', handler, flags);\n  }\n}\n\nfunction eventTargetAgnosticAddListener(emitter, name, listener, flags) {\n  if (typeof emitter.on === 'function') {\n    if (flags.once) {\n      emitter.once(name, listener);\n    } else {\n      emitter.on(name, listener);\n    }\n  } else if (typeof emitter.addEventListener === 'function') {\n    // EventTarget does not have `error` event semantics like Node\n    // EventEmitters, we do not listen for `error` events here.\n    emitter.addEventListener(name, function wrapListener(arg) {\n      // IE does not have builtin `{ once: true }` support so we\n      // have to do it manually.\n      if (flags.once) {\n        emitter.removeEventListener(name, wrapListener);\n      }\n      listener(arg);\n    });\n  } else {\n    throw new TypeError('The \"emitter\" argument must be of type EventEmitter. Received type ' + typeof emitter);\n  }\n}\n","/**\n * Obliterator Iterator Class\n * ===========================\n *\n * Simple class representing the library's iterators.\n */\n\n/**\n * Iterator class.\n *\n * @constructor\n * @param {function} next - Next function.\n */\nfunction Iterator(next) {\n  if (typeof next !== 'function')\n    throw new Error('obliterator/iterator: expecting a function!');\n\n  this.next = next;\n}\n\n/**\n * If symbols are supported, we add `next` to `Symbol.iterator`.\n */\nif (typeof Symbol !== 'undefined')\n  Iterator.prototype[Symbol.iterator] = function () {\n    return this;\n  };\n\n/**\n * Returning an iterator of the given values.\n *\n * @param  {any...} values - Values.\n * @return {Iterator}\n */\nIterator.of = function () {\n  var args = arguments,\n    l = args.length,\n    i = 0;\n\n  return new Iterator(function () {\n    if (i >= l) return {done: true};\n\n    return {done: false, value: args[i++]};\n  });\n};\n\n/**\n * Returning an empty iterator.\n *\n * @return {Iterator}\n */\nIterator.empty = function () {\n  var iterator = new Iterator(function () {\n    return {done: true};\n  });\n\n  return iterator;\n};\n\n/**\n * Returning an iterator over the given indexed sequence.\n *\n * @param  {string|Array} sequence - Target sequence.\n * @return {Iterator}\n */\nIterator.fromSequence = function (sequence) {\n  var i = 0,\n    l = sequence.length;\n\n  return new Iterator(function () {\n    if (i >= l) return {done: true};\n\n    return {done: false, value: sequence[i++]};\n  });\n};\n\n/**\n * Returning whether the given value is an iterator.\n *\n * @param  {any} value - Value.\n * @return {boolean}\n */\nIterator.is = function (value) {\n  if (value instanceof Iterator) return true;\n\n  return (\n    typeof value === 'object' &&\n    value !== null &&\n    typeof value.next === 'function'\n  );\n};\n\n/**\n * Exporting.\n */\nmodule.exports = Iterator;\n","exports.ARRAY_BUFFER_SUPPORT = typeof ArrayBuffer !== 'undefined';\nexports.SYMBOL_SUPPORT = typeof Symbol !== 'undefined';\n","/**\n * Obliterator Iter Function\n * ==========================\n *\n * Function coercing values to an iterator. It can be quite useful when needing\n * to handle iterables and iterators the same way.\n */\nvar Iterator = require('./iterator.js');\nvar support = require('./support.js');\n\nvar ARRAY_BUFFER_SUPPORT = support.ARRAY_BUFFER_SUPPORT;\nvar SYMBOL_SUPPORT = support.SYMBOL_SUPPORT;\n\nfunction iterOrNull(target) {\n  // Indexed sequence\n  if (\n    typeof target === 'string' ||\n    Array.isArray(target) ||\n    (ARRAY_BUFFER_SUPPORT && ArrayBuffer.isView(target))\n  )\n    return Iterator.fromSequence(target);\n\n  // Invalid value\n  if (typeof target !== 'object' || target === null) return null;\n\n  // Iterable\n  if (SYMBOL_SUPPORT && typeof target[Symbol.iterator] === 'function')\n    return target[Symbol.iterator]();\n\n  // Iterator duck-typing\n  if (typeof target.next === 'function') return target;\n\n  // Invalid object\n  return null;\n}\n\nmodule.exports = function iter(target) {\n  var iterator = iterOrNull(target);\n\n  if (!iterator)\n    throw new Error(\n      'obliterator: target is not iterable nor a valid iterator.'\n    );\n\n  return iterator;\n};\n","/* eslint no-constant-condition: 0 */\n/**\n * Obliterator Take Function\n * ==========================\n *\n * Function taking n or every value of the given iterator and returns them\n * into an array.\n */\nvar iter = require('./iter.js');\n\n/**\n * Take.\n *\n * @param  {Iterable} iterable - Target iterable.\n * @param  {number}   [n]      - Optional number of items to take.\n * @return {array}\n */\nmodule.exports = function take(iterable, n) {\n  var l = arguments.length > 1 ? n : Infinity,\n    array = l !== Infinity ? new Array(l) : [],\n    step,\n    i = 0;\n\n  var iterator = iter(iterable);\n\n  while (true) {\n    if (i === l) return array;\n\n    step = iterator.next();\n\n    if (step.done) {\n      if (i !== n) array.length = i;\n\n      return array;\n    }\n\n    array[i++] = step.value;\n  }\n};\n","/**\n * Graphology Custom Errors\n * =========================\n *\n * Defining custom errors for ease of use & easy unit tests across\n * implementations (normalized typology rather than relying on error\n * messages to check whether the correct error was found).\n */\nexport class GraphError extends Error {\n  constructor(message) {\n    super();\n    this.name = 'GraphError';\n    this.message = message;\n  }\n}\n\nexport class InvalidArgumentsGraphError extends GraphError {\n  constructor(message) {\n    super(message);\n    this.name = 'InvalidArgumentsGraphError';\n\n    // This is V8 specific to enhance stack readability\n    if (typeof Error.captureStackTrace === 'function')\n      Error.captureStackTrace(\n        this,\n        InvalidArgumentsGraphError.prototype.constructor\n      );\n  }\n}\n\nexport class NotFoundGraphError extends GraphError {\n  constructor(message) {\n    super(message);\n    this.name = 'NotFoundGraphError';\n\n    // This is V8 specific to enhance stack readability\n    if (typeof Error.captureStackTrace === 'function')\n      Error.captureStackTrace(this, NotFoundGraphError.prototype.constructor);\n  }\n}\n\nexport class UsageGraphError extends GraphError {\n  constructor(message) {\n    super(message);\n    this.name = 'UsageGraphError';\n\n    // This is V8 specific to enhance stack readability\n    if (typeof Error.captureStackTrace === 'function')\n      Error.captureStackTrace(this, UsageGraphError.prototype.constructor);\n  }\n}\n","/**\n * Graphology Internal Data Classes\n * =================================\n *\n * Internal classes hopefully reduced to structs by engines & storing\n * necessary information for nodes & edges.\n *\n * Note that those classes don't rely on the `class` keyword to avoid some\n * cruft introduced by most of ES2015 transpilers.\n */\n\n/**\n * MixedNodeData class.\n *\n * @constructor\n * @param {string} string     - The node's key.\n * @param {object} attributes - Node's attributes.\n */\nexport function MixedNodeData(key, attributes) {\n  // Attributes\n  this.key = key;\n  this.attributes = attributes;\n\n  this.clear();\n}\n\nMixedNodeData.prototype.clear = function () {\n  // Degrees\n  this.inDegree = 0;\n  this.outDegree = 0;\n  this.undirectedDegree = 0;\n  this.undirectedLoops = 0;\n  this.directedLoops = 0;\n\n  // Indices\n  this.in = {};\n  this.out = {};\n  this.undirected = {};\n};\n\n/**\n * DirectedNodeData class.\n *\n * @constructor\n * @param {string} string     - The node's key.\n * @param {object} attributes - Node's attributes.\n */\nexport function DirectedNodeData(key, attributes) {\n  // Attributes\n  this.key = key;\n  this.attributes = attributes;\n\n  this.clear();\n}\n\nDirectedNodeData.prototype.clear = function () {\n  // Degrees\n  this.inDegree = 0;\n  this.outDegree = 0;\n  this.directedLoops = 0;\n\n  // Indices\n  this.in = {};\n  this.out = {};\n};\n\n/**\n * UndirectedNodeData class.\n *\n * @constructor\n * @param {string} string     - The node's key.\n * @param {object} attributes - Node's attributes.\n */\nexport function UndirectedNodeData(key, attributes) {\n  // Attributes\n  this.key = key;\n  this.attributes = attributes;\n\n  this.clear();\n}\n\nUndirectedNodeData.prototype.clear = function () {\n  // Degrees\n  this.undirectedDegree = 0;\n  this.undirectedLoops = 0;\n\n  // Indices\n  this.undirected = {};\n};\n\n/**\n * EdgeData class.\n *\n * @constructor\n * @param {boolean} undirected   - Whether the edge is undirected.\n * @param {string}  string       - The edge's key.\n * @param {string}  source       - Source of the edge.\n * @param {string}  target       - Target of the edge.\n * @param {object}  attributes   - Edge's attributes.\n */\nexport function EdgeData(undirected, key, source, target, attributes) {\n  // Attributes\n  this.key = key;\n  this.attributes = attributes;\n  this.undirected = undirected;\n\n  // Extremities\n  this.source = source;\n  this.target = target;\n}\n\nEdgeData.prototype.attach = function () {\n  let outKey = 'out';\n  let inKey = 'in';\n\n  if (this.undirected) outKey = inKey = 'undirected';\n\n  const source = this.source.key;\n  const target = this.target.key;\n\n  // Handling source\n  this.source[outKey][target] = this;\n\n  if (this.undirected && source === target) return;\n\n  // Handling target\n  this.target[inKey][source] = this;\n};\n\nEdgeData.prototype.attachMulti = function () {\n  let outKey = 'out';\n  let inKey = 'in';\n\n  const source = this.source.key;\n  const target = this.target.key;\n\n  if (this.undirected) outKey = inKey = 'undirected';\n\n  // Handling source\n  const adj = this.source[outKey];\n  const head = adj[target];\n\n  if (typeof head === 'undefined') {\n    adj[target] = this;\n\n    // Self-loop optimization\n    if (!(this.undirected && source === target)) {\n      // Handling target\n      this.target[inKey][source] = this;\n    }\n\n    return;\n  }\n\n  // Prepending to doubly-linked list\n  head.previous = this;\n  this.next = head;\n\n  // Pointing to new head\n  // NOTE: use mutating swap later to avoid lookup?\n  adj[target] = this;\n  this.target[inKey][source] = this;\n};\n\nEdgeData.prototype.detach = function () {\n  const source = this.source.key;\n  const target = this.target.key;\n\n  let outKey = 'out';\n  let inKey = 'in';\n\n  if (this.undirected) outKey = inKey = 'undirected';\n\n  delete this.source[outKey][target];\n\n  // No-op delete in case of undirected self-loop\n  delete this.target[inKey][source];\n};\n\nEdgeData.prototype.detachMulti = function () {\n  const source = this.source.key;\n  const target = this.target.key;\n\n  let outKey = 'out';\n  let inKey = 'in';\n\n  if (this.undirected) outKey = inKey = 'undirected';\n\n  // Deleting from doubly-linked list\n  if (this.previous === undefined) {\n    // We are dealing with the head\n\n    // Should we delete the adjacency entry because it is now empty?\n    if (this.next === undefined) {\n      delete this.source[outKey][target];\n\n      // No-op delete in case of undirected self-loop\n      delete this.target[inKey][source];\n    } else {\n      // Detaching\n      this.next.previous = undefined;\n\n      // NOTE: could avoid the lookups by creating a #.become mutating method\n      this.source[outKey][target] = this.next;\n\n      // No-op delete in case of undirected self-loop\n      this.target[inKey][source] = this.next;\n    }\n  } else {\n    // We are dealing with another list node\n    this.previous.next = this.next;\n\n    // If not last\n    if (this.next !== undefined) {\n      this.next.previous = this.previous;\n    }\n  }\n};\n","/**\n * Graphology Node Attributes methods\n * ===================================\n */\nimport {assign, isPlainObject} from '../utils';\n\nimport {InvalidArgumentsGraphError, NotFoundGraphError} from '../errors';\n\nconst NODE = 0;\nconst SOURCE = 1;\nconst TARGET = 2;\nconst OPPOSITE = 3;\n\nfunction findRelevantNodeData(\n  graph,\n  method,\n  mode,\n  nodeOrEdge,\n  nameOrEdge,\n  add1,\n  add2\n) {\n  let nodeData, edgeData, arg1, arg2;\n\n  nodeOrEdge = '' + nodeOrEdge;\n\n  if (mode === NODE) {\n    nodeData = graph._nodes.get(nodeOrEdge);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.${method}: could not find the \"${nodeOrEdge}\" node in the graph.`\n      );\n\n    arg1 = nameOrEdge;\n    arg2 = add1;\n  } else if (mode === OPPOSITE) {\n    nameOrEdge = '' + nameOrEdge;\n\n    edgeData = graph._edges.get(nameOrEdge);\n\n    if (!edgeData)\n      throw new NotFoundGraphError(\n        `Graph.${method}: could not find the \"${nameOrEdge}\" edge in the graph.`\n      );\n\n    const source = edgeData.source.key;\n    const target = edgeData.target.key;\n\n    if (nodeOrEdge === source) {\n      nodeData = edgeData.target;\n    } else if (nodeOrEdge === target) {\n      nodeData = edgeData.source;\n    } else {\n      throw new NotFoundGraphError(\n        `Graph.${method}: the \"${nodeOrEdge}\" node is not attached to the \"${nameOrEdge}\" edge (${source}, ${target}).`\n      );\n    }\n\n    arg1 = add1;\n    arg2 = add2;\n  } else {\n    edgeData = graph._edges.get(nodeOrEdge);\n\n    if (!edgeData)\n      throw new NotFoundGraphError(\n        `Graph.${method}: could not find the \"${nodeOrEdge}\" edge in the graph.`\n      );\n\n    if (mode === SOURCE) {\n      nodeData = edgeData.source;\n    } else {\n      nodeData = edgeData.target;\n    }\n\n    arg1 = nameOrEdge;\n    arg2 = add1;\n  }\n\n  return [nodeData, arg1, arg2];\n}\n\nfunction attachNodeAttributeGetter(Class, method, mode) {\n  Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) {\n    const [data, name] = findRelevantNodeData(\n      this,\n      method,\n      mode,\n      nodeOrEdge,\n      nameOrEdge,\n      add1\n    );\n\n    return data.attributes[name];\n  };\n}\n\nfunction attachNodeAttributesGetter(Class, method, mode) {\n  Class.prototype[method] = function (nodeOrEdge, nameOrEdge) {\n    const [data] = findRelevantNodeData(\n      this,\n      method,\n      mode,\n      nodeOrEdge,\n      nameOrEdge\n    );\n\n    return data.attributes;\n  };\n}\n\nfunction attachNodeAttributeChecker(Class, method, mode) {\n  Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) {\n    const [data, name] = findRelevantNodeData(\n      this,\n      method,\n      mode,\n      nodeOrEdge,\n      nameOrEdge,\n      add1\n    );\n\n    return data.attributes.hasOwnProperty(name);\n  };\n}\n\nfunction attachNodeAttributeSetter(Class, method, mode) {\n  Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1, add2) {\n    const [data, name, value] = findRelevantNodeData(\n      this,\n      method,\n      mode,\n      nodeOrEdge,\n      nameOrEdge,\n      add1,\n      add2\n    );\n\n    data.attributes[name] = value;\n\n    // Emitting\n    this.emit('nodeAttributesUpdated', {\n      key: data.key,\n      type: 'set',\n      attributes: data.attributes,\n      name\n    });\n\n    return this;\n  };\n}\n\nfunction attachNodeAttributeUpdater(Class, method, mode) {\n  Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1, add2) {\n    const [data, name, updater] = findRelevantNodeData(\n      this,\n      method,\n      mode,\n      nodeOrEdge,\n      nameOrEdge,\n      add1,\n      add2\n    );\n\n    if (typeof updater !== 'function')\n      throw new InvalidArgumentsGraphError(\n        `Graph.${method}: updater should be a function.`\n      );\n\n    const attributes = data.attributes;\n    const value = updater(attributes[name]);\n\n    attributes[name] = value;\n\n    // Emitting\n    this.emit('nodeAttributesUpdated', {\n      key: data.key,\n      type: 'set',\n      attributes: data.attributes,\n      name\n    });\n\n    return this;\n  };\n}\n\nfunction attachNodeAttributeRemover(Class, method, mode) {\n  Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) {\n    const [data, name] = findRelevantNodeData(\n      this,\n      method,\n      mode,\n      nodeOrEdge,\n      nameOrEdge,\n      add1\n    );\n\n    delete data.attributes[name];\n\n    // Emitting\n    this.emit('nodeAttributesUpdated', {\n      key: data.key,\n      type: 'remove',\n      attributes: data.attributes,\n      name\n    });\n\n    return this;\n  };\n}\n\nfunction attachNodeAttributesReplacer(Class, method, mode) {\n  Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) {\n    const [data, attributes] = findRelevantNodeData(\n      this,\n      method,\n      mode,\n      nodeOrEdge,\n      nameOrEdge,\n      add1\n    );\n\n    if (!isPlainObject(attributes))\n      throw new InvalidArgumentsGraphError(\n        `Graph.${method}: provided attributes are not a plain object.`\n      );\n\n    data.attributes = attributes;\n\n    // Emitting\n    this.emit('nodeAttributesUpdated', {\n      key: data.key,\n      type: 'replace',\n      attributes: data.attributes\n    });\n\n    return this;\n  };\n}\n\nfunction attachNodeAttributesMerger(Class, method, mode) {\n  Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) {\n    const [data, attributes] = findRelevantNodeData(\n      this,\n      method,\n      mode,\n      nodeOrEdge,\n      nameOrEdge,\n      add1\n    );\n\n    if (!isPlainObject(attributes))\n      throw new InvalidArgumentsGraphError(\n        `Graph.${method}: provided attributes are not a plain object.`\n      );\n\n    assign(data.attributes, attributes);\n\n    // Emitting\n    this.emit('nodeAttributesUpdated', {\n      key: data.key,\n      type: 'merge',\n      attributes: data.attributes,\n      data: attributes\n    });\n\n    return this;\n  };\n}\n\nfunction attachNodeAttributesUpdater(Class, method, mode) {\n  Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) {\n    const [data, updater] = findRelevantNodeData(\n      this,\n      method,\n      mode,\n      nodeOrEdge,\n      nameOrEdge,\n      add1\n    );\n\n    if (typeof updater !== 'function')\n      throw new InvalidArgumentsGraphError(\n        `Graph.${method}: provided updater is not a function.`\n      );\n\n    data.attributes = updater(data.attributes);\n\n    // Emitting\n    this.emit('nodeAttributesUpdated', {\n      key: data.key,\n      type: 'update',\n      attributes: data.attributes\n    });\n\n    return this;\n  };\n}\n\n/**\n * List of methods to attach.\n */\nconst NODE_ATTRIBUTES_METHODS = [\n  {\n    name: element => `get${element}Attribute`,\n    attacher: attachNodeAttributeGetter\n  },\n  {\n    name: element => `get${element}Attributes`,\n    attacher: attachNodeAttributesGetter\n  },\n  {\n    name: element => `has${element}Attribute`,\n    attacher: attachNodeAttributeChecker\n  },\n  {\n    name: element => `set${element}Attribute`,\n    attacher: attachNodeAttributeSetter\n  },\n  {\n    name: element => `update${element}Attribute`,\n    attacher: attachNodeAttributeUpdater\n  },\n  {\n    name: element => `remove${element}Attribute`,\n    attacher: attachNodeAttributeRemover\n  },\n  {\n    name: element => `replace${element}Attributes`,\n    attacher: attachNodeAttributesReplacer\n  },\n  {\n    name: element => `merge${element}Attributes`,\n    attacher: attachNodeAttributesMerger\n  },\n  {\n    name: element => `update${element}Attributes`,\n    attacher: attachNodeAttributesUpdater\n  }\n];\n\n/**\n * Attach every attributes-related methods to a Graph class.\n *\n * @param {function} Graph - Target class.\n */\nexport default function attachNodeAttributesMethods(Graph) {\n  NODE_ATTRIBUTES_METHODS.forEach(function ({name, attacher}) {\n    // For nodes\n    attacher(Graph, name('Node'), NODE);\n\n    // For sources\n    attacher(Graph, name('Source'), SOURCE);\n\n    // For targets\n    attacher(Graph, name('Target'), TARGET);\n\n    // For opposites\n    attacher(Graph, name('Opposite'), OPPOSITE);\n  });\n}\n","/**\n * Graphology Edge Attributes methods\n * ===================================\n */\nimport {assign, isPlainObject, getMatchingEdge} from '../utils';\n\nimport {\n  InvalidArgumentsGraphError,\n  NotFoundGraphError,\n  UsageGraphError\n} from '../errors';\n\n/**\n * Attach an attribute getter method onto the provided class.\n *\n * @param {function} Class         - Target class.\n * @param {string}   method        - Method name.\n * @param {string}   type          - Type of the edge to find.\n */\nfunction attachEdgeAttributeGetter(Class, method, type) {\n  /**\n   * Get the desired attribute for the given element (node or edge).\n   *\n   * Arity 2:\n   * @param  {any}    element - Target element.\n   * @param  {string} name    - Attribute's name.\n   *\n   * Arity 3 (only for edges):\n   * @param  {any}     source - Source element.\n   * @param  {any}     target - Target element.\n   * @param  {string}  name   - Attribute's name.\n   *\n   * @return {mixed}          - The attribute's value.\n   *\n   * @throws {Error} - Will throw if too many arguments are provided.\n   * @throws {Error} - Will throw if any of the elements is not found.\n   */\n  Class.prototype[method] = function (element, name) {\n    let data;\n\n    if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type)\n      throw new UsageGraphError(\n        `Graph.${method}: cannot find this type of edges in your ${this.type} graph.`\n      );\n\n    if (arguments.length > 2) {\n      if (this.multi)\n        throw new UsageGraphError(\n          `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`\n        );\n\n      const source = '' + element;\n      const target = '' + name;\n\n      name = arguments[2];\n\n      data = getMatchingEdge(this, source, target, type);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find an edge for the given path (\"${source}\" - \"${target}\").`\n        );\n    } else {\n      if (type !== 'mixed')\n        throw new UsageGraphError(\n          `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`\n        );\n\n      element = '' + element;\n      data = this._edges.get(element);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find the \"${element}\" edge in the graph.`\n        );\n    }\n\n    return data.attributes[name];\n  };\n}\n\n/**\n * Attach an attributes getter method onto the provided class.\n *\n * @param {function} Class       - Target class.\n * @param {string}   method      - Method name.\n * @param {string}   type        - Type of the edge to find.\n */\nfunction attachEdgeAttributesGetter(Class, method, type) {\n  /**\n   * Retrieves all the target element's attributes.\n   *\n   * Arity 2:\n   * @param  {any}    element - Target element.\n   *\n   * Arity 3 (only for edges):\n   * @param  {any}     source - Source element.\n   * @param  {any}     target - Target element.\n   *\n   * @return {object}          - The element's attributes.\n   *\n   * @throws {Error} - Will throw if too many arguments are provided.\n   * @throws {Error} - Will throw if any of the elements is not found.\n   */\n  Class.prototype[method] = function (element) {\n    let data;\n\n    if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type)\n      throw new UsageGraphError(\n        `Graph.${method}: cannot find this type of edges in your ${this.type} graph.`\n      );\n\n    if (arguments.length > 1) {\n      if (this.multi)\n        throw new UsageGraphError(\n          `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`\n        );\n\n      const source = '' + element,\n        target = '' + arguments[1];\n\n      data = getMatchingEdge(this, source, target, type);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find an edge for the given path (\"${source}\" - \"${target}\").`\n        );\n    } else {\n      if (type !== 'mixed')\n        throw new UsageGraphError(\n          `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`\n        );\n\n      element = '' + element;\n      data = this._edges.get(element);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find the \"${element}\" edge in the graph.`\n        );\n    }\n\n    return data.attributes;\n  };\n}\n\n/**\n * Attach an attribute checker method onto the provided class.\n *\n * @param {function} Class       - Target class.\n * @param {string}   method      - Method name.\n * @param {string}   type        - Type of the edge to find.\n */\nfunction attachEdgeAttributeChecker(Class, method, type) {\n  /**\n   * Checks whether the desired attribute is set for the given element (node or edge).\n   *\n   * Arity 2:\n   * @param  {any}    element - Target element.\n   * @param  {string} name    - Attribute's name.\n   *\n   * Arity 3 (only for edges):\n   * @param  {any}     source - Source element.\n   * @param  {any}     target - Target element.\n   * @param  {string}  name   - Attribute's name.\n   *\n   * @return {boolean}\n   *\n   * @throws {Error} - Will throw if too many arguments are provided.\n   * @throws {Error} - Will throw if any of the elements is not found.\n   */\n  Class.prototype[method] = function (element, name) {\n    let data;\n\n    if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type)\n      throw new UsageGraphError(\n        `Graph.${method}: cannot find this type of edges in your ${this.type} graph.`\n      );\n\n    if (arguments.length > 2) {\n      if (this.multi)\n        throw new UsageGraphError(\n          `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`\n        );\n\n      const source = '' + element;\n      const target = '' + name;\n\n      name = arguments[2];\n\n      data = getMatchingEdge(this, source, target, type);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find an edge for the given path (\"${source}\" - \"${target}\").`\n        );\n    } else {\n      if (type !== 'mixed')\n        throw new UsageGraphError(\n          `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`\n        );\n\n      element = '' + element;\n      data = this._edges.get(element);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find the \"${element}\" edge in the graph.`\n        );\n    }\n\n    return data.attributes.hasOwnProperty(name);\n  };\n}\n\n/**\n * Attach an attribute setter method onto the provided class.\n *\n * @param {function} Class         - Target class.\n * @param {string}   method        - Method name.\n * @param {string}   type          - Type of the edge to find.\n */\nfunction attachEdgeAttributeSetter(Class, method, type) {\n  /**\n   * Set the desired attribute for the given element (node or edge).\n   *\n   * Arity 2:\n   * @param  {any}    element - Target element.\n   * @param  {string} name    - Attribute's name.\n   * @param  {mixed}  value   - New attribute value.\n   *\n   * Arity 3 (only for edges):\n   * @param  {any}     source - Source element.\n   * @param  {any}     target - Target element.\n   * @param  {string}  name   - Attribute's name.\n   * @param  {mixed}  value   - New attribute value.\n   *\n   * @return {Graph}          - Returns itself for chaining.\n   *\n   * @throws {Error} - Will throw if too many arguments are provided.\n   * @throws {Error} - Will throw if any of the elements is not found.\n   */\n  Class.prototype[method] = function (element, name, value) {\n    let data;\n\n    if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type)\n      throw new UsageGraphError(\n        `Graph.${method}: cannot find this type of edges in your ${this.type} graph.`\n      );\n\n    if (arguments.length > 3) {\n      if (this.multi)\n        throw new UsageGraphError(\n          `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`\n        );\n\n      const source = '' + element;\n      const target = '' + name;\n\n      name = arguments[2];\n      value = arguments[3];\n\n      data = getMatchingEdge(this, source, target, type);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find an edge for the given path (\"${source}\" - \"${target}\").`\n        );\n    } else {\n      if (type !== 'mixed')\n        throw new UsageGraphError(\n          `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`\n        );\n\n      element = '' + element;\n      data = this._edges.get(element);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find the \"${element}\" edge in the graph.`\n        );\n    }\n\n    data.attributes[name] = value;\n\n    // Emitting\n    this.emit('edgeAttributesUpdated', {\n      key: data.key,\n      type: 'set',\n      attributes: data.attributes,\n      name\n    });\n\n    return this;\n  };\n}\n\n/**\n * Attach an attribute updater method onto the provided class.\n *\n * @param {function} Class         - Target class.\n * @param {string}   method        - Method name.\n * @param {string}   type          - Type of the edge to find.\n */\nfunction attachEdgeAttributeUpdater(Class, method, type) {\n  /**\n   * Update the desired attribute for the given element (node or edge) using\n   * the provided function.\n   *\n   * Arity 2:\n   * @param  {any}      element - Target element.\n   * @param  {string}   name    - Attribute's name.\n   * @param  {function} updater - Updater function.\n   *\n   * Arity 3 (only for edges):\n   * @param  {any}      source  - Source element.\n   * @param  {any}      target  - Target element.\n   * @param  {string}   name    - Attribute's name.\n   * @param  {function} updater - Updater function.\n   *\n   * @return {Graph}            - Returns itself for chaining.\n   *\n   * @throws {Error} - Will throw if too many arguments are provided.\n   * @throws {Error} - Will throw if any of the elements is not found.\n   */\n  Class.prototype[method] = function (element, name, updater) {\n    let data;\n\n    if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type)\n      throw new UsageGraphError(\n        `Graph.${method}: cannot find this type of edges in your ${this.type} graph.`\n      );\n\n    if (arguments.length > 3) {\n      if (this.multi)\n        throw new UsageGraphError(\n          `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`\n        );\n\n      const source = '' + element;\n      const target = '' + name;\n\n      name = arguments[2];\n      updater = arguments[3];\n\n      data = getMatchingEdge(this, source, target, type);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find an edge for the given path (\"${source}\" - \"${target}\").`\n        );\n    } else {\n      if (type !== 'mixed')\n        throw new UsageGraphError(\n          `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`\n        );\n\n      element = '' + element;\n      data = this._edges.get(element);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find the \"${element}\" edge in the graph.`\n        );\n    }\n\n    if (typeof updater !== 'function')\n      throw new InvalidArgumentsGraphError(\n        `Graph.${method}: updater should be a function.`\n      );\n\n    data.attributes[name] = updater(data.attributes[name]);\n\n    // Emitting\n    this.emit('edgeAttributesUpdated', {\n      key: data.key,\n      type: 'set',\n      attributes: data.attributes,\n      name\n    });\n\n    return this;\n  };\n}\n\n/**\n * Attach an attribute remover method onto the provided class.\n *\n * @param {function} Class         - Target class.\n * @param {string}   method        - Method name.\n * @param {string}   type          - Type of the edge to find.\n */\nfunction attachEdgeAttributeRemover(Class, method, type) {\n  /**\n   * Remove the desired attribute for the given element (node or edge).\n   *\n   * Arity 2:\n   * @param  {any}    element - Target element.\n   * @param  {string} name    - Attribute's name.\n   *\n   * Arity 3 (only for edges):\n   * @param  {any}     source - Source element.\n   * @param  {any}     target - Target element.\n   * @param  {string}  name   - Attribute's name.\n   *\n   * @return {Graph}          - Returns itself for chaining.\n   *\n   * @throws {Error} - Will throw if too many arguments are provided.\n   * @throws {Error} - Will throw if any of the elements is not found.\n   */\n  Class.prototype[method] = function (element, name) {\n    let data;\n\n    if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type)\n      throw new UsageGraphError(\n        `Graph.${method}: cannot find this type of edges in your ${this.type} graph.`\n      );\n\n    if (arguments.length > 2) {\n      if (this.multi)\n        throw new UsageGraphError(\n          `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`\n        );\n\n      const source = '' + element;\n      const target = '' + name;\n\n      name = arguments[2];\n\n      data = getMatchingEdge(this, source, target, type);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find an edge for the given path (\"${source}\" - \"${target}\").`\n        );\n    } else {\n      if (type !== 'mixed')\n        throw new UsageGraphError(\n          `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`\n        );\n\n      element = '' + element;\n      data = this._edges.get(element);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find the \"${element}\" edge in the graph.`\n        );\n    }\n\n    delete data.attributes[name];\n\n    // Emitting\n    this.emit('edgeAttributesUpdated', {\n      key: data.key,\n      type: 'remove',\n      attributes: data.attributes,\n      name\n    });\n\n    return this;\n  };\n}\n\n/**\n * Attach an attribute replacer method onto the provided class.\n *\n * @param {function} Class         - Target class.\n * @param {string}   method        - Method name.\n * @param {string}   type          - Type of the edge to find.\n */\nfunction attachEdgeAttributesReplacer(Class, method, type) {\n  /**\n   * Replace the attributes for the given element (node or edge).\n   *\n   * Arity 2:\n   * @param  {any}    element    - Target element.\n   * @param  {object} attributes - New attributes.\n   *\n   * Arity 3 (only for edges):\n   * @param  {any}     source     - Source element.\n   * @param  {any}     target     - Target element.\n   * @param  {object}  attributes - New attributes.\n   *\n   * @return {Graph}              - Returns itself for chaining.\n   *\n   * @throws {Error} - Will throw if too many arguments are provided.\n   * @throws {Error} - Will throw if any of the elements is not found.\n   */\n  Class.prototype[method] = function (element, attributes) {\n    let data;\n\n    if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type)\n      throw new UsageGraphError(\n        `Graph.${method}: cannot find this type of edges in your ${this.type} graph.`\n      );\n\n    if (arguments.length > 2) {\n      if (this.multi)\n        throw new UsageGraphError(\n          `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`\n        );\n\n      const source = '' + element,\n        target = '' + attributes;\n\n      attributes = arguments[2];\n\n      data = getMatchingEdge(this, source, target, type);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find an edge for the given path (\"${source}\" - \"${target}\").`\n        );\n    } else {\n      if (type !== 'mixed')\n        throw new UsageGraphError(\n          `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`\n        );\n\n      element = '' + element;\n      data = this._edges.get(element);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find the \"${element}\" edge in the graph.`\n        );\n    }\n\n    if (!isPlainObject(attributes))\n      throw new InvalidArgumentsGraphError(\n        `Graph.${method}: provided attributes are not a plain object.`\n      );\n\n    data.attributes = attributes;\n\n    // Emitting\n    this.emit('edgeAttributesUpdated', {\n      key: data.key,\n      type: 'replace',\n      attributes: data.attributes\n    });\n\n    return this;\n  };\n}\n\n/**\n * Attach an attribute merger method onto the provided class.\n *\n * @param {function} Class         - Target class.\n * @param {string}   method        - Method name.\n * @param {string}   type          - Type of the edge to find.\n */\nfunction attachEdgeAttributesMerger(Class, method, type) {\n  /**\n   * Merge the attributes for the given element (node or edge).\n   *\n   * Arity 2:\n   * @param  {any}    element    - Target element.\n   * @param  {object} attributes - Attributes to merge.\n   *\n   * Arity 3 (only for edges):\n   * @param  {any}     source     - Source element.\n   * @param  {any}     target     - Target element.\n   * @param  {object}  attributes - Attributes to merge.\n   *\n   * @return {Graph}              - Returns itself for chaining.\n   *\n   * @throws {Error} - Will throw if too many arguments are provided.\n   * @throws {Error} - Will throw if any of the elements is not found.\n   */\n  Class.prototype[method] = function (element, attributes) {\n    let data;\n\n    if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type)\n      throw new UsageGraphError(\n        `Graph.${method}: cannot find this type of edges in your ${this.type} graph.`\n      );\n\n    if (arguments.length > 2) {\n      if (this.multi)\n        throw new UsageGraphError(\n          `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`\n        );\n\n      const source = '' + element,\n        target = '' + attributes;\n\n      attributes = arguments[2];\n\n      data = getMatchingEdge(this, source, target, type);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find an edge for the given path (\"${source}\" - \"${target}\").`\n        );\n    } else {\n      if (type !== 'mixed')\n        throw new UsageGraphError(\n          `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`\n        );\n\n      element = '' + element;\n      data = this._edges.get(element);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find the \"${element}\" edge in the graph.`\n        );\n    }\n\n    if (!isPlainObject(attributes))\n      throw new InvalidArgumentsGraphError(\n        `Graph.${method}: provided attributes are not a plain object.`\n      );\n\n    assign(data.attributes, attributes);\n\n    // Emitting\n    this.emit('edgeAttributesUpdated', {\n      key: data.key,\n      type: 'merge',\n      attributes: data.attributes,\n      data: attributes\n    });\n\n    return this;\n  };\n}\n\n/**\n * Attach an attribute updater method onto the provided class.\n *\n * @param {function} Class         - Target class.\n * @param {string}   method        - Method name.\n * @param {string}   type          - Type of the edge to find.\n */\nfunction attachEdgeAttributesUpdater(Class, method, type) {\n  /**\n   * Update the attributes of the given element (node or edge).\n   *\n   * Arity 2:\n   * @param  {any}      element - Target element.\n   * @param  {function} updater - Updater function.\n   *\n   * Arity 3 (only for edges):\n   * @param  {any}      source  - Source element.\n   * @param  {any}      target  - Target element.\n   * @param  {function} updater - Updater function.\n   *\n   * @return {Graph}            - Returns itself for chaining.\n   *\n   * @throws {Error} - Will throw if too many arguments are provided.\n   * @throws {Error} - Will throw if any of the elements is not found.\n   */\n  Class.prototype[method] = function (element, updater) {\n    let data;\n\n    if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type)\n      throw new UsageGraphError(\n        `Graph.${method}: cannot find this type of edges in your ${this.type} graph.`\n      );\n\n    if (arguments.length > 2) {\n      if (this.multi)\n        throw new UsageGraphError(\n          `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`\n        );\n\n      const source = '' + element,\n        target = '' + updater;\n\n      updater = arguments[2];\n\n      data = getMatchingEdge(this, source, target, type);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find an edge for the given path (\"${source}\" - \"${target}\").`\n        );\n    } else {\n      if (type !== 'mixed')\n        throw new UsageGraphError(\n          `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`\n        );\n\n      element = '' + element;\n      data = this._edges.get(element);\n\n      if (!data)\n        throw new NotFoundGraphError(\n          `Graph.${method}: could not find the \"${element}\" edge in the graph.`\n        );\n    }\n\n    if (typeof updater !== 'function')\n      throw new InvalidArgumentsGraphError(\n        `Graph.${method}: provided updater is not a function.`\n      );\n\n    data.attributes = updater(data.attributes);\n\n    // Emitting\n    this.emit('edgeAttributesUpdated', {\n      key: data.key,\n      type: 'update',\n      attributes: data.attributes\n    });\n\n    return this;\n  };\n}\n\n/**\n * List of methods to attach.\n */\nconst EDGE_ATTRIBUTES_METHODS = [\n  {\n    name: element => `get${element}Attribute`,\n    attacher: attachEdgeAttributeGetter\n  },\n  {\n    name: element => `get${element}Attributes`,\n    attacher: attachEdgeAttributesGetter\n  },\n  {\n    name: element => `has${element}Attribute`,\n    attacher: attachEdgeAttributeChecker\n  },\n  {\n    name: element => `set${element}Attribute`,\n    attacher: attachEdgeAttributeSetter\n  },\n  {\n    name: element => `update${element}Attribute`,\n    attacher: attachEdgeAttributeUpdater\n  },\n  {\n    name: element => `remove${element}Attribute`,\n    attacher: attachEdgeAttributeRemover\n  },\n  {\n    name: element => `replace${element}Attributes`,\n    attacher: attachEdgeAttributesReplacer\n  },\n  {\n    name: element => `merge${element}Attributes`,\n    attacher: attachEdgeAttributesMerger\n  },\n  {\n    name: element => `update${element}Attributes`,\n    attacher: attachEdgeAttributesUpdater\n  }\n];\n\n/**\n * Attach every attributes-related methods to a Graph class.\n *\n * @param {function} Graph - Target class.\n */\nexport default function attachEdgeAttributesMethods(Graph) {\n  EDGE_ATTRIBUTES_METHODS.forEach(function ({name, attacher}) {\n    // For edges\n    attacher(Graph, name('Edge'), 'mixed');\n\n    // For directed edges\n    attacher(Graph, name('DirectedEdge'), 'directed');\n\n    // For undirected edges\n    attacher(Graph, name('UndirectedEdge'), 'undirected');\n  });\n}\n","/**\n * Obliterator Chain Function\n * ===========================\n *\n * Variadic function combining the given iterables.\n */\nvar Iterator = require('./iterator.js');\nvar iter = require('./iter.js');\n\n/**\n * Chain.\n *\n * @param  {...Iterator} iterables - Target iterables.\n * @return {Iterator}\n */\nmodule.exports = function chain() {\n  var iterables = arguments;\n  var current = null;\n  var i = -1;\n\n  /* eslint-disable no-constant-condition */\n  return new Iterator(function next() {\n    var step = null;\n\n    do {\n      if (current === null) {\n        i++;\n\n        if (i >= iterables.length) return {done: true};\n\n        current = iter(iterables[i]);\n      }\n\n      step = current.next();\n\n      if (step.done === true) {\n        current = null;\n        continue;\n      }\n\n      break;\n    } while (true);\n\n    return step;\n  });\n};\n","/**\n * Graphology Edge Iteration\n * ==========================\n *\n * Attaching some methods to the Graph class to be able to iterate over a\n * graph's edges.\n */\nimport Iterator from 'obliterator/iterator';\nimport chain from 'obliterator/chain';\nimport take from 'obliterator/take';\n\nimport {InvalidArgumentsGraphError, NotFoundGraphError} from '../errors';\n\n/**\n * Definitions.\n */\nconst EDGES_ITERATION = [\n  {\n    name: 'edges',\n    type: 'mixed'\n  },\n  {\n    name: 'inEdges',\n    type: 'directed',\n    direction: 'in'\n  },\n  {\n    name: 'outEdges',\n    type: 'directed',\n    direction: 'out'\n  },\n  {\n    name: 'inboundEdges',\n    type: 'mixed',\n    direction: 'in'\n  },\n  {\n    name: 'outboundEdges',\n    type: 'mixed',\n    direction: 'out'\n  },\n  {\n    name: 'directedEdges',\n    type: 'directed'\n  },\n  {\n    name: 'undirectedEdges',\n    type: 'undirected'\n  }\n];\n\n/**\n * Function iterating over edges from the given object to match one of them.\n *\n * @param {object}   object   - Target object.\n * @param {function} callback - Function to call.\n */\nfunction forEachSimple(breakable, object, callback, avoid) {\n  let shouldBreak = false;\n\n  for (const k in object) {\n    if (k === avoid) continue;\n\n    const edgeData = object[k];\n\n    shouldBreak = callback(\n      edgeData.key,\n      edgeData.attributes,\n      edgeData.source.key,\n      edgeData.target.key,\n      edgeData.source.attributes,\n      edgeData.target.attributes,\n      edgeData.undirected\n    );\n\n    if (breakable && shouldBreak) return edgeData.key;\n  }\n\n  return;\n}\n\nfunction forEachMulti(breakable, object, callback, avoid) {\n  let edgeData, source, target;\n\n  let shouldBreak = false;\n\n  for (const k in object) {\n    if (k === avoid) continue;\n\n    edgeData = object[k];\n\n    do {\n      source = edgeData.source;\n      target = edgeData.target;\n\n      shouldBreak = callback(\n        edgeData.key,\n        edgeData.attributes,\n        source.key,\n        target.key,\n        source.attributes,\n        target.attributes,\n        edgeData.undirected\n      );\n\n      if (breakable && shouldBreak) return edgeData.key;\n\n      edgeData = edgeData.next;\n    } while (edgeData !== undefined);\n  }\n\n  return;\n}\n\n/**\n * Function returning an iterator over edges from the given object.\n *\n * @param  {object}   object - Target object.\n * @return {Iterator}\n */\nfunction createIterator(object, avoid) {\n  const keys = Object.keys(object);\n  const l = keys.length;\n\n  let edgeData;\n  let i = 0;\n\n  return new Iterator(function next() {\n    do {\n      if (!edgeData) {\n        if (i >= l) return {done: true};\n\n        const k = keys[i++];\n\n        if (k === avoid) {\n          edgeData = undefined;\n          continue;\n        }\n\n        edgeData = object[k];\n      } else {\n        edgeData = edgeData.next;\n      }\n    } while (!edgeData);\n\n    return {\n      done: false,\n      value: {\n        edge: edgeData.key,\n        attributes: edgeData.attributes,\n        source: edgeData.source.key,\n        target: edgeData.target.key,\n        sourceAttributes: edgeData.source.attributes,\n        targetAttributes: edgeData.target.attributes,\n        undirected: edgeData.undirected\n      }\n    };\n  });\n}\n\n/**\n * Function iterating over the egdes from the object at given key to match\n * one of them.\n *\n * @param {object}   object   - Target object.\n * @param {mixed}    k        - Neighbor key.\n * @param {function} callback - Callback to use.\n */\nfunction forEachForKeySimple(breakable, object, k, callback) {\n  const edgeData = object[k];\n\n  if (!edgeData) return;\n\n  const sourceData = edgeData.source;\n  const targetData = edgeData.target;\n\n  if (\n    callback(\n      edgeData.key,\n      edgeData.attributes,\n      sourceData.key,\n      targetData.key,\n      sourceData.attributes,\n      targetData.attributes,\n      edgeData.undirected\n    ) &&\n    breakable\n  )\n    return edgeData.key;\n}\n\nfunction forEachForKeyMulti(breakable, object, k, callback) {\n  let edgeData = object[k];\n\n  if (!edgeData) return;\n\n  let shouldBreak = false;\n\n  do {\n    shouldBreak = callback(\n      edgeData.key,\n      edgeData.attributes,\n      edgeData.source.key,\n      edgeData.target.key,\n      edgeData.source.attributes,\n      edgeData.target.attributes,\n      edgeData.undirected\n    );\n\n    if (breakable && shouldBreak) return edgeData.key;\n\n    edgeData = edgeData.next;\n  } while (edgeData !== undefined);\n\n  return;\n}\n\n/**\n * Function returning an iterator over the egdes from the object at given key.\n *\n * @param  {object}   object   - Target object.\n * @param  {mixed}    k        - Neighbor key.\n * @return {Iterator}\n */\nfunction createIteratorForKey(object, k) {\n  let edgeData = object[k];\n\n  if (edgeData.next !== undefined) {\n    return new Iterator(function () {\n      if (!edgeData) return {done: true};\n\n      const value = {\n        edge: edgeData.key,\n        attributes: edgeData.attributes,\n        source: edgeData.source.key,\n        target: edgeData.target.key,\n        sourceAttributes: edgeData.source.attributes,\n        targetAttributes: edgeData.target.attributes,\n        undirected: edgeData.undirected\n      };\n\n      edgeData = edgeData.next;\n\n      return {\n        done: false,\n        value\n      };\n    });\n  }\n\n  return Iterator.of({\n    edge: edgeData.key,\n    attributes: edgeData.attributes,\n    source: edgeData.source.key,\n    target: edgeData.target.key,\n    sourceAttributes: edgeData.source.attributes,\n    targetAttributes: edgeData.target.attributes,\n    undirected: edgeData.undirected\n  });\n}\n\n/**\n * Function creating an array of edges for the given type.\n *\n * @param  {Graph}   graph - Target Graph instance.\n * @param  {string}  type  - Type of edges to retrieve.\n * @return {array}         - Array of edges.\n */\nfunction createEdgeArray(graph, type) {\n  if (graph.size === 0) return [];\n\n  if (type === 'mixed' || type === graph.type) {\n    if (typeof Array.from === 'function')\n      return Array.from(graph._edges.keys());\n\n    return take(graph._edges.keys(), graph._edges.size);\n  }\n\n  const size =\n    type === 'undirected' ? graph.undirectedSize : graph.directedSize;\n\n  const list = new Array(size),\n    mask = type === 'undirected';\n\n  const iterator = graph._edges.values();\n\n  let i = 0;\n  let step, data;\n\n  while (((step = iterator.next()), step.done !== true)) {\n    data = step.value;\n\n    if (data.undirected === mask) list[i++] = data.key;\n  }\n\n  return list;\n}\n\n/**\n * Function iterating over a graph's edges using a callback to match one of\n * them.\n *\n * @param  {Graph}    graph    - Target Graph instance.\n * @param  {string}   type     - Type of edges to retrieve.\n * @param  {function} callback - Function to call.\n */\nfunction forEachEdge(breakable, graph, type, callback) {\n  if (graph.size === 0) return;\n\n  const shouldFilter = type !== 'mixed' && type !== graph.type;\n  const mask = type === 'undirected';\n\n  let step, data;\n  let shouldBreak = false;\n  const iterator = graph._edges.values();\n\n  while (((step = iterator.next()), step.done !== true)) {\n    data = step.value;\n\n    if (shouldFilter && data.undirected !== mask) continue;\n\n    const {key, attributes, source, target} = data;\n\n    shouldBreak = callback(\n      key,\n      attributes,\n      source.key,\n      target.key,\n      source.attributes,\n      target.attributes,\n      data.undirected\n    );\n\n    if (breakable && shouldBreak) return key;\n  }\n\n  return;\n}\n\n/**\n * Function creating an iterator of edges for the given type.\n *\n * @param  {Graph}    graph - Target Graph instance.\n * @param  {string}   type  - Type of edges to retrieve.\n * @return {Iterator}\n */\nfunction createEdgeIterator(graph, type) {\n  if (graph.size === 0) return Iterator.empty();\n\n  const shouldFilter = type !== 'mixed' && type !== graph.type;\n  const mask = type === 'undirected';\n\n  const iterator = graph._edges.values();\n\n  return new Iterator(function next() {\n    let step, data;\n\n    // eslint-disable-next-line no-constant-condition\n    while (true) {\n      step = iterator.next();\n\n      if (step.done) return step;\n\n      data = step.value;\n\n      if (shouldFilter && data.undirected !== mask) continue;\n\n      break;\n    }\n\n    const value = {\n      edge: data.key,\n      attributes: data.attributes,\n      source: data.source.key,\n      target: data.target.key,\n      sourceAttributes: data.source.attributes,\n      targetAttributes: data.target.attributes,\n      undirected: data.undirected\n    };\n\n    return {value, done: false};\n  });\n}\n\n/**\n * Function iterating over a node's edges using a callback to match one of them.\n *\n * @param  {boolean}  multi     - Whether the graph is multi or not.\n * @param  {string}   type      - Type of edges to retrieve.\n * @param  {string}   direction - In or out?\n * @param  {any}      nodeData  - Target node's data.\n * @param  {function} callback  - Function to call.\n */\nfunction forEachEdgeForNode(\n  breakable,\n  multi,\n  type,\n  direction,\n  nodeData,\n  callback\n) {\n  const fn = multi ? forEachMulti : forEachSimple;\n\n  let found;\n\n  if (type !== 'undirected') {\n    if (direction !== 'out') {\n      found = fn(breakable, nodeData.in, callback);\n\n      if (breakable && found) return found;\n    }\n    if (direction !== 'in') {\n      found = fn(\n        breakable,\n        nodeData.out,\n        callback,\n        !direction ? nodeData.key : undefined\n      );\n\n      if (breakable && found) return found;\n    }\n  }\n\n  if (type !== 'directed') {\n    found = fn(breakable, nodeData.undirected, callback);\n\n    if (breakable && found) return found;\n  }\n\n  return;\n}\n\n/**\n * Function creating an array of edges for the given type & the given node.\n *\n * @param  {boolean} multi     - Whether the graph is multi or not.\n * @param  {string}  type      - Type of edges to retrieve.\n * @param  {string}  direction - In or out?\n * @param  {any}     nodeData  - Target node's data.\n * @return {array}             - Array of edges.\n */\nfunction createEdgeArrayForNode(multi, type, direction, nodeData) {\n  const edges = []; // TODO: possibility to know size beforehand or factorize with map\n\n  forEachEdgeForNode(false, multi, type, direction, nodeData, function (key) {\n    edges.push(key);\n  });\n\n  return edges;\n}\n\n/**\n * Function iterating over a node's edges using a callback.\n *\n * @param  {string}   type      - Type of edges to retrieve.\n * @param  {string}   direction - In or out?\n * @param  {any}      nodeData  - Target node's data.\n * @return {Iterator}\n */\nfunction createEdgeIteratorForNode(type, direction, nodeData) {\n  let iterator = Iterator.empty();\n\n  if (type !== 'undirected') {\n    if (direction !== 'out' && typeof nodeData.in !== 'undefined')\n      iterator = chain(iterator, createIterator(nodeData.in));\n    if (direction !== 'in' && typeof nodeData.out !== 'undefined')\n      iterator = chain(\n        iterator,\n        createIterator(nodeData.out, !direction ? nodeData.key : undefined)\n      );\n  }\n\n  if (type !== 'directed' && typeof nodeData.undirected !== 'undefined') {\n    iterator = chain(iterator, createIterator(nodeData.undirected));\n  }\n\n  return iterator;\n}\n\n/**\n * Function iterating over edges for the given path using a callback to match\n * one of them.\n *\n * @param  {string}   type       - Type of edges to retrieve.\n * @param  {boolean}  multi      - Whether the graph is multi.\n * @param  {string}   direction  - In or out?\n * @param  {NodeData} sourceData - Source node's data.\n * @param  {string}   target     - Target node.\n * @param  {function} callback   - Function to call.\n */\nfunction forEachEdgeForPath(\n  breakable,\n  type,\n  multi,\n  direction,\n  sourceData,\n  target,\n  callback\n) {\n  const fn = multi ? forEachForKeyMulti : forEachForKeySimple;\n\n  let found;\n\n  if (type !== 'undirected') {\n    if (typeof sourceData.in !== 'undefined' && direction !== 'out') {\n      found = fn(breakable, sourceData.in, target, callback);\n\n      if (breakable && found) return found;\n    }\n\n    if (\n      typeof sourceData.out !== 'undefined' &&\n      direction !== 'in' &&\n      (direction || sourceData.key !== target)\n    ) {\n      found = fn(breakable, sourceData.out, target, callback);\n\n      if (breakable && found) return found;\n    }\n  }\n\n  if (type !== 'directed') {\n    if (typeof sourceData.undirected !== 'undefined') {\n      found = fn(breakable, sourceData.undirected, target, callback);\n\n      if (breakable && found) return found;\n    }\n  }\n\n  return;\n}\n\n/**\n * Function creating an array of edges for the given path.\n *\n * @param  {string}   type       - Type of edges to retrieve.\n * @param  {boolean}  multi      - Whether the graph is multi.\n * @param  {string}   direction  - In or out?\n * @param  {NodeData} sourceData - Source node's data.\n * @param  {any}      target     - Target node.\n * @return {array}               - Array of edges.\n */\nfunction createEdgeArrayForPath(type, multi, direction, sourceData, target) {\n  const edges = []; // TODO: possibility to know size beforehand or factorize with map\n\n  forEachEdgeForPath(\n    false,\n    type,\n    multi,\n    direction,\n    sourceData,\n    target,\n    function (key) {\n      edges.push(key);\n    }\n  );\n\n  return edges;\n}\n\n/**\n * Function returning an iterator over edges for the given path.\n *\n * @param  {string}   type       - Type of edges to retrieve.\n * @param  {string}   direction  - In or out?\n * @param  {NodeData} sourceData - Source node's data.\n * @param  {string}   target     - Target node.\n * @param  {function} callback   - Function to call.\n */\nfunction createEdgeIteratorForPath(type, direction, sourceData, target) {\n  let iterator = Iterator.empty();\n\n  if (type !== 'undirected') {\n    if (\n      typeof sourceData.in !== 'undefined' &&\n      direction !== 'out' &&\n      target in sourceData.in\n    )\n      iterator = chain(iterator, createIteratorForKey(sourceData.in, target));\n\n    if (\n      typeof sourceData.out !== 'undefined' &&\n      direction !== 'in' &&\n      target in sourceData.out &&\n      (direction || sourceData.key !== target)\n    )\n      iterator = chain(iterator, createIteratorForKey(sourceData.out, target));\n  }\n\n  if (type !== 'directed') {\n    if (\n      typeof sourceData.undirected !== 'undefined' &&\n      target in sourceData.undirected\n    )\n      iterator = chain(\n        iterator,\n        createIteratorForKey(sourceData.undirected, target)\n      );\n  }\n\n  return iterator;\n}\n\n/**\n * Function attaching an edge array creator method to the Graph prototype.\n *\n * @param {function} Class       - Target class.\n * @param {object}   description - Method description.\n */\nfunction attachEdgeArrayCreator(Class, description) {\n  const {name, type, direction} = description;\n\n  /**\n   * Function returning an array of certain edges.\n   *\n   * Arity 0: Return all the relevant edges.\n   *\n   * Arity 1: Return all of a node's relevant edges.\n   * @param  {any}   node   - Target node.\n   *\n   * Arity 2: Return the relevant edges across the given path.\n   * @param  {any}   source - Source node.\n   * @param  {any}   target - Target node.\n   *\n   * @return {array|number} - The edges or the number of edges.\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  Class.prototype[name] = function (source, target) {\n    // Early termination\n    if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type)\n      return [];\n\n    if (!arguments.length) return createEdgeArray(this, type);\n\n    if (arguments.length === 1) {\n      source = '' + source;\n\n      const nodeData = this._nodes.get(source);\n\n      if (typeof nodeData === 'undefined')\n        throw new NotFoundGraphError(\n          `Graph.${name}: could not find the \"${source}\" node in the graph.`\n        );\n\n      // Iterating over a node's edges\n      return createEdgeArrayForNode(\n        this.multi,\n        type === 'mixed' ? this.type : type,\n        direction,\n        nodeData\n      );\n    }\n\n    if (arguments.length === 2) {\n      source = '' + source;\n      target = '' + target;\n\n      const sourceData = this._nodes.get(source);\n\n      if (!sourceData)\n        throw new NotFoundGraphError(\n          `Graph.${name}:  could not find the \"${source}\" source node in the graph.`\n        );\n\n      if (!this._nodes.has(target))\n        throw new NotFoundGraphError(\n          `Graph.${name}:  could not find the \"${target}\" target node in the graph.`\n        );\n\n      // Iterating over the edges between source & target\n      return createEdgeArrayForPath(\n        type,\n        this.multi,\n        direction,\n        sourceData,\n        target\n      );\n    }\n\n    throw new InvalidArgumentsGraphError(\n      `Graph.${name}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).`\n    );\n  };\n}\n\n/**\n * Function attaching a edge callback iterator method to the Graph prototype.\n *\n * @param {function} Class       - Target class.\n * @param {object}   description - Method description.\n */\nfunction attachForEachEdge(Class, description) {\n  const {name, type, direction} = description;\n\n  const forEachName = 'forEach' + name[0].toUpperCase() + name.slice(1, -1);\n\n  /**\n   * Function iterating over the graph's relevant edges by applying the given\n   * callback.\n   *\n   * Arity 1: Iterate over all the relevant edges.\n   * @param  {function} callback - Callback to use.\n   *\n   * Arity 2: Iterate over all of a node's relevant edges.\n   * @param  {any}      node     - Target node.\n   * @param  {function} callback - Callback to use.\n   *\n   * Arity 3: Iterate over the relevant edges across the given path.\n   * @param  {any}      source   - Source node.\n   * @param  {any}      target   - Target node.\n   * @param  {function} callback - Callback to use.\n   *\n   * @return {undefined}\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  Class.prototype[forEachName] = function (source, target, callback) {\n    // Early termination\n    if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return;\n\n    if (arguments.length === 1) {\n      callback = source;\n      return forEachEdge(false, this, type, callback);\n    }\n\n    if (arguments.length === 2) {\n      source = '' + source;\n      callback = target;\n\n      const nodeData = this._nodes.get(source);\n\n      if (typeof nodeData === 'undefined')\n        throw new NotFoundGraphError(\n          `Graph.${forEachName}: could not find the \"${source}\" node in the graph.`\n        );\n\n      // Iterating over a node's edges\n      // TODO: maybe attach the sub method to the instance dynamically?\n      return forEachEdgeForNode(\n        false,\n        this.multi,\n        type === 'mixed' ? this.type : type,\n        direction,\n        nodeData,\n        callback\n      );\n    }\n\n    if (arguments.length === 3) {\n      source = '' + source;\n      target = '' + target;\n\n      const sourceData = this._nodes.get(source);\n\n      if (!sourceData)\n        throw new NotFoundGraphError(\n          `Graph.${forEachName}:  could not find the \"${source}\" source node in the graph.`\n        );\n\n      if (!this._nodes.has(target))\n        throw new NotFoundGraphError(\n          `Graph.${forEachName}:  could not find the \"${target}\" target node in the graph.`\n        );\n\n      // Iterating over the edges between source & target\n      return forEachEdgeForPath(\n        false,\n        type,\n        this.multi,\n        direction,\n        sourceData,\n        target,\n        callback\n      );\n    }\n\n    throw new InvalidArgumentsGraphError(\n      `Graph.${forEachName}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).`\n    );\n  };\n\n  /**\n   * Function mapping the graph's relevant edges by applying the given\n   * callback.\n   *\n   * Arity 1: Map all the relevant edges.\n   * @param  {function} callback - Callback to use.\n   *\n   * Arity 2: Map all of a node's relevant edges.\n   * @param  {any}      node     - Target node.\n   * @param  {function} callback - Callback to use.\n   *\n   * Arity 3: Map the relevant edges across the given path.\n   * @param  {any}      source   - Source node.\n   * @param  {any}      target   - Target node.\n   * @param  {function} callback - Callback to use.\n   *\n   * @return {undefined}\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  const mapName = 'map' + name[0].toUpperCase() + name.slice(1);\n\n  Class.prototype[mapName] = function () {\n    const args = Array.prototype.slice.call(arguments);\n    const callback = args.pop();\n\n    let result;\n\n    // We know the result length beforehand\n    if (args.length === 0) {\n      let length = 0;\n\n      if (type !== 'directed') length += this.undirectedSize;\n      if (type !== 'undirected') length += this.directedSize;\n\n      result = new Array(length);\n\n      let i = 0;\n\n      args.push((e, ea, s, t, sa, ta, u) => {\n        result[i++] = callback(e, ea, s, t, sa, ta, u);\n      });\n    }\n\n    // We don't know the result length beforehand\n    // TODO: we can in some instances of simple graphs, knowing degree\n    else {\n      result = [];\n\n      args.push((e, ea, s, t, sa, ta, u) => {\n        result.push(callback(e, ea, s, t, sa, ta, u));\n      });\n    }\n\n    this[forEachName].apply(this, args);\n\n    return result;\n  };\n\n  /**\n   * Function filtering the graph's relevant edges using the provided predicate\n   * function.\n   *\n   * Arity 1: Filter all the relevant edges.\n   * @param  {function} predicate - Predicate to use.\n   *\n   * Arity 2: Filter all of a node's relevant edges.\n   * @param  {any}      node      - Target node.\n   * @param  {function} predicate - Predicate to use.\n   *\n   * Arity 3: Filter the relevant edges across the given path.\n   * @param  {any}      source    - Source node.\n   * @param  {any}      target    - Target node.\n   * @param  {function} predicate - Predicate to use.\n   *\n   * @return {undefined}\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  const filterName = 'filter' + name[0].toUpperCase() + name.slice(1);\n\n  Class.prototype[filterName] = function () {\n    const args = Array.prototype.slice.call(arguments);\n    const callback = args.pop();\n\n    const result = [];\n\n    args.push((e, ea, s, t, sa, ta, u) => {\n      if (callback(e, ea, s, t, sa, ta, u)) result.push(e);\n    });\n\n    this[forEachName].apply(this, args);\n\n    return result;\n  };\n\n  /**\n   * Function reducing the graph's relevant edges using the provided accumulator\n   * function.\n   *\n   * Arity 1: Reduce all the relevant edges.\n   * @param  {function} accumulator  - Accumulator to use.\n   * @param  {any}      initialValue - Initial value.\n   *\n   * Arity 2: Reduce all of a node's relevant edges.\n   * @param  {any}      node         - Target node.\n   * @param  {function} accumulator  - Accumulator to use.\n   * @param  {any}      initialValue - Initial value.\n   *\n   * Arity 3: Reduce the relevant edges across the given path.\n   * @param  {any}      source       - Source node.\n   * @param  {any}      target       - Target node.\n   * @param  {function} accumulator  - Accumulator to use.\n   * @param  {any}      initialValue - Initial value.\n   *\n   * @return {undefined}\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  const reduceName = 'reduce' + name[0].toUpperCase() + name.slice(1);\n\n  Class.prototype[reduceName] = function () {\n    let args = Array.prototype.slice.call(arguments);\n\n    if (args.length < 2 || args.length > 4) {\n      throw new InvalidArgumentsGraphError(\n        `Graph.${reduceName}: invalid number of arguments (expecting 2, 3 or 4 and got ${args.length}).`\n      );\n    }\n\n    if (\n      typeof args[args.length - 1] === 'function' &&\n      typeof args[args.length - 2] !== 'function'\n    ) {\n      throw new InvalidArgumentsGraphError(\n        `Graph.${reduceName}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.`\n      );\n    }\n\n    let callback;\n    let initialValue;\n\n    if (args.length === 2) {\n      callback = args[0];\n      initialValue = args[1];\n      args = [];\n    } else if (args.length === 3) {\n      callback = args[1];\n      initialValue = args[2];\n      args = [args[0]];\n    } else if (args.length === 4) {\n      callback = args[2];\n      initialValue = args[3];\n      args = [args[0], args[1]];\n    }\n\n    let accumulator = initialValue;\n\n    args.push((e, ea, s, t, sa, ta, u) => {\n      accumulator = callback(accumulator, e, ea, s, t, sa, ta, u);\n    });\n\n    this[forEachName].apply(this, args);\n\n    return accumulator;\n  };\n}\n\n/**\n * Function attaching a breakable edge callback iterator method to the Graph\n * prototype.\n *\n * @param {function} Class       - Target class.\n * @param {object}   description - Method description.\n */\nfunction attachFindEdge(Class, description) {\n  const {name, type, direction} = description;\n\n  const findEdgeName = 'find' + name[0].toUpperCase() + name.slice(1, -1);\n\n  /**\n   * Function iterating over the graph's relevant edges in order to match\n   * one of them using the provided predicate function.\n   *\n   * Arity 1: Iterate over all the relevant edges.\n   * @param  {function} callback - Callback to use.\n   *\n   * Arity 2: Iterate over all of a node's relevant edges.\n   * @param  {any}      node     - Target node.\n   * @param  {function} callback - Callback to use.\n   *\n   * Arity 3: Iterate over the relevant edges across the given path.\n   * @param  {any}      source   - Source node.\n   * @param  {any}      target   - Target node.\n   * @param  {function} callback - Callback to use.\n   *\n   * @return {undefined}\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  Class.prototype[findEdgeName] = function (source, target, callback) {\n    // Early termination\n    if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type)\n      return false;\n\n    if (arguments.length === 1) {\n      callback = source;\n      return forEachEdge(true, this, type, callback);\n    }\n\n    if (arguments.length === 2) {\n      source = '' + source;\n      callback = target;\n\n      const nodeData = this._nodes.get(source);\n\n      if (typeof nodeData === 'undefined')\n        throw new NotFoundGraphError(\n          `Graph.${findEdgeName}: could not find the \"${source}\" node in the graph.`\n        );\n\n      // Iterating over a node's edges\n      // TODO: maybe attach the sub method to the instance dynamically?\n      return forEachEdgeForNode(\n        true,\n        this.multi,\n        type === 'mixed' ? this.type : type,\n        direction,\n        nodeData,\n        callback\n      );\n    }\n\n    if (arguments.length === 3) {\n      source = '' + source;\n      target = '' + target;\n\n      const sourceData = this._nodes.get(source);\n\n      if (!sourceData)\n        throw new NotFoundGraphError(\n          `Graph.${findEdgeName}:  could not find the \"${source}\" source node in the graph.`\n        );\n\n      if (!this._nodes.has(target))\n        throw new NotFoundGraphError(\n          `Graph.${findEdgeName}:  could not find the \"${target}\" target node in the graph.`\n        );\n\n      // Iterating over the edges between source & target\n      return forEachEdgeForPath(\n        true,\n        type,\n        this.multi,\n        direction,\n        sourceData,\n        target,\n        callback\n      );\n    }\n\n    throw new InvalidArgumentsGraphError(\n      `Graph.${findEdgeName}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).`\n    );\n  };\n\n  /**\n   * Function iterating over the graph's relevant edges in order to assert\n   * whether any one of them matches the provided predicate function.\n   *\n   * Arity 1: Iterate over all the relevant edges.\n   * @param  {function} callback - Callback to use.\n   *\n   * Arity 2: Iterate over all of a node's relevant edges.\n   * @param  {any}      node     - Target node.\n   * @param  {function} callback - Callback to use.\n   *\n   * Arity 3: Iterate over the relevant edges across the given path.\n   * @param  {any}      source   - Source node.\n   * @param  {any}      target   - Target node.\n   * @param  {function} callback - Callback to use.\n   *\n   * @return {undefined}\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  const someName = 'some' + name[0].toUpperCase() + name.slice(1, -1);\n\n  Class.prototype[someName] = function () {\n    const args = Array.prototype.slice.call(arguments);\n    const callback = args.pop();\n\n    args.push((e, ea, s, t, sa, ta, u) => {\n      return callback(e, ea, s, t, sa, ta, u);\n    });\n\n    const found = this[findEdgeName].apply(this, args);\n\n    if (found) return true;\n\n    return false;\n  };\n\n  /**\n   * Function iterating over the graph's relevant edges in order to assert\n   * whether all of them matche the provided predicate function.\n   *\n   * Arity 1: Iterate over all the relevant edges.\n   * @param  {function} callback - Callback to use.\n   *\n   * Arity 2: Iterate over all of a node's relevant edges.\n   * @param  {any}      node     - Target node.\n   * @param  {function} callback - Callback to use.\n   *\n   * Arity 3: Iterate over the relevant edges across the given path.\n   * @param  {any}      source   - Source node.\n   * @param  {any}      target   - Target node.\n   * @param  {function} callback - Callback to use.\n   *\n   * @return {undefined}\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  const everyName = 'every' + name[0].toUpperCase() + name.slice(1, -1);\n\n  Class.prototype[everyName] = function () {\n    const args = Array.prototype.slice.call(arguments);\n    const callback = args.pop();\n\n    args.push((e, ea, s, t, sa, ta, u) => {\n      return !callback(e, ea, s, t, sa, ta, u);\n    });\n\n    const found = this[findEdgeName].apply(this, args);\n\n    if (found) return false;\n\n    return true;\n  };\n}\n\n/**\n * Function attaching an edge iterator method to the Graph prototype.\n *\n * @param {function} Class       - Target class.\n * @param {object}   description - Method description.\n */\nfunction attachEdgeIteratorCreator(Class, description) {\n  const {name: originalName, type, direction} = description;\n\n  const name = originalName.slice(0, -1) + 'Entries';\n\n  /**\n   * Function returning an iterator over the graph's edges.\n   *\n   * Arity 0: Iterate over all the relevant edges.\n   *\n   * Arity 1: Iterate over all of a node's relevant edges.\n   * @param  {any}   node   - Target node.\n   *\n   * Arity 2: Iterate over the relevant edges across the given path.\n   * @param  {any}   source - Source node.\n   * @param  {any}   target - Target node.\n   *\n   * @return {array|number} - The edges or the number of edges.\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  Class.prototype[name] = function (source, target) {\n    // Early termination\n    if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type)\n      return Iterator.empty();\n\n    if (!arguments.length) return createEdgeIterator(this, type);\n\n    if (arguments.length === 1) {\n      source = '' + source;\n\n      const sourceData = this._nodes.get(source);\n\n      if (!sourceData)\n        throw new NotFoundGraphError(\n          `Graph.${name}: could not find the \"${source}\" node in the graph.`\n        );\n\n      // Iterating over a node's edges\n      return createEdgeIteratorForNode(type, direction, sourceData);\n    }\n\n    if (arguments.length === 2) {\n      source = '' + source;\n      target = '' + target;\n\n      const sourceData = this._nodes.get(source);\n\n      if (!sourceData)\n        throw new NotFoundGraphError(\n          `Graph.${name}:  could not find the \"${source}\" source node in the graph.`\n        );\n\n      if (!this._nodes.has(target))\n        throw new NotFoundGraphError(\n          `Graph.${name}:  could not find the \"${target}\" target node in the graph.`\n        );\n\n      // Iterating over the edges between source & target\n      return createEdgeIteratorForPath(type, direction, sourceData, target);\n    }\n\n    throw new InvalidArgumentsGraphError(\n      `Graph.${name}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).`\n    );\n  };\n}\n\n/**\n * Function attaching every edge iteration method to the Graph class.\n *\n * @param {function} Graph - Graph class.\n */\nexport default function attachEdgeIterationMethods(Graph) {\n  EDGES_ITERATION.forEach(description => {\n    attachEdgeArrayCreator(Graph, description);\n    attachForEachEdge(Graph, description);\n    attachFindEdge(Graph, description);\n    attachEdgeIteratorCreator(Graph, description);\n  });\n}\n","/**\n * Graphology Neighbor Iteration\n * ==============================\n *\n * Attaching some methods to the Graph class to be able to iterate over\n * neighbors.\n */\nimport Iterator from 'obliterator/iterator';\nimport chain from 'obliterator/chain';\n\nimport {NotFoundGraphError, InvalidArgumentsGraphError} from '../errors';\n\n/**\n * Definitions.\n */\nconst NEIGHBORS_ITERATION = [\n  {\n    name: 'neighbors',\n    type: 'mixed'\n  },\n  {\n    name: 'inNeighbors',\n    type: 'directed',\n    direction: 'in'\n  },\n  {\n    name: 'outNeighbors',\n    type: 'directed',\n    direction: 'out'\n  },\n  {\n    name: 'inboundNeighbors',\n    type: 'mixed',\n    direction: 'in'\n  },\n  {\n    name: 'outboundNeighbors',\n    type: 'mixed',\n    direction: 'out'\n  },\n  {\n    name: 'directedNeighbors',\n    type: 'directed'\n  },\n  {\n    name: 'undirectedNeighbors',\n    type: 'undirected'\n  }\n];\n\n/**\n * Helpers.\n */\nfunction CompositeSetWrapper() {\n  this.A = null;\n  this.B = null;\n}\n\nCompositeSetWrapper.prototype.wrap = function (set) {\n  if (this.A === null) this.A = set;\n  else if (this.B === null) this.B = set;\n};\n\nCompositeSetWrapper.prototype.has = function (key) {\n  if (this.A !== null && key in this.A) return true;\n  if (this.B !== null && key in this.B) return true;\n  return false;\n};\n\n/**\n * Function iterating over the given node's relevant neighbors to match\n * one of them using a predicated function.\n *\n * @param  {string}   type      - Type of neighbors.\n * @param  {string}   direction - Direction.\n * @param  {any}      nodeData  - Target node's data.\n * @param  {function} callback  - Callback to use.\n */\nfunction forEachInObjectOnce(breakable, visited, nodeData, object, callback) {\n  for (const k in object) {\n    const edgeData = object[k];\n\n    const sourceData = edgeData.source;\n    const targetData = edgeData.target;\n\n    const neighborData = sourceData === nodeData ? targetData : sourceData;\n\n    if (visited && visited.has(neighborData.key)) continue;\n\n    const shouldBreak = callback(neighborData.key, neighborData.attributes);\n\n    if (breakable && shouldBreak) return neighborData.key;\n  }\n\n  return;\n}\n\nfunction forEachNeighbor(breakable, type, direction, nodeData, callback) {\n  // If we want only undirected or in or out, we can roll some optimizations\n  if (type !== 'mixed') {\n    if (type === 'undirected')\n      return forEachInObjectOnce(\n        breakable,\n        null,\n        nodeData,\n        nodeData.undirected,\n        callback\n      );\n\n    if (typeof direction === 'string')\n      return forEachInObjectOnce(\n        breakable,\n        null,\n        nodeData,\n        nodeData[direction],\n        callback\n      );\n  }\n\n  // Else we need to keep a set of neighbors not to return duplicates\n  // We cheat by querying the other adjacencies\n  const visited = new CompositeSetWrapper();\n\n  let found;\n\n  if (type !== 'undirected') {\n    if (direction !== 'out') {\n      found = forEachInObjectOnce(\n        breakable,\n        null,\n        nodeData,\n        nodeData.in,\n        callback\n      );\n\n      if (breakable && found) return found;\n\n      visited.wrap(nodeData.in);\n    }\n    if (direction !== 'in') {\n      found = forEachInObjectOnce(\n        breakable,\n        visited,\n        nodeData,\n        nodeData.out,\n        callback\n      );\n\n      if (breakable && found) return found;\n\n      visited.wrap(nodeData.out);\n    }\n  }\n\n  if (type !== 'directed') {\n    found = forEachInObjectOnce(\n      breakable,\n      visited,\n      nodeData,\n      nodeData.undirected,\n      callback\n    );\n\n    if (breakable && found) return found;\n  }\n\n  return;\n}\n\n/**\n * Function creating an array of relevant neighbors for the given node.\n *\n * @param  {string}       type      - Type of neighbors.\n * @param  {string}       direction - Direction.\n * @param  {any}          nodeData  - Target node's data.\n * @return {Array}                  - The list of neighbors.\n */\nfunction createNeighborArrayForNode(type, direction, nodeData) {\n  // If we want only undirected or in or out, we can roll some optimizations\n  if (type !== 'mixed') {\n    if (type === 'undirected') return Object.keys(nodeData.undirected);\n\n    if (typeof direction === 'string') return Object.keys(nodeData[direction]);\n  }\n\n  const neighbors = [];\n\n  forEachNeighbor(false, type, direction, nodeData, function (key) {\n    neighbors.push(key);\n  });\n\n  return neighbors;\n}\n\n/**\n * Function returning an iterator over the given node's relevant neighbors.\n *\n * @param  {string}   type      - Type of neighbors.\n * @param  {string}   direction - Direction.\n * @param  {any}      nodeData  - Target node's data.\n * @return {Iterator}\n */\nfunction createDedupedObjectIterator(visited, nodeData, object) {\n  const keys = Object.keys(object);\n  const l = keys.length;\n\n  let i = 0;\n\n  return new Iterator(function next() {\n    let neighborData = null;\n\n    do {\n      if (i >= l) {\n        if (visited) visited.wrap(object);\n        return {done: true};\n      }\n\n      const edgeData = object[keys[i++]];\n\n      const sourceData = edgeData.source;\n      const targetData = edgeData.target;\n\n      neighborData = sourceData === nodeData ? targetData : sourceData;\n\n      if (visited && visited.has(neighborData.key)) {\n        neighborData = null;\n        continue;\n      }\n    } while (neighborData === null);\n\n    return {\n      done: false,\n      value: {neighbor: neighborData.key, attributes: neighborData.attributes}\n    };\n  });\n}\n\nfunction createNeighborIterator(type, direction, nodeData) {\n  // If we want only undirected or in or out, we can roll some optimizations\n  if (type !== 'mixed') {\n    if (type === 'undirected')\n      return createDedupedObjectIterator(null, nodeData, nodeData.undirected);\n\n    if (typeof direction === 'string')\n      return createDedupedObjectIterator(null, nodeData, nodeData[direction]);\n  }\n\n  let iterator = Iterator.empty();\n\n  // Else we need to keep a set of neighbors not to return duplicates\n  // We cheat by querying the other adjacencies\n  const visited = new CompositeSetWrapper();\n\n  if (type !== 'undirected') {\n    if (direction !== 'out') {\n      iterator = chain(\n        iterator,\n        createDedupedObjectIterator(visited, nodeData, nodeData.in)\n      );\n    }\n    if (direction !== 'in') {\n      iterator = chain(\n        iterator,\n        createDedupedObjectIterator(visited, nodeData, nodeData.out)\n      );\n    }\n  }\n\n  if (type !== 'directed') {\n    iterator = chain(\n      iterator,\n      createDedupedObjectIterator(visited, nodeData, nodeData.undirected)\n    );\n  }\n\n  return iterator;\n}\n\n/**\n * Function attaching a neighbors array creator method to the Graph prototype.\n *\n * @param {function} Class       - Target class.\n * @param {object}   description - Method description.\n */\nfunction attachNeighborArrayCreator(Class, description) {\n  const {name, type, direction} = description;\n\n  /**\n   * Function returning an array of certain neighbors.\n   *\n   * @param  {any}   node   - Target node.\n   * @return {array} - The neighbors of neighbors.\n   *\n   * @throws {Error} - Will throw if node is not found in the graph.\n   */\n  Class.prototype[name] = function (node) {\n    // Early termination\n    if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type)\n      return [];\n\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (typeof nodeData === 'undefined')\n      throw new NotFoundGraphError(\n        `Graph.${name}: could not find the \"${node}\" node in the graph.`\n      );\n\n    // Here, we want to iterate over a node's relevant neighbors\n    return createNeighborArrayForNode(\n      type === 'mixed' ? this.type : type,\n      direction,\n      nodeData\n    );\n  };\n}\n\n/**\n * Function attaching a neighbors callback iterator method to the Graph prototype.\n *\n * @param {function} Class       - Target class.\n * @param {object}   description - Method description.\n */\nfunction attachForEachNeighbor(Class, description) {\n  const {name, type, direction} = description;\n\n  const forEachName = 'forEach' + name[0].toUpperCase() + name.slice(1, -1);\n\n  /**\n   * Function iterating over all the relevant neighbors using a callback.\n   *\n   * @param  {any}      node     - Target node.\n   * @param  {function} callback - Callback to use.\n   * @return {undefined}\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  Class.prototype[forEachName] = function (node, callback) {\n    // Early termination\n    if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return;\n\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (typeof nodeData === 'undefined')\n      throw new NotFoundGraphError(\n        `Graph.${forEachName}: could not find the \"${node}\" node in the graph.`\n      );\n\n    // Here, we want to iterate over a node's relevant neighbors\n    forEachNeighbor(\n      false,\n      type === 'mixed' ? this.type : type,\n      direction,\n      nodeData,\n      callback\n    );\n  };\n\n  /**\n   * Function mapping the relevant neighbors using a callback.\n   *\n   * @param  {any}      node     - Target node.\n   * @param  {function} callback - Callback to use.\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  const mapName = 'map' + name[0].toUpperCase() + name.slice(1);\n\n  Class.prototype[mapName] = function (node, callback) {\n    // TODO: optimize when size is known beforehand\n    const result = [];\n\n    this[forEachName](node, (n, a) => {\n      result.push(callback(n, a));\n    });\n\n    return result;\n  };\n\n  /**\n   * Function filtering the relevant neighbors using a callback.\n   *\n   * @param  {any}      node     - Target node.\n   * @param  {function} callback - Callback to use.\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  const filterName = 'filter' + name[0].toUpperCase() + name.slice(1);\n\n  Class.prototype[filterName] = function (node, callback) {\n    const result = [];\n\n    this[forEachName](node, (n, a) => {\n      if (callback(n, a)) result.push(n);\n    });\n\n    return result;\n  };\n\n  /**\n   * Function reducing the relevant neighbors using a callback.\n   *\n   * @param  {any}      node     - Target node.\n   * @param  {function} callback - Callback to use.\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  const reduceName = 'reduce' + name[0].toUpperCase() + name.slice(1);\n\n  Class.prototype[reduceName] = function (node, callback, initialValue) {\n    if (arguments.length < 3)\n      throw new InvalidArgumentsGraphError(\n        `Graph.${reduceName}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.`\n      );\n\n    let accumulator = initialValue;\n\n    this[forEachName](node, (n, a) => {\n      accumulator = callback(accumulator, n, a);\n    });\n\n    return accumulator;\n  };\n}\n\n/**\n * Function attaching a breakable neighbors callback iterator method to the\n * Graph prototype.\n *\n * @param {function} Class       - Target class.\n * @param {object}   description - Method description.\n */\nfunction attachFindNeighbor(Class, description) {\n  const {name, type, direction} = description;\n\n  const capitalizedSingular = name[0].toUpperCase() + name.slice(1, -1);\n\n  const findName = 'find' + capitalizedSingular;\n\n  /**\n   * Function iterating over all the relevant neighbors using a callback.\n   *\n   * @param  {any}      node     - Target node.\n   * @param  {function} callback - Callback to use.\n   * @return {undefined}\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  Class.prototype[findName] = function (node, callback) {\n    // Early termination\n    if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return;\n\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (typeof nodeData === 'undefined')\n      throw new NotFoundGraphError(\n        `Graph.${findName}: could not find the \"${node}\" node in the graph.`\n      );\n\n    // Here, we want to iterate over a node's relevant neighbors\n    return forEachNeighbor(\n      true,\n      type === 'mixed' ? this.type : type,\n      direction,\n      nodeData,\n      callback\n    );\n  };\n\n  /**\n   * Function iterating over all the relevant neighbors to find if any of them\n   * matches the given predicate.\n   *\n   * @param  {any}      node     - Target node.\n   * @param  {function} callback - Callback to use.\n   * @return {boolean}\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  const someName = 'some' + capitalizedSingular;\n\n  Class.prototype[someName] = function (node, callback) {\n    const found = this[findName](node, callback);\n\n    if (found) return true;\n\n    return false;\n  };\n\n  /**\n   * Function iterating over all the relevant neighbors to find if all of them\n   * matche the given predicate.\n   *\n   * @param  {any}      node     - Target node.\n   * @param  {function} callback - Callback to use.\n   * @return {boolean}\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  const everyName = 'every' + capitalizedSingular;\n\n  Class.prototype[everyName] = function (node, callback) {\n    const found = this[findName](node, (n, a) => {\n      return !callback(n, a);\n    });\n\n    if (found) return false;\n\n    return true;\n  };\n}\n\n/**\n * Function attaching a neighbors callback iterator method to the Graph prototype.\n *\n * @param {function} Class       - Target class.\n * @param {object}   description - Method description.\n */\nfunction attachNeighborIteratorCreator(Class, description) {\n  const {name, type, direction} = description;\n\n  const iteratorName = name.slice(0, -1) + 'Entries';\n\n  /**\n   * Function returning an iterator over all the relevant neighbors.\n   *\n   * @param  {any}      node     - Target node.\n   * @return {Iterator}\n   *\n   * @throws {Error} - Will throw if there are too many arguments.\n   */\n  Class.prototype[iteratorName] = function (node) {\n    // Early termination\n    if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type)\n      return Iterator.empty();\n\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (typeof nodeData === 'undefined')\n      throw new NotFoundGraphError(\n        `Graph.${iteratorName}: could not find the \"${node}\" node in the graph.`\n      );\n\n    // Here, we want to iterate over a node's relevant neighbors\n    return createNeighborIterator(\n      type === 'mixed' ? this.type : type,\n      direction,\n      nodeData\n    );\n  };\n}\n\n/**\n * Function attaching every neighbor iteration method to the Graph class.\n *\n * @param {function} Graph - Graph class.\n */\nexport default function attachNeighborIterationMethods(Graph) {\n  NEIGHBORS_ITERATION.forEach(description => {\n    attachNeighborArrayCreator(Graph, description);\n    attachForEachNeighbor(Graph, description);\n    attachFindNeighbor(Graph, description);\n    attachNeighborIteratorCreator(Graph, description);\n  });\n}\n","/**\n * Graphology Adjacency Iteration\n * ===============================\n *\n * Attaching some methods to the Graph class to be able to iterate over a\n * graph's adjacency.\n */\n\n/**\n * Function iterating over a simple graph's adjacency using a callback.\n *\n * @param {boolean}  breakable         - Can we break?\n * @param {boolean}  assymetric        - Whether to emit undirected edges only once.\n * @param {boolean}  disconnectedNodes - Whether to emit disconnected nodes.\n * @param {Graph}    graph             - Target Graph instance.\n * @param {callback} function          - Iteration callback.\n */\nexport function forEachAdjacency(\n  breakable,\n  assymetric,\n  disconnectedNodes,\n  graph,\n  callback\n) {\n  const iterator = graph._nodes.values();\n\n  const type = graph.type;\n\n  let step, sourceData, neighbor, adj, edgeData, targetData, shouldBreak;\n\n  while (((step = iterator.next()), step.done !== true)) {\n    let hasEdges = false;\n\n    sourceData = step.value;\n\n    if (type !== 'undirected') {\n      adj = sourceData.out;\n\n      for (neighbor in adj) {\n        edgeData = adj[neighbor];\n\n        do {\n          targetData = edgeData.target;\n\n          hasEdges = true;\n          shouldBreak = callback(\n            sourceData.key,\n            targetData.key,\n            sourceData.attributes,\n            targetData.attributes,\n            edgeData.key,\n            edgeData.attributes,\n            edgeData.undirected\n          );\n\n          if (breakable && shouldBreak) return edgeData;\n\n          edgeData = edgeData.next;\n        } while (edgeData);\n      }\n    }\n\n    if (type !== 'directed') {\n      adj = sourceData.undirected;\n\n      for (neighbor in adj) {\n        if (assymetric && sourceData.key > neighbor) continue;\n\n        edgeData = adj[neighbor];\n\n        do {\n          targetData = edgeData.target;\n\n          if (targetData.key !== neighbor) targetData = edgeData.source;\n\n          hasEdges = true;\n          shouldBreak = callback(\n            sourceData.key,\n            targetData.key,\n            sourceData.attributes,\n            targetData.attributes,\n            edgeData.key,\n            edgeData.attributes,\n            edgeData.undirected\n          );\n\n          if (breakable && shouldBreak) return edgeData;\n\n          edgeData = edgeData.next;\n        } while (edgeData);\n      }\n    }\n\n    if (disconnectedNodes && !hasEdges) {\n      shouldBreak = callback(\n        sourceData.key,\n        null,\n        sourceData.attributes,\n        null,\n        null,\n        null,\n        null\n      );\n\n      if (breakable && shouldBreak) return null;\n    }\n  }\n\n  return;\n}\n","/**\n * Graphology Serialization Utilities\n * ===================================\n *\n * Collection of functions used by the graph serialization schemes.\n */\nimport {InvalidArgumentsGraphError} from './errors';\nimport {assign, isPlainObject, isEmpty} from './utils';\n\n/**\n * Formats internal node data into a serialized node.\n *\n * @param  {any}    key  - The node's key.\n * @param  {object} data - Internal node's data.\n * @return {array}       - The serialized node.\n */\nexport function serializeNode(key, data) {\n  const serialized = {key};\n\n  if (!isEmpty(data.attributes))\n    serialized.attributes = assign({}, data.attributes);\n\n  return serialized;\n}\n\n/**\n * Formats internal edge data into a serialized edge.\n *\n * @param  {string} type - The graph's type.\n * @param  {any}    key  - The edge's key.\n * @param  {object} data - Internal edge's data.\n * @return {array}       - The serialized edge.\n */\nexport function serializeEdge(type, key, data) {\n  const serialized = {\n    key,\n    source: data.source.key,\n    target: data.target.key\n  };\n\n  if (!isEmpty(data.attributes))\n    serialized.attributes = assign({}, data.attributes);\n\n  if (type === 'mixed' && data.undirected) serialized.undirected = true;\n\n  return serialized;\n}\n\n/**\n * Checks whether the given value is a serialized node.\n *\n * @param  {mixed} value - Target value.\n * @return {string|null}\n */\nexport function validateSerializedNode(value) {\n  if (!isPlainObject(value))\n    throw new InvalidArgumentsGraphError(\n      'Graph.import: invalid serialized node. A serialized node should be a plain object with at least a \"key\" property.'\n    );\n\n  if (!('key' in value))\n    throw new InvalidArgumentsGraphError(\n      'Graph.import: serialized node is missing its key.'\n    );\n\n  if (\n    'attributes' in value &&\n    (!isPlainObject(value.attributes) || value.attributes === null)\n  )\n    throw new InvalidArgumentsGraphError(\n      'Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.'\n    );\n}\n\n/**\n * Checks whether the given value is a serialized edge.\n *\n * @param  {mixed} value - Target value.\n * @return {string|null}\n */\nexport function validateSerializedEdge(value) {\n  if (!isPlainObject(value))\n    throw new InvalidArgumentsGraphError(\n      'Graph.import: invalid serialized edge. A serialized edge should be a plain object with at least a \"source\" & \"target\" property.'\n    );\n\n  if (!('source' in value))\n    throw new InvalidArgumentsGraphError(\n      'Graph.import: serialized edge is missing its source.'\n    );\n\n  if (!('target' in value))\n    throw new InvalidArgumentsGraphError(\n      'Graph.import: serialized edge is missing its target.'\n    );\n\n  if (\n    'attributes' in value &&\n    (!isPlainObject(value.attributes) || value.attributes === null)\n  )\n    throw new InvalidArgumentsGraphError(\n      'Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.'\n    );\n\n  if ('undirected' in value && typeof value.undirected !== 'boolean')\n    throw new InvalidArgumentsGraphError(\n      'Graph.import: invalid undirectedness information. Undirected should be boolean or omitted.'\n    );\n}\n","/* eslint no-nested-ternary: 0 */\n/**\n * Graphology Reference Implementation\n * ====================================\n *\n * Reference implementation of the graphology specs.\n */\nimport {EventEmitter} from 'events';\nimport Iterator from 'obliterator/iterator';\nimport take from 'obliterator/take';\n\nimport {\n  InvalidArgumentsGraphError,\n  NotFoundGraphError,\n  UsageGraphError\n} from './errors';\n\nimport {\n  MixedNodeData,\n  DirectedNodeData,\n  UndirectedNodeData,\n  EdgeData\n} from './data';\n\nimport attachNodeAttributesMethods from './attributes/nodes';\nimport attachEdgeAttributesMethods from './attributes/edges';\nimport attachEdgeIterationMethods from './iteration/edges';\nimport attachNeighborIterationMethods from './iteration/neighbors';\nimport {forEachAdjacency} from './iteration/adjacency';\n\nimport {\n  serializeNode,\n  serializeEdge,\n  validateSerializedNode,\n  validateSerializedEdge\n} from './serialization';\n\nimport {\n  assign,\n  getMatchingEdge,\n  isPlainObject,\n  privateProperty,\n  readOnlyProperty,\n  incrementalIdStartingFromRandomByte,\n  validateHints\n} from './utils';\n\n/**\n * Constants.\n */\nconst INSTANCE_ID = incrementalIdStartingFromRandomByte();\n\n/**\n * Enums.\n */\nconst TYPES = new Set(['directed', 'undirected', 'mixed']);\n\nconst EMITTER_PROPS = new Set([\n  'domain',\n  '_events',\n  '_eventsCount',\n  '_maxListeners'\n]);\n\nconst EDGE_ADD_METHODS = [\n  {\n    name: verb => `${verb}Edge`,\n    generateKey: true\n  },\n  {\n    name: verb => `${verb}DirectedEdge`,\n    generateKey: true,\n    type: 'directed'\n  },\n  {\n    name: verb => `${verb}UndirectedEdge`,\n    generateKey: true,\n    type: 'undirected'\n  },\n  {\n    name: verb => `${verb}EdgeWithKey`\n  },\n  {\n    name: verb => `${verb}DirectedEdgeWithKey`,\n    type: 'directed'\n  },\n  {\n    name: verb => `${verb}UndirectedEdgeWithKey`,\n    type: 'undirected'\n  }\n];\n\n/**\n * Default options.\n */\nconst DEFAULTS = {\n  allowSelfLoops: true,\n  multi: false,\n  type: 'mixed'\n};\n\n/**\n * Abstract functions used by the Graph class for various methods.\n */\n\n/**\n * Internal method used to add a node to the given graph\n *\n * @param  {Graph}   graph           - Target graph.\n * @param  {any}     node            - The node's key.\n * @param  {object}  [attributes]    - Optional attributes.\n * @return {NodeData}                - Created node data.\n */\nfunction addNode(graph, node, attributes) {\n  if (attributes && !isPlainObject(attributes))\n    throw new InvalidArgumentsGraphError(\n      `Graph.addNode: invalid attributes. Expecting an object but got \"${attributes}\"`\n    );\n\n  // String coercion\n  node = '' + node;\n  attributes = attributes || {};\n\n  if (graph._nodes.has(node))\n    throw new UsageGraphError(\n      `Graph.addNode: the \"${node}\" node already exist in the graph.`\n    );\n\n  const data = new graph.NodeDataClass(node, attributes);\n\n  // Adding the node to internal register\n  graph._nodes.set(node, data);\n\n  // Emitting\n  graph.emit('nodeAdded', {\n    key: node,\n    attributes\n  });\n\n  return data;\n}\n\n/**\n * Same as the above but without sanity checks because we call this in contexts\n * where necessary checks were already done.\n */\nfunction unsafeAddNode(graph, node, attributes) {\n  const data = new graph.NodeDataClass(node, attributes);\n\n  graph._nodes.set(node, data);\n\n  graph.emit('nodeAdded', {\n    key: node,\n    attributes\n  });\n\n  return data;\n}\n\n/**\n * Internal method used to add an arbitrary edge to the given graph.\n *\n * @param  {Graph}   graph           - Target graph.\n * @param  {string}  name            - Name of the child method for errors.\n * @param  {boolean} mustGenerateKey - Should the graph generate an id?\n * @param  {boolean} undirected      - Whether the edge is undirected.\n * @param  {any}     edge            - The edge's key.\n * @param  {any}     source          - The source node.\n * @param  {any}     target          - The target node.\n * @param  {object}  [attributes]    - Optional attributes.\n * @return {any}                     - The edge.\n *\n * @throws {Error} - Will throw if the graph is of the wrong type.\n * @throws {Error} - Will throw if the given attributes are not an object.\n * @throws {Error} - Will throw if source or target doesn't exist.\n * @throws {Error} - Will throw if the edge already exist.\n */\nfunction addEdge(\n  graph,\n  name,\n  mustGenerateKey,\n  undirected,\n  edge,\n  source,\n  target,\n  attributes\n) {\n  // Checking validity of operation\n  if (!undirected && graph.type === 'undirected')\n    throw new UsageGraphError(\n      `Graph.${name}: you cannot add a directed edge to an undirected graph. Use the #.addEdge or #.addUndirectedEdge instead.`\n    );\n\n  if (undirected && graph.type === 'directed')\n    throw new UsageGraphError(\n      `Graph.${name}: you cannot add an undirected edge to a directed graph. Use the #.addEdge or #.addDirectedEdge instead.`\n    );\n\n  if (attributes && !isPlainObject(attributes))\n    throw new InvalidArgumentsGraphError(\n      `Graph.${name}: invalid attributes. Expecting an object but got \"${attributes}\"`\n    );\n\n  // Coercion of source & target:\n  source = '' + source;\n  target = '' + target;\n  attributes = attributes || {};\n\n  if (!graph.allowSelfLoops && source === target)\n    throw new UsageGraphError(\n      `Graph.${name}: source & target are the same (\"${source}\"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.`\n    );\n\n  const sourceData = graph._nodes.get(source),\n    targetData = graph._nodes.get(target);\n\n  if (!sourceData)\n    throw new NotFoundGraphError(\n      `Graph.${name}: source node \"${source}\" not found.`\n    );\n\n  if (!targetData)\n    throw new NotFoundGraphError(\n      `Graph.${name}: target node \"${target}\" not found.`\n    );\n\n  // Must the graph generate an id for this edge?\n  const eventData = {\n    key: null,\n    undirected,\n    source,\n    target,\n    attributes\n  };\n\n  if (mustGenerateKey) {\n    // NOTE: in this case we can guarantee that the key does not already\n    // exist and is already correctly casted as a string\n    edge = graph._edgeKeyGenerator();\n  } else {\n    // Coercion of edge key\n    edge = '' + edge;\n\n    // Here, we have a key collision\n    if (graph._edges.has(edge))\n      throw new UsageGraphError(\n        `Graph.${name}: the \"${edge}\" edge already exists in the graph.`\n      );\n  }\n\n  // Here, we might have a source / target collision\n  if (\n    !graph.multi &&\n    (undirected\n      ? typeof sourceData.undirected[target] !== 'undefined'\n      : typeof sourceData.out[target] !== 'undefined')\n  ) {\n    throw new UsageGraphError(\n      `Graph.${name}: an edge linking \"${source}\" to \"${target}\" already exists. If you really want to add multiple edges linking those nodes, you should create a multi graph by using the 'multi' option.`\n    );\n  }\n\n  // Storing some data\n  const edgeData = new EdgeData(\n    undirected,\n    edge,\n    sourceData,\n    targetData,\n    attributes\n  );\n\n  // Adding the edge to the internal register\n  graph._edges.set(edge, edgeData);\n\n  // Incrementing node degree counters\n  const isSelfLoop = source === target;\n\n  if (undirected) {\n    sourceData.undirectedDegree++;\n    targetData.undirectedDegree++;\n\n    if (isSelfLoop) {\n      sourceData.undirectedLoops++;\n      graph._undirectedSelfLoopCount++;\n    }\n  } else {\n    sourceData.outDegree++;\n    targetData.inDegree++;\n\n    if (isSelfLoop) {\n      sourceData.directedLoops++;\n      graph._directedSelfLoopCount++;\n    }\n  }\n\n  // Updating relevant index\n  if (graph.multi) edgeData.attachMulti();\n  else edgeData.attach();\n\n  if (undirected) graph._undirectedSize++;\n  else graph._directedSize++;\n\n  // Emitting\n  eventData.key = edge;\n\n  graph.emit('edgeAdded', eventData);\n\n  return edge;\n}\n\n/**\n * Internal method used to add an arbitrary edge to the given graph.\n *\n * @param  {Graph}   graph           - Target graph.\n * @param  {string}  name            - Name of the child method for errors.\n * @param  {boolean} mustGenerateKey - Should the graph generate an id?\n * @param  {boolean} undirected      - Whether the edge is undirected.\n * @param  {any}     edge            - The edge's key.\n * @param  {any}     source          - The source node.\n * @param  {any}     target          - The target node.\n * @param  {object}  [attributes]    - Optional attributes.\n * @param  {boolean} [asUpdater]       - Are we updating or merging?\n * @return {any}                     - The edge.\n *\n * @throws {Error} - Will throw if the graph is of the wrong type.\n * @throws {Error} - Will throw if the given attributes are not an object.\n * @throws {Error} - Will throw if source or target doesn't exist.\n * @throws {Error} - Will throw if the edge already exist.\n */\nfunction mergeEdge(\n  graph,\n  name,\n  mustGenerateKey,\n  undirected,\n  edge,\n  source,\n  target,\n  attributes,\n  asUpdater\n) {\n  // Checking validity of operation\n  if (!undirected && graph.type === 'undirected')\n    throw new UsageGraphError(\n      `Graph.${name}: you cannot merge/update a directed edge to an undirected graph. Use the #.mergeEdge/#.updateEdge or #.addUndirectedEdge instead.`\n    );\n\n  if (undirected && graph.type === 'directed')\n    throw new UsageGraphError(\n      `Graph.${name}: you cannot merge/update an undirected edge to a directed graph. Use the #.mergeEdge/#.updateEdge or #.addDirectedEdge instead.`\n    );\n\n  if (attributes) {\n    if (asUpdater) {\n      if (typeof attributes !== 'function')\n        throw new InvalidArgumentsGraphError(\n          `Graph.${name}: invalid updater function. Expecting a function but got \"${attributes}\"`\n        );\n    } else {\n      if (!isPlainObject(attributes))\n        throw new InvalidArgumentsGraphError(\n          `Graph.${name}: invalid attributes. Expecting an object but got \"${attributes}\"`\n        );\n    }\n  }\n\n  // Coercion of source & target:\n  source = '' + source;\n  target = '' + target;\n\n  let updater;\n\n  if (asUpdater) {\n    updater = attributes;\n    attributes = undefined;\n  }\n\n  if (!graph.allowSelfLoops && source === target)\n    throw new UsageGraphError(\n      `Graph.${name}: source & target are the same (\"${source}\"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.`\n    );\n\n  let sourceData = graph._nodes.get(source);\n  let targetData = graph._nodes.get(target);\n  let edgeData;\n\n  // Do we need to handle duplicate?\n  let alreadyExistingEdgeData;\n\n  if (!mustGenerateKey) {\n    edgeData = graph._edges.get(edge);\n\n    if (edgeData) {\n      // Here, we need to ensure, if the user gave a key, that source & target\n      // are consistent\n      if (edgeData.source.key !== source || edgeData.target.key !== target) {\n        // If source or target inconsistent\n        if (\n          !undirected ||\n          edgeData.source.key !== target ||\n          edgeData.target.key !== source\n        ) {\n          // If directed, or source/target aren't flipped\n          throw new UsageGraphError(\n            `Graph.${name}: inconsistency detected when attempting to merge the \"${edge}\" edge with \"${source}\" source & \"${target}\" target vs. (\"${edgeData.source.key}\", \"${edgeData.target.key}\").`\n          );\n        }\n      }\n\n      alreadyExistingEdgeData = edgeData;\n    }\n  }\n\n  // Here, we might have a source / target collision\n  if (!alreadyExistingEdgeData && !graph.multi && sourceData) {\n    alreadyExistingEdgeData = undirected\n      ? sourceData.undirected[target]\n      : sourceData.out[target];\n  }\n\n  // Handling duplicates\n  if (alreadyExistingEdgeData) {\n    const info = [alreadyExistingEdgeData.key, false, false, false];\n\n    // We can skip the attribute merging part if the user did not provide them\n    if (asUpdater ? !updater : !attributes) return info;\n\n    // Updating the attributes\n    if (asUpdater) {\n      const oldAttributes = alreadyExistingEdgeData.attributes;\n      alreadyExistingEdgeData.attributes = updater(oldAttributes);\n\n      graph.emit('edgeAttributesUpdated', {\n        type: 'replace',\n        key: alreadyExistingEdgeData.key,\n        attributes: alreadyExistingEdgeData.attributes\n      });\n    }\n\n    // Merging the attributes\n    else {\n      assign(alreadyExistingEdgeData.attributes, attributes);\n\n      graph.emit('edgeAttributesUpdated', {\n        type: 'merge',\n        key: alreadyExistingEdgeData.key,\n        attributes: alreadyExistingEdgeData.attributes,\n        data: attributes\n      });\n    }\n\n    return info;\n  }\n\n  attributes = attributes || {};\n\n  if (asUpdater && updater) attributes = updater(attributes);\n\n  // Must the graph generate an id for this edge?\n  const eventData = {\n    key: null,\n    undirected,\n    source,\n    target,\n    attributes\n  };\n\n  if (mustGenerateKey) {\n    // NOTE: in this case we can guarantee that the key does not already\n    // exist and is already correctly casted as a string\n    edge = graph._edgeKeyGenerator();\n  } else {\n    // Coercion of edge key\n    edge = '' + edge;\n\n    // Here, we have a key collision\n    if (graph._edges.has(edge))\n      throw new UsageGraphError(\n        `Graph.${name}: the \"${edge}\" edge already exists in the graph.`\n      );\n  }\n\n  let sourceWasAdded = false;\n  let targetWasAdded = false;\n\n  if (!sourceData) {\n    sourceData = unsafeAddNode(graph, source, {});\n    sourceWasAdded = true;\n\n    if (source === target) {\n      targetData = sourceData;\n      targetWasAdded = true;\n    }\n  }\n  if (!targetData) {\n    targetData = unsafeAddNode(graph, target, {});\n    targetWasAdded = true;\n  }\n\n  // Storing some data\n  edgeData = new EdgeData(undirected, edge, sourceData, targetData, attributes);\n\n  // Adding the edge to the internal register\n  graph._edges.set(edge, edgeData);\n\n  // Incrementing node degree counters\n  const isSelfLoop = source === target;\n\n  if (undirected) {\n    sourceData.undirectedDegree++;\n    targetData.undirectedDegree++;\n\n    if (isSelfLoop) {\n      sourceData.undirectedLoops++;\n      graph._undirectedSelfLoopCount++;\n    }\n  } else {\n    sourceData.outDegree++;\n    targetData.inDegree++;\n\n    if (isSelfLoop) {\n      sourceData.directedLoops++;\n      graph._directedSelfLoopCount++;\n    }\n  }\n\n  // Updating relevant index\n  if (graph.multi) edgeData.attachMulti();\n  else edgeData.attach();\n\n  if (undirected) graph._undirectedSize++;\n  else graph._directedSize++;\n\n  // Emitting\n  eventData.key = edge;\n\n  graph.emit('edgeAdded', eventData);\n\n  return [edge, true, sourceWasAdded, targetWasAdded];\n}\n\n/**\n * Internal method used to drop an edge.\n *\n * @param  {Graph}    graph    - Target graph.\n * @param  {EdgeData} edgeData - Data of the edge to drop.\n */\nfunction dropEdgeFromData(graph, edgeData) {\n  // Dropping the edge from the register\n  graph._edges.delete(edgeData.key);\n\n  // Updating related degrees\n  const {source: sourceData, target: targetData, attributes} = edgeData;\n\n  const undirected = edgeData.undirected;\n\n  const isSelfLoop = sourceData === targetData;\n\n  if (undirected) {\n    sourceData.undirectedDegree--;\n    targetData.undirectedDegree--;\n\n    if (isSelfLoop) {\n      sourceData.undirectedLoops--;\n      graph._undirectedSelfLoopCount--;\n    }\n  } else {\n    sourceData.outDegree--;\n    targetData.inDegree--;\n\n    if (isSelfLoop) {\n      sourceData.directedLoops--;\n      graph._directedSelfLoopCount--;\n    }\n  }\n\n  // Clearing index\n  if (graph.multi) edgeData.detachMulti();\n  else edgeData.detach();\n\n  if (undirected) graph._undirectedSize--;\n  else graph._directedSize--;\n\n  // Emitting\n  graph.emit('edgeDropped', {\n    key: edgeData.key,\n    attributes,\n    source: sourceData.key,\n    target: targetData.key,\n    undirected\n  });\n}\n\n/**\n * Graph class\n *\n * @constructor\n * @param  {object}  [options] - Options:\n * @param  {boolean}   [allowSelfLoops] - Allow self loops?\n * @param  {string}    [type]           - Type of the graph.\n * @param  {boolean}   [map]            - Allow references as keys?\n * @param  {boolean}   [multi]          - Allow parallel edges?\n *\n * @throws {Error} - Will throw if the arguments are not valid.\n */\nexport default class Graph extends EventEmitter {\n  constructor(options) {\n    super();\n\n    //-- Solving options\n    options = assign({}, DEFAULTS, options);\n\n    // Enforcing options validity\n    if (typeof options.multi !== 'boolean')\n      throw new InvalidArgumentsGraphError(\n        `Graph.constructor: invalid 'multi' option. Expecting a boolean but got \"${options.multi}\".`\n      );\n\n    if (!TYPES.has(options.type))\n      throw new InvalidArgumentsGraphError(\n        `Graph.constructor: invalid 'type' option. Should be one of \"mixed\", \"directed\" or \"undirected\" but got \"${options.type}\".`\n      );\n\n    if (typeof options.allowSelfLoops !== 'boolean')\n      throw new InvalidArgumentsGraphError(\n        `Graph.constructor: invalid 'allowSelfLoops' option. Expecting a boolean but got \"${options.allowSelfLoops}\".`\n      );\n\n    //-- Private properties\n\n    // Utilities\n    const NodeDataClass =\n      options.type === 'mixed'\n        ? MixedNodeData\n        : options.type === 'directed'\n        ? DirectedNodeData\n        : UndirectedNodeData;\n\n    privateProperty(this, 'NodeDataClass', NodeDataClass);\n\n    // Internal edge key generator\n\n    // NOTE: this internal generator produce keys that are strings\n    // composed of a weird prefix, an incremental instance id starting from\n    // a random byte and finally an internal instance incremental id.\n    // All this to avoid intra-frame and cross-frame adversarial inputs\n    // that can force a single #.addEdge call to degenerate into a O(n)\n    // available key search loop.\n\n    // It also ensures that automatically generated edge keys are unlikely\n    // to produce collisions with arbitrary keys given by users.\n    const instancePrefix = 'geid_' + INSTANCE_ID() + '_';\n    let edgeId = 0;\n\n    const edgeKeyGenerator = () => {\n      let availableEdgeKey;\n\n      do {\n        availableEdgeKey = instancePrefix + edgeId++;\n      } while (this._edges.has(availableEdgeKey));\n\n      return availableEdgeKey;\n    };\n\n    // Indexes\n    privateProperty(this, '_attributes', {});\n    privateProperty(this, '_nodes', new Map());\n    privateProperty(this, '_edges', new Map());\n    privateProperty(this, '_directedSize', 0);\n    privateProperty(this, '_undirectedSize', 0);\n    privateProperty(this, '_directedSelfLoopCount', 0);\n    privateProperty(this, '_undirectedSelfLoopCount', 0);\n    privateProperty(this, '_edgeKeyGenerator', edgeKeyGenerator);\n\n    // Options\n    privateProperty(this, '_options', options);\n\n    // Emitter properties\n    EMITTER_PROPS.forEach(prop => privateProperty(this, prop, this[prop]));\n\n    //-- Properties readers\n    readOnlyProperty(this, 'order', () => this._nodes.size);\n    readOnlyProperty(this, 'size', () => this._edges.size);\n    readOnlyProperty(this, 'directedSize', () => this._directedSize);\n    readOnlyProperty(this, 'undirectedSize', () => this._undirectedSize);\n    readOnlyProperty(\n      this,\n      'selfLoopCount',\n      () => this._directedSelfLoopCount + this._undirectedSelfLoopCount\n    );\n    readOnlyProperty(\n      this,\n      'directedSelfLoopCount',\n      () => this._directedSelfLoopCount\n    );\n    readOnlyProperty(\n      this,\n      'undirectedSelfLoopCount',\n      () => this._undirectedSelfLoopCount\n    );\n    readOnlyProperty(this, 'multi', this._options.multi);\n    readOnlyProperty(this, 'type', this._options.type);\n    readOnlyProperty(this, 'allowSelfLoops', this._options.allowSelfLoops);\n    readOnlyProperty(this, 'implementation', () => 'graphology');\n  }\n\n  _resetInstanceCounters() {\n    this._directedSize = 0;\n    this._undirectedSize = 0;\n    this._directedSelfLoopCount = 0;\n    this._undirectedSelfLoopCount = 0;\n  }\n\n  /**---------------------------------------------------------------------------\n   * Read\n   **---------------------------------------------------------------------------\n   */\n\n  /**\n   * Method returning whether the given node is found in the graph.\n   *\n   * @param  {any}     node - The node.\n   * @return {boolean}\n   */\n  hasNode(node) {\n    return this._nodes.has('' + node);\n  }\n\n  /**\n   * Method returning whether the given directed edge is found in the graph.\n   *\n   * Arity 1:\n   * @param  {any}     edge - The edge's key.\n   *\n   * Arity 2:\n   * @param  {any}     source - The edge's source.\n   * @param  {any}     target - The edge's target.\n   *\n   * @return {boolean}\n   *\n   * @throws {Error} - Will throw if the arguments are invalid.\n   */\n  hasDirectedEdge(source, target) {\n    // Early termination\n    if (this.type === 'undirected') return false;\n\n    if (arguments.length === 1) {\n      const edge = '' + source;\n\n      const edgeData = this._edges.get(edge);\n\n      return !!edgeData && !edgeData.undirected;\n    } else if (arguments.length === 2) {\n      source = '' + source;\n      target = '' + target;\n\n      // If the node source or the target is not in the graph we break\n      const nodeData = this._nodes.get(source);\n\n      if (!nodeData) return false;\n\n      // Is there a directed edge pointing toward target?\n      return nodeData.out.hasOwnProperty(target);\n    }\n\n    throw new InvalidArgumentsGraphError(\n      `Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`\n    );\n  }\n\n  /**\n   * Method returning whether the given undirected edge is found in the graph.\n   *\n   * Arity 1:\n   * @param  {any}     edge - The edge's key.\n   *\n   * Arity 2:\n   * @param  {any}     source - The edge's source.\n   * @param  {any}     target - The edge's target.\n   *\n   * @return {boolean}\n   *\n   * @throws {Error} - Will throw if the arguments are invalid.\n   */\n  hasUndirectedEdge(source, target) {\n    // Early termination\n    if (this.type === 'directed') return false;\n\n    if (arguments.length === 1) {\n      const edge = '' + source;\n\n      const edgeData = this._edges.get(edge);\n\n      return !!edgeData && edgeData.undirected;\n    } else if (arguments.length === 2) {\n      source = '' + source;\n      target = '' + target;\n\n      // If the node source or the target is not in the graph we break\n      const nodeData = this._nodes.get(source);\n\n      if (!nodeData) return false;\n\n      // Is there a directed edge pointing toward target?\n      return nodeData.undirected.hasOwnProperty(target);\n    }\n\n    throw new InvalidArgumentsGraphError(\n      `Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`\n    );\n  }\n\n  /**\n   * Method returning whether the given edge is found in the graph.\n   *\n   * Arity 1:\n   * @param  {any}     edge - The edge's key.\n   *\n   * Arity 2:\n   * @param  {any}     source - The edge's source.\n   * @param  {any}     target - The edge's target.\n   *\n   * @return {boolean}\n   *\n   * @throws {Error} - Will throw if the arguments are invalid.\n   */\n  hasEdge(source, target) {\n    if (arguments.length === 1) {\n      const edge = '' + source;\n\n      return this._edges.has(edge);\n    } else if (arguments.length === 2) {\n      source = '' + source;\n      target = '' + target;\n\n      // If the node source or the target is not in the graph we break\n      const nodeData = this._nodes.get(source);\n\n      if (!nodeData) return false;\n\n      // Is there a directed edge pointing toward target?\n      return (\n        (typeof nodeData.out !== 'undefined' &&\n          nodeData.out.hasOwnProperty(target)) ||\n        (typeof nodeData.undirected !== 'undefined' &&\n          nodeData.undirected.hasOwnProperty(target))\n      );\n    }\n\n    throw new InvalidArgumentsGraphError(\n      `Graph.hasEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`\n    );\n  }\n\n  /**\n   * Method returning the edge matching source & target in a directed fashion.\n   *\n   * @param  {any} source - The edge's source.\n   * @param  {any} target - The edge's target.\n   *\n   * @return {any|undefined}\n   *\n   * @throws {Error} - Will throw if the graph is multi.\n   * @throws {Error} - Will throw if source or target doesn't exist.\n   */\n  directedEdge(source, target) {\n    if (this.type === 'undirected') return;\n\n    source = '' + source;\n    target = '' + target;\n\n    if (this.multi)\n      throw new UsageGraphError(\n        'Graph.directedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.directedEdges instead.'\n      );\n\n    const sourceData = this._nodes.get(source);\n\n    if (!sourceData)\n      throw new NotFoundGraphError(\n        `Graph.directedEdge: could not find the \"${source}\" source node in the graph.`\n      );\n\n    if (!this._nodes.has(target))\n      throw new NotFoundGraphError(\n        `Graph.directedEdge: could not find the \"${target}\" target node in the graph.`\n      );\n\n    const edgeData = (sourceData.out && sourceData.out[target]) || undefined;\n\n    if (edgeData) return edgeData.key;\n  }\n\n  /**\n   * Method returning the edge matching source & target in a undirected fashion.\n   *\n   * @param  {any} source - The edge's source.\n   * @param  {any} target - The edge's target.\n   *\n   * @return {any|undefined}\n   *\n   * @throws {Error} - Will throw if the graph is multi.\n   * @throws {Error} - Will throw if source or target doesn't exist.\n   */\n  undirectedEdge(source, target) {\n    if (this.type === 'directed') return;\n\n    source = '' + source;\n    target = '' + target;\n\n    if (this.multi)\n      throw new UsageGraphError(\n        'Graph.undirectedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.undirectedEdges instead.'\n      );\n\n    const sourceData = this._nodes.get(source);\n\n    if (!sourceData)\n      throw new NotFoundGraphError(\n        `Graph.undirectedEdge: could not find the \"${source}\" source node in the graph.`\n      );\n\n    if (!this._nodes.has(target))\n      throw new NotFoundGraphError(\n        `Graph.undirectedEdge: could not find the \"${target}\" target node in the graph.`\n      );\n\n    const edgeData =\n      (sourceData.undirected && sourceData.undirected[target]) || undefined;\n\n    if (edgeData) return edgeData.key;\n  }\n\n  /**\n   * Method returning the edge matching source & target in a mixed fashion.\n   *\n   * @param  {any} source - The edge's source.\n   * @param  {any} target - The edge's target.\n   *\n   * @return {any|undefined}\n   *\n   * @throws {Error} - Will throw if the graph is multi.\n   * @throws {Error} - Will throw if source or target doesn't exist.\n   */\n  edge(source, target) {\n    if (this.multi)\n      throw new UsageGraphError(\n        'Graph.edge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.edges instead.'\n      );\n\n    source = '' + source;\n    target = '' + target;\n\n    const sourceData = this._nodes.get(source);\n\n    if (!sourceData)\n      throw new NotFoundGraphError(\n        `Graph.edge: could not find the \"${source}\" source node in the graph.`\n      );\n\n    if (!this._nodes.has(target))\n      throw new NotFoundGraphError(\n        `Graph.edge: could not find the \"${target}\" target node in the graph.`\n      );\n\n    const edgeData =\n      (sourceData.out && sourceData.out[target]) ||\n      (sourceData.undirected && sourceData.undirected[target]) ||\n      undefined;\n\n    if (edgeData) return edgeData.key;\n  }\n\n  /**\n   * Method returning whether two nodes are directed neighbors.\n   *\n   * @param  {any}     node     - The node's key.\n   * @param  {any}     neighbor - The neighbor's key.\n   * @return {boolean}\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  areDirectedNeighbors(node, neighbor) {\n    node = '' + node;\n    neighbor = '' + neighbor;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.areDirectedNeighbors: could not find the \"${node}\" node in the graph.`\n      );\n\n    if (this.type === 'undirected') return false;\n\n    return neighbor in nodeData.in || neighbor in nodeData.out;\n  }\n\n  /**\n   * Method returning whether two nodes are out neighbors.\n   *\n   * @param  {any}     node     - The node's key.\n   * @param  {any}     neighbor - The neighbor's key.\n   * @return {boolean}\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  areOutNeighbors(node, neighbor) {\n    node = '' + node;\n    neighbor = '' + neighbor;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.areOutNeighbors: could not find the \"${node}\" node in the graph.`\n      );\n\n    if (this.type === 'undirected') return false;\n\n    return neighbor in nodeData.out;\n  }\n\n  /**\n   * Method returning whether two nodes are in neighbors.\n   *\n   * @param  {any}     node     - The node's key.\n   * @param  {any}     neighbor - The neighbor's key.\n   * @return {boolean}\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  areInNeighbors(node, neighbor) {\n    node = '' + node;\n    neighbor = '' + neighbor;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.areInNeighbors: could not find the \"${node}\" node in the graph.`\n      );\n\n    if (this.type === 'undirected') return false;\n\n    return neighbor in nodeData.in;\n  }\n\n  /**\n   * Method returning whether two nodes are undirected neighbors.\n   *\n   * @param  {any}     node     - The node's key.\n   * @param  {any}     neighbor - The neighbor's key.\n   * @return {boolean}\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  areUndirectedNeighbors(node, neighbor) {\n    node = '' + node;\n    neighbor = '' + neighbor;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.areUndirectedNeighbors: could not find the \"${node}\" node in the graph.`\n      );\n\n    if (this.type === 'directed') return false;\n\n    return neighbor in nodeData.undirected;\n  }\n\n  /**\n   * Method returning whether two nodes are neighbors.\n   *\n   * @param  {any}     node     - The node's key.\n   * @param  {any}     neighbor - The neighbor's key.\n   * @return {boolean}\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  areNeighbors(node, neighbor) {\n    node = '' + node;\n    neighbor = '' + neighbor;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.areNeighbors: could not find the \"${node}\" node in the graph.`\n      );\n\n    if (this.type !== 'undirected') {\n      if (neighbor in nodeData.in || neighbor in nodeData.out) return true;\n    }\n\n    if (this.type !== 'directed') {\n      if (neighbor in nodeData.undirected) return true;\n    }\n\n    return false;\n  }\n\n  /**\n   * Method returning whether two nodes are inbound neighbors.\n   *\n   * @param  {any}     node     - The node's key.\n   * @param  {any}     neighbor - The neighbor's key.\n   * @return {boolean}\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  areInboundNeighbors(node, neighbor) {\n    node = '' + node;\n    neighbor = '' + neighbor;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.areInboundNeighbors: could not find the \"${node}\" node in the graph.`\n      );\n\n    if (this.type !== 'undirected') {\n      if (neighbor in nodeData.in) return true;\n    }\n\n    if (this.type !== 'directed') {\n      if (neighbor in nodeData.undirected) return true;\n    }\n\n    return false;\n  }\n\n  /**\n   * Method returning whether two nodes are outbound neighbors.\n   *\n   * @param  {any}     node     - The node's key.\n   * @param  {any}     neighbor - The neighbor's key.\n   * @return {boolean}\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  areOutboundNeighbors(node, neighbor) {\n    node = '' + node;\n    neighbor = '' + neighbor;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.areOutboundNeighbors: could not find the \"${node}\" node in the graph.`\n      );\n\n    if (this.type !== 'undirected') {\n      if (neighbor in nodeData.out) return true;\n    }\n\n    if (this.type !== 'directed') {\n      if (neighbor in nodeData.undirected) return true;\n    }\n\n    return false;\n  }\n\n  /**\n   * Method returning the given node's in degree.\n   *\n   * @param  {any}     node - The node's key.\n   * @return {number}       - The node's in degree.\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  inDegree(node) {\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.inDegree: could not find the \"${node}\" node in the graph.`\n      );\n\n    if (this.type === 'undirected') return 0;\n\n    return nodeData.inDegree;\n  }\n\n  /**\n   * Method returning the given node's out degree.\n   *\n   * @param  {any}     node - The node's key.\n   * @return {number}       - The node's in degree.\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  outDegree(node) {\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.outDegree: could not find the \"${node}\" node in the graph.`\n      );\n\n    if (this.type === 'undirected') return 0;\n\n    return nodeData.outDegree;\n  }\n\n  /**\n   * Method returning the given node's directed degree.\n   *\n   * @param  {any}     node - The node's key.\n   * @return {number}       - The node's in degree.\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  directedDegree(node) {\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.directedDegree: could not find the \"${node}\" node in the graph.`\n      );\n\n    if (this.type === 'undirected') return 0;\n\n    return nodeData.inDegree + nodeData.outDegree;\n  }\n\n  /**\n   * Method returning the given node's undirected degree.\n   *\n   * @param  {any}     node - The node's key.\n   * @return {number}       - The node's in degree.\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  undirectedDegree(node) {\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.undirectedDegree: could not find the \"${node}\" node in the graph.`\n      );\n\n    if (this.type === 'directed') return 0;\n\n    return nodeData.undirectedDegree;\n  }\n\n  /**\n   * Method returning the given node's inbound degree.\n   *\n   * @param  {any}     node - The node's key.\n   * @return {number}       - The node's inbound degree.\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  inboundDegree(node) {\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.inboundDegree: could not find the \"${node}\" node in the graph.`\n      );\n\n    let degree = 0;\n\n    if (this.type !== 'directed') {\n      degree += nodeData.undirectedDegree;\n    }\n\n    if (this.type !== 'undirected') {\n      degree += nodeData.inDegree;\n    }\n\n    return degree;\n  }\n\n  /**\n   * Method returning the given node's outbound degree.\n   *\n   * @param  {any}     node - The node's key.\n   * @return {number}       - The node's outbound degree.\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  outboundDegree(node) {\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.outboundDegree: could not find the \"${node}\" node in the graph.`\n      );\n\n    let degree = 0;\n\n    if (this.type !== 'directed') {\n      degree += nodeData.undirectedDegree;\n    }\n\n    if (this.type !== 'undirected') {\n      degree += nodeData.outDegree;\n    }\n\n    return degree;\n  }\n\n  /**\n   * Method returning the given node's directed degree.\n   *\n   * @param  {any}     node - The node's key.\n   * @return {number}       - The node's degree.\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  degree(node) {\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.degree: could not find the \"${node}\" node in the graph.`\n      );\n\n    let degree = 0;\n\n    if (this.type !== 'directed') {\n      degree += nodeData.undirectedDegree;\n    }\n\n    if (this.type !== 'undirected') {\n      degree += nodeData.inDegree + nodeData.outDegree;\n    }\n\n    return degree;\n  }\n\n  /**\n   * Method returning the given node's in degree without considering self loops.\n   *\n   * @param  {any}     node - The node's key.\n   * @return {number}       - The node's in degree.\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  inDegreeWithoutSelfLoops(node) {\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.inDegreeWithoutSelfLoops: could not find the \"${node}\" node in the graph.`\n      );\n\n    if (this.type === 'undirected') return 0;\n\n    return nodeData.inDegree - nodeData.directedLoops;\n  }\n\n  /**\n   * Method returning the given node's out degree without considering self loops.\n   *\n   * @param  {any}     node - The node's key.\n   * @return {number}       - The node's in degree.\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  outDegreeWithoutSelfLoops(node) {\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.outDegreeWithoutSelfLoops: could not find the \"${node}\" node in the graph.`\n      );\n\n    if (this.type === 'undirected') return 0;\n\n    return nodeData.outDegree - nodeData.directedLoops;\n  }\n\n  /**\n   * Method returning the given node's directed degree without considering self loops.\n   *\n   * @param  {any}     node - The node's key.\n   * @return {number}       - The node's in degree.\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  directedDegreeWithoutSelfLoops(node) {\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.directedDegreeWithoutSelfLoops: could not find the \"${node}\" node in the graph.`\n      );\n\n    if (this.type === 'undirected') return 0;\n\n    return nodeData.inDegree + nodeData.outDegree - nodeData.directedLoops * 2;\n  }\n\n  /**\n   * Method returning the given node's undirected degree without considering self loops.\n   *\n   * @param  {any}     node - The node's key.\n   * @return {number}       - The node's in degree.\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  undirectedDegreeWithoutSelfLoops(node) {\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.undirectedDegreeWithoutSelfLoops: could not find the \"${node}\" node in the graph.`\n      );\n\n    if (this.type === 'directed') return 0;\n\n    return nodeData.undirectedDegree - nodeData.undirectedLoops * 2;\n  }\n\n  /**\n   * Method returning the given node's inbound degree without considering self loops.\n   *\n   * @param  {any}     node - The node's key.\n   * @return {number}       - The node's inbound degree.\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  inboundDegreeWithoutSelfLoops(node) {\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.inboundDegreeWithoutSelfLoops: could not find the \"${node}\" node in the graph.`\n      );\n\n    let degree = 0;\n    let loops = 0;\n\n    if (this.type !== 'directed') {\n      degree += nodeData.undirectedDegree;\n      loops += nodeData.undirectedLoops * 2;\n    }\n\n    if (this.type !== 'undirected') {\n      degree += nodeData.inDegree;\n      loops += nodeData.directedLoops;\n    }\n\n    return degree - loops;\n  }\n\n  /**\n   * Method returning the given node's outbound degree without considering self loops.\n   *\n   * @param  {any}     node - The node's key.\n   * @return {number}       - The node's outbound degree.\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  outboundDegreeWithoutSelfLoops(node) {\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.outboundDegreeWithoutSelfLoops: could not find the \"${node}\" node in the graph.`\n      );\n\n    let degree = 0;\n    let loops = 0;\n\n    if (this.type !== 'directed') {\n      degree += nodeData.undirectedDegree;\n      loops += nodeData.undirectedLoops * 2;\n    }\n\n    if (this.type !== 'undirected') {\n      degree += nodeData.outDegree;\n      loops += nodeData.directedLoops;\n    }\n\n    return degree - loops;\n  }\n\n  /**\n   * Method returning the given node's directed degree without considering self loops.\n   *\n   * @param  {any}     node - The node's key.\n   * @return {number}       - The node's degree.\n   *\n   * @throws {Error} - Will throw if the node isn't in the graph.\n   */\n  degreeWithoutSelfLoops(node) {\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.degreeWithoutSelfLoops: could not find the \"${node}\" node in the graph.`\n      );\n\n    let degree = 0;\n    let loops = 0;\n\n    if (this.type !== 'directed') {\n      degree += nodeData.undirectedDegree;\n      loops += nodeData.undirectedLoops * 2;\n    }\n\n    if (this.type !== 'undirected') {\n      degree += nodeData.inDegree + nodeData.outDegree;\n      loops += nodeData.directedLoops * 2;\n    }\n\n    return degree - loops;\n  }\n\n  /**\n   * Method returning the given edge's source.\n   *\n   * @param  {any} edge - The edge's key.\n   * @return {any}      - The edge's source.\n   *\n   * @throws {Error} - Will throw if the edge isn't in the graph.\n   */\n  source(edge) {\n    edge = '' + edge;\n\n    const data = this._edges.get(edge);\n\n    if (!data)\n      throw new NotFoundGraphError(\n        `Graph.source: could not find the \"${edge}\" edge in the graph.`\n      );\n\n    return data.source.key;\n  }\n\n  /**\n   * Method returning the given edge's target.\n   *\n   * @param  {any} edge - The edge's key.\n   * @return {any}      - The edge's target.\n   *\n   * @throws {Error} - Will throw if the edge isn't in the graph.\n   */\n  target(edge) {\n    edge = '' + edge;\n\n    const data = this._edges.get(edge);\n\n    if (!data)\n      throw new NotFoundGraphError(\n        `Graph.target: could not find the \"${edge}\" edge in the graph.`\n      );\n\n    return data.target.key;\n  }\n\n  /**\n   * Method returning the given edge's extremities.\n   *\n   * @param  {any}   edge - The edge's key.\n   * @return {array}      - The edge's extremities.\n   *\n   * @throws {Error} - Will throw if the edge isn't in the graph.\n   */\n  extremities(edge) {\n    edge = '' + edge;\n\n    const edgeData = this._edges.get(edge);\n\n    if (!edgeData)\n      throw new NotFoundGraphError(\n        `Graph.extremities: could not find the \"${edge}\" edge in the graph.`\n      );\n\n    return [edgeData.source.key, edgeData.target.key];\n  }\n\n  /**\n   * Given a node & an edge, returns the other extremity of the edge.\n   *\n   * @param  {any}   node - The node's key.\n   * @param  {any}   edge - The edge's key.\n   * @return {any}        - The related node.\n   *\n   * @throws {Error} - Will throw if the edge isn't in the graph or if the\n   *                   edge & node are not related.\n   */\n  opposite(node, edge) {\n    node = '' + node;\n    edge = '' + edge;\n\n    const data = this._edges.get(edge);\n\n    if (!data)\n      throw new NotFoundGraphError(\n        `Graph.opposite: could not find the \"${edge}\" edge in the graph.`\n      );\n\n    const source = data.source.key;\n    const target = data.target.key;\n\n    if (node === source) return target;\n    if (node === target) return source;\n\n    throw new NotFoundGraphError(\n      `Graph.opposite: the \"${node}\" node is not attached to the \"${edge}\" edge (${source}, ${target}).`\n    );\n  }\n\n  /**\n   * Returns whether the given edge has the given node as extremity.\n   *\n   * @param  {any}     edge - The edge's key.\n   * @param  {any}     node - The node's key.\n   * @return {boolean}      - The related node.\n   *\n   * @throws {Error} - Will throw if either the node or the edge isn't in the graph.\n   */\n  hasExtremity(edge, node) {\n    edge = '' + edge;\n    node = '' + node;\n\n    const data = this._edges.get(edge);\n\n    if (!data)\n      throw new NotFoundGraphError(\n        `Graph.hasExtremity: could not find the \"${edge}\" edge in the graph.`\n      );\n\n    return data.source.key === node || data.target.key === node;\n  }\n\n  /**\n   * Method returning whether the given edge is undirected.\n   *\n   * @param  {any}     edge - The edge's key.\n   * @return {boolean}\n   *\n   * @throws {Error} - Will throw if the edge isn't in the graph.\n   */\n  isUndirected(edge) {\n    edge = '' + edge;\n\n    const data = this._edges.get(edge);\n\n    if (!data)\n      throw new NotFoundGraphError(\n        `Graph.isUndirected: could not find the \"${edge}\" edge in the graph.`\n      );\n\n    return data.undirected;\n  }\n\n  /**\n   * Method returning whether the given edge is directed.\n   *\n   * @param  {any}     edge - The edge's key.\n   * @return {boolean}\n   *\n   * @throws {Error} - Will throw if the edge isn't in the graph.\n   */\n  isDirected(edge) {\n    edge = '' + edge;\n\n    const data = this._edges.get(edge);\n\n    if (!data)\n      throw new NotFoundGraphError(\n        `Graph.isDirected: could not find the \"${edge}\" edge in the graph.`\n      );\n\n    return !data.undirected;\n  }\n\n  /**\n   * Method returning whether the given edge is a self loop.\n   *\n   * @param  {any}     edge - The edge's key.\n   * @return {boolean}\n   *\n   * @throws {Error} - Will throw if the edge isn't in the graph.\n   */\n  isSelfLoop(edge) {\n    edge = '' + edge;\n\n    const data = this._edges.get(edge);\n\n    if (!data)\n      throw new NotFoundGraphError(\n        `Graph.isSelfLoop: could not find the \"${edge}\" edge in the graph.`\n      );\n\n    return data.source === data.target;\n  }\n\n  /**---------------------------------------------------------------------------\n   * Mutation\n   **---------------------------------------------------------------------------\n   */\n\n  /**\n   * Method used to add a node to the graph.\n   *\n   * @param  {any}    node         - The node.\n   * @param  {object} [attributes] - Optional attributes.\n   * @return {any}                 - The node.\n   *\n   * @throws {Error} - Will throw if the given node already exist.\n   * @throws {Error} - Will throw if the given attributes are not an object.\n   */\n  addNode(node, attributes) {\n    const nodeData = addNode(this, node, attributes);\n\n    return nodeData.key;\n  }\n\n  /**\n   * Method used to merge a node into the graph.\n   *\n   * @param  {any}    node         - The node.\n   * @param  {object} [attributes] - Optional attributes.\n   * @return {any}                 - The node.\n   */\n  mergeNode(node, attributes) {\n    if (attributes && !isPlainObject(attributes))\n      throw new InvalidArgumentsGraphError(\n        `Graph.mergeNode: invalid attributes. Expecting an object but got \"${attributes}\"`\n      );\n\n    // String coercion\n    node = '' + node;\n    attributes = attributes || {};\n\n    // If the node already exists, we merge the attributes\n    let data = this._nodes.get(node);\n\n    if (data) {\n      if (attributes) {\n        assign(data.attributes, attributes);\n\n        this.emit('nodeAttributesUpdated', {\n          type: 'merge',\n          key: node,\n          attributes: data.attributes,\n          data: attributes\n        });\n      }\n      return [node, false];\n    }\n\n    data = new this.NodeDataClass(node, attributes);\n\n    // Adding the node to internal register\n    this._nodes.set(node, data);\n\n    // Emitting\n    this.emit('nodeAdded', {\n      key: node,\n      attributes\n    });\n\n    return [node, true];\n  }\n\n  /**\n   * Method used to add a node if it does not exist in the graph or else to\n   * update its attributes using a function.\n   *\n   * @param  {any}      node      - The node.\n   * @param  {function} [updater] - Optional updater function.\n   * @return {any}                - The node.\n   */\n  updateNode(node, updater) {\n    if (updater && typeof updater !== 'function')\n      throw new InvalidArgumentsGraphError(\n        `Graph.updateNode: invalid updater function. Expecting a function but got \"${updater}\"`\n      );\n\n    // String coercion\n    node = '' + node;\n\n    // If the node already exists, we update the attributes\n    let data = this._nodes.get(node);\n\n    if (data) {\n      if (updater) {\n        const oldAttributes = data.attributes;\n        data.attributes = updater(oldAttributes);\n\n        this.emit('nodeAttributesUpdated', {\n          type: 'replace',\n          key: node,\n          attributes: data.attributes\n        });\n      }\n      return [node, false];\n    }\n\n    const attributes = updater ? updater({}) : {};\n\n    data = new this.NodeDataClass(node, attributes);\n\n    // Adding the node to internal register\n    this._nodes.set(node, data);\n\n    // Emitting\n    this.emit('nodeAdded', {\n      key: node,\n      attributes\n    });\n\n    return [node, true];\n  }\n\n  /**\n   * Method used to drop a single node & all its attached edges from the graph.\n   *\n   * @param  {any}    node - The node.\n   * @return {Graph}\n   *\n   * @throws {Error} - Will throw if the node doesn't exist.\n   */\n  dropNode(node) {\n    node = '' + node;\n\n    const nodeData = this._nodes.get(node);\n\n    if (!nodeData)\n      throw new NotFoundGraphError(\n        `Graph.dropNode: could not find the \"${node}\" node in the graph.`\n      );\n\n    let edgeData;\n\n    // Removing attached edges\n    // NOTE: we could be faster here, but this is such a pain to maintain\n    if (this.type !== 'undirected') {\n      for (const neighbor in nodeData.out) {\n        edgeData = nodeData.out[neighbor];\n\n        do {\n          dropEdgeFromData(this, edgeData);\n          edgeData = edgeData.next;\n        } while (edgeData);\n      }\n\n      for (const neighbor in nodeData.in) {\n        edgeData = nodeData.in[neighbor];\n\n        do {\n          dropEdgeFromData(this, edgeData);\n          edgeData = edgeData.next;\n        } while (edgeData);\n      }\n    }\n\n    if (this.type !== 'directed') {\n      for (const neighbor in nodeData.undirected) {\n        edgeData = nodeData.undirected[neighbor];\n\n        do {\n          dropEdgeFromData(this, edgeData);\n          edgeData = edgeData.next;\n        } while (edgeData);\n      }\n    }\n\n    // Dropping the node from the register\n    this._nodes.delete(node);\n\n    // Emitting\n    this.emit('nodeDropped', {\n      key: node,\n      attributes: nodeData.attributes\n    });\n  }\n\n  /**\n   * Method used to drop a single edge from the graph.\n   *\n   * Arity 1:\n   * @param  {any}    edge - The edge.\n   *\n   * Arity 2:\n   * @param  {any}    source - Source node.\n   * @param  {any}    target - Target node.\n   *\n   * @return {Graph}\n   *\n   * @throws {Error} - Will throw if the edge doesn't exist.\n   */\n  dropEdge(edge) {\n    let edgeData;\n\n    if (arguments.length > 1) {\n      const source = '' + arguments[0];\n      const target = '' + arguments[1];\n\n      edgeData = getMatchingEdge(this, source, target, this.type);\n\n      if (!edgeData)\n        throw new NotFoundGraphError(\n          `Graph.dropEdge: could not find the \"${source}\" -> \"${target}\" edge in the graph.`\n        );\n    } else {\n      edge = '' + edge;\n\n      edgeData = this._edges.get(edge);\n\n      if (!edgeData)\n        throw new NotFoundGraphError(\n          `Graph.dropEdge: could not find the \"${edge}\" edge in the graph.`\n        );\n    }\n\n    dropEdgeFromData(this, edgeData);\n\n    return this;\n  }\n\n  /**\n   * Method used to drop a single directed edge from the graph.\n   *\n   * @param  {any}    source - Source node.\n   * @param  {any}    target - Target node.\n   *\n   * @return {Graph}\n   *\n   * @throws {Error} - Will throw if the edge doesn't exist.\n   */\n  dropDirectedEdge(source, target) {\n    if (arguments.length < 2)\n      throw new UsageGraphError(\n        'Graph.dropDirectedEdge: it does not make sense to try and drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.'\n      );\n\n    if (this.multi)\n      throw new UsageGraphError(\n        'Graph.dropDirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.'\n      );\n\n    source = '' + source;\n    target = '' + target;\n\n    const edgeData = getMatchingEdge(this, source, target, 'directed');\n\n    if (!edgeData)\n      throw new NotFoundGraphError(\n        `Graph.dropDirectedEdge: could not find a \"${source}\" -> \"${target}\" edge in the graph.`\n      );\n\n    dropEdgeFromData(this, edgeData);\n\n    return this;\n  }\n\n  /**\n   * Method used to drop a single undirected edge from the graph.\n   *\n   * @param  {any}    source - Source node.\n   * @param  {any}    target - Target node.\n   *\n   * @return {Graph}\n   *\n   * @throws {Error} - Will throw if the edge doesn't exist.\n   */\n  dropUndirectedEdge(source, target) {\n    if (arguments.length < 2)\n      throw new UsageGraphError(\n        'Graph.dropUndirectedEdge: it does not make sense to drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.'\n      );\n\n    if (this.multi)\n      throw new UsageGraphError(\n        'Graph.dropUndirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.'\n      );\n\n    const edgeData = getMatchingEdge(this, source, target, 'undirected');\n\n    if (!edgeData)\n      throw new NotFoundGraphError(\n        `Graph.dropUndirectedEdge: could not find a \"${source}\" -> \"${target}\" edge in the graph.`\n      );\n\n    dropEdgeFromData(this, edgeData);\n\n    return this;\n  }\n\n  /**\n   * Method used to remove every edge & every node from the graph.\n   *\n   * @return {Graph}\n   */\n  clear() {\n    // Clearing edges\n    this._edges.clear();\n\n    // Clearing nodes\n    this._nodes.clear();\n\n    // Reset counters\n    this._resetInstanceCounters();\n\n    // Emitting\n    this.emit('cleared');\n  }\n\n  /**\n   * Method used to remove every edge from the graph.\n   *\n   * @return {Graph}\n   */\n  clearEdges() {\n    // Clearing structure index\n    const iterator = this._nodes.values();\n\n    let step;\n\n    while (((step = iterator.next()), step.done !== true)) {\n      step.value.clear();\n    }\n\n    // Clearing edges\n    this._edges.clear();\n\n    // Reset counters\n    this._resetInstanceCounters();\n\n    // Emitting\n    this.emit('edgesCleared');\n  }\n\n  /**---------------------------------------------------------------------------\n   * Attributes-related methods\n   **---------------------------------------------------------------------------\n   */\n\n  /**\n   * Method returning the desired graph's attribute.\n   *\n   * @param  {string} name - Name of the attribute.\n   * @return {any}\n   */\n  getAttribute(name) {\n    return this._attributes[name];\n  }\n\n  /**\n   * Method returning the graph's attributes.\n   *\n   * @return {object}\n   */\n  getAttributes() {\n    return this._attributes;\n  }\n\n  /**\n   * Method returning whether the graph has the desired attribute.\n   *\n   * @param  {string}  name - Name of the attribute.\n   * @return {boolean}\n   */\n  hasAttribute(name) {\n    return this._attributes.hasOwnProperty(name);\n  }\n\n  /**\n   * Method setting a value for the desired graph's attribute.\n   *\n   * @param  {string}  name  - Name of the attribute.\n   * @param  {any}     value - Value for the attribute.\n   * @return {Graph}\n   */\n  setAttribute(name, value) {\n    this._attributes[name] = value;\n\n    // Emitting\n    this.emit('attributesUpdated', {\n      type: 'set',\n      attributes: this._attributes,\n      name\n    });\n\n    return this;\n  }\n\n  /**\n   * Method using a function to update the desired graph's attribute's value.\n   *\n   * @param  {string}   name    - Name of the attribute.\n   * @param  {function} updater - Function use to update the attribute's value.\n   * @return {Graph}\n   */\n  updateAttribute(name, updater) {\n    if (typeof updater !== 'function')\n      throw new InvalidArgumentsGraphError(\n        'Graph.updateAttribute: updater should be a function.'\n      );\n\n    const value = this._attributes[name];\n\n    this._attributes[name] = updater(value);\n\n    // Emitting\n    this.emit('attributesUpdated', {\n      type: 'set',\n      attributes: this._attributes,\n      name\n    });\n\n    return this;\n  }\n\n  /**\n   * Method removing the desired graph's attribute.\n   *\n   * @param  {string} name  - Name of the attribute.\n   * @return {Graph}\n   */\n  removeAttribute(name) {\n    delete this._attributes[name];\n\n    // Emitting\n    this.emit('attributesUpdated', {\n      type: 'remove',\n      attributes: this._attributes,\n      name\n    });\n\n    return this;\n  }\n\n  /**\n   * Method replacing the graph's attributes.\n   *\n   * @param  {object} attributes - New attributes.\n   * @return {Graph}\n   *\n   * @throws {Error} - Will throw if given attributes are not a plain object.\n   */\n  replaceAttributes(attributes) {\n    if (!isPlainObject(attributes))\n      throw new InvalidArgumentsGraphError(\n        'Graph.replaceAttributes: provided attributes are not a plain object.'\n      );\n\n    this._attributes = attributes;\n\n    // Emitting\n    this.emit('attributesUpdated', {\n      type: 'replace',\n      attributes: this._attributes\n    });\n\n    return this;\n  }\n\n  /**\n   * Method merging the graph's attributes.\n   *\n   * @param  {object} attributes - Attributes to merge.\n   * @return {Graph}\n   *\n   * @throws {Error} - Will throw if given attributes are not a plain object.\n   */\n  mergeAttributes(attributes) {\n    if (!isPlainObject(attributes))\n      throw new InvalidArgumentsGraphError(\n        'Graph.mergeAttributes: provided attributes are not a plain object.'\n      );\n\n    assign(this._attributes, attributes);\n\n    // Emitting\n    this.emit('attributesUpdated', {\n      type: 'merge',\n      attributes: this._attributes,\n      data: attributes\n    });\n\n    return this;\n  }\n\n  /**\n   * Method updating the graph's attributes.\n   *\n   * @param  {function} updater - Function used to update the attributes.\n   * @return {Graph}\n   *\n   * @throws {Error} - Will throw if given updater is not a function.\n   */\n  updateAttributes(updater) {\n    if (typeof updater !== 'function')\n      throw new InvalidArgumentsGraphError(\n        'Graph.updateAttributes: provided updater is not a function.'\n      );\n\n    this._attributes = updater(this._attributes);\n\n    // Emitting\n    this.emit('attributesUpdated', {\n      type: 'update',\n      attributes: this._attributes\n    });\n\n    return this;\n  }\n\n  /**\n   * Method used to update each node's attributes using the given function.\n   *\n   * @param {function}  updater - Updater function to use.\n   * @param {object}    [hints] - Optional hints.\n   */\n  updateEachNodeAttributes(updater, hints) {\n    if (typeof updater !== 'function')\n      throw new InvalidArgumentsGraphError(\n        'Graph.updateEachNodeAttributes: expecting an updater function.'\n      );\n\n    if (hints && !validateHints(hints))\n      throw new InvalidArgumentsGraphError(\n        'Graph.updateEachNodeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}'\n      );\n\n    const iterator = this._nodes.values();\n\n    let step, nodeData;\n\n    while (((step = iterator.next()), step.done !== true)) {\n      nodeData = step.value;\n      nodeData.attributes = updater(nodeData.key, nodeData.attributes);\n    }\n\n    this.emit('eachNodeAttributesUpdated', {\n      hints: hints ? hints : null\n    });\n  }\n\n  /**\n   * Method used to update each edge's attributes using the given function.\n   *\n   * @param {function}  updater - Updater function to use.\n   * @param {object}    [hints] - Optional hints.\n   */\n  updateEachEdgeAttributes(updater, hints) {\n    if (typeof updater !== 'function')\n      throw new InvalidArgumentsGraphError(\n        'Graph.updateEachEdgeAttributes: expecting an updater function.'\n      );\n\n    if (hints && !validateHints(hints))\n      throw new InvalidArgumentsGraphError(\n        'Graph.updateEachEdgeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}'\n      );\n\n    const iterator = this._edges.values();\n\n    let step, edgeData, sourceData, targetData;\n\n    while (((step = iterator.next()), step.done !== true)) {\n      edgeData = step.value;\n      sourceData = edgeData.source;\n      targetData = edgeData.target;\n\n      edgeData.attributes = updater(\n        edgeData.key,\n        edgeData.attributes,\n        sourceData.key,\n        targetData.key,\n        sourceData.attributes,\n        targetData.attributes,\n        edgeData.undirected\n      );\n    }\n\n    this.emit('eachEdgeAttributesUpdated', {\n      hints: hints ? hints : null\n    });\n  }\n\n  /**---------------------------------------------------------------------------\n   * Iteration-related methods\n   **---------------------------------------------------------------------------\n   */\n\n  /**\n   * Method iterating over the graph's adjacency using the given callback.\n   *\n   * @param  {function}  callback - Callback to use.\n   */\n  forEachAdjacencyEntry(callback) {\n    if (typeof callback !== 'function')\n      throw new InvalidArgumentsGraphError(\n        'Graph.forEachAdjacencyEntry: expecting a callback.'\n      );\n\n    forEachAdjacency(false, false, false, this, callback);\n  }\n  forEachAdjacencyEntryWithOrphans(callback) {\n    if (typeof callback !== 'function')\n      throw new InvalidArgumentsGraphError(\n        'Graph.forEachAdjacencyEntryWithOrphans: expecting a callback.'\n      );\n\n    forEachAdjacency(false, false, true, this, callback);\n  }\n\n  /**\n   * Method iterating over the graph's assymetric adjacency using the given callback.\n   *\n   * @param  {function}  callback - Callback to use.\n   */\n  forEachAssymetricAdjacencyEntry(callback) {\n    if (typeof callback !== 'function')\n      throw new InvalidArgumentsGraphError(\n        'Graph.forEachAssymetricAdjacencyEntry: expecting a callback.'\n      );\n\n    forEachAdjacency(false, true, false, this, callback);\n  }\n  forEachAssymetricAdjacencyEntryWithOrphans(callback) {\n    if (typeof callback !== 'function')\n      throw new InvalidArgumentsGraphError(\n        'Graph.forEachAssymetricAdjacencyEntryWithOrphans: expecting a callback.'\n      );\n\n    forEachAdjacency(false, true, true, this, callback);\n  }\n\n  /**\n   * Method returning the list of the graph's nodes.\n   *\n   * @return {array} - The nodes.\n   */\n  nodes() {\n    if (typeof Array.from === 'function') return Array.from(this._nodes.keys());\n\n    return take(this._nodes.keys(), this._nodes.size);\n  }\n\n  /**\n   * Method iterating over the graph's nodes using the given callback.\n   *\n   * @param  {function}  callback - Callback (key, attributes, index).\n   */\n  forEachNode(callback) {\n    if (typeof callback !== 'function')\n      throw new InvalidArgumentsGraphError(\n        'Graph.forEachNode: expecting a callback.'\n      );\n\n    const iterator = this._nodes.values();\n\n    let step, nodeData;\n\n    while (((step = iterator.next()), step.done !== true)) {\n      nodeData = step.value;\n      callback(nodeData.key, nodeData.attributes);\n    }\n  }\n\n  /**\n   * Method iterating attempting to find a node matching the given predicate\n   * function.\n   *\n   * @param  {function}  callback - Callback (key, attributes).\n   */\n  findNode(callback) {\n    if (typeof callback !== 'function')\n      throw new InvalidArgumentsGraphError(\n        'Graph.findNode: expecting a callback.'\n      );\n\n    const iterator = this._nodes.values();\n\n    let step, nodeData;\n\n    while (((step = iterator.next()), step.done !== true)) {\n      nodeData = step.value;\n\n      if (callback(nodeData.key, nodeData.attributes)) return nodeData.key;\n    }\n\n    return;\n  }\n\n  /**\n   * Method mapping nodes.\n   *\n   * @param  {function}  callback - Callback (key, attributes).\n   */\n  mapNodes(callback) {\n    if (typeof callback !== 'function')\n      throw new InvalidArgumentsGraphError(\n        'Graph.mapNode: expecting a callback.'\n      );\n\n    const iterator = this._nodes.values();\n\n    let step, nodeData;\n\n    const result = new Array(this.order);\n    let i = 0;\n\n    while (((step = iterator.next()), step.done !== true)) {\n      nodeData = step.value;\n      result[i++] = callback(nodeData.key, nodeData.attributes);\n    }\n\n    return result;\n  }\n\n  /**\n   * Method returning whether some node verify the given predicate.\n   *\n   * @param  {function}  callback - Callback (key, attributes).\n   */\n  someNode(callback) {\n    if (typeof callback !== 'function')\n      throw new InvalidArgumentsGraphError(\n        'Graph.someNode: expecting a callback.'\n      );\n\n    const iterator = this._nodes.values();\n\n    let step, nodeData;\n\n    while (((step = iterator.next()), step.done !== true)) {\n      nodeData = step.value;\n\n      if (callback(nodeData.key, nodeData.attributes)) return true;\n    }\n\n    return false;\n  }\n\n  /**\n   * Method returning whether all node verify the given predicate.\n   *\n   * @param  {function}  callback - Callback (key, attributes).\n   */\n  everyNode(callback) {\n    if (typeof callback !== 'function')\n      throw new InvalidArgumentsGraphError(\n        'Graph.everyNode: expecting a callback.'\n      );\n\n    const iterator = this._nodes.values();\n\n    let step, nodeData;\n\n    while (((step = iterator.next()), step.done !== true)) {\n      nodeData = step.value;\n\n      if (!callback(nodeData.key, nodeData.attributes)) return false;\n    }\n\n    return true;\n  }\n\n  /**\n   * Method filtering nodes.\n   *\n   * @param  {function}  callback - Callback (key, attributes).\n   */\n  filterNodes(callback) {\n    if (typeof callback !== 'function')\n      throw new InvalidArgumentsGraphError(\n        'Graph.filterNodes: expecting a callback.'\n      );\n\n    const iterator = this._nodes.values();\n\n    let step, nodeData;\n\n    const result = [];\n\n    while (((step = iterator.next()), step.done !== true)) {\n      nodeData = step.value;\n\n      if (callback(nodeData.key, nodeData.attributes))\n        result.push(nodeData.key);\n    }\n\n    return result;\n  }\n\n  /**\n   * Method reducing nodes.\n   *\n   * @param  {function}  callback - Callback (accumulator, key, attributes).\n   */\n  reduceNodes(callback, initialValue) {\n    if (typeof callback !== 'function')\n      throw new InvalidArgumentsGraphError(\n        'Graph.reduceNodes: expecting a callback.'\n      );\n\n    if (arguments.length < 2)\n      throw new InvalidArgumentsGraphError(\n        'Graph.reduceNodes: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.'\n      );\n\n    let accumulator = initialValue;\n\n    const iterator = this._nodes.values();\n\n    let step, nodeData;\n\n    while (((step = iterator.next()), step.done !== true)) {\n      nodeData = step.value;\n      accumulator = callback(accumulator, nodeData.key, nodeData.attributes);\n    }\n\n    return accumulator;\n  }\n\n  /**\n   * Method returning an iterator over the graph's node entries.\n   *\n   * @return {Iterator}\n   */\n  nodeEntries() {\n    const iterator = this._nodes.values();\n\n    return new Iterator(() => {\n      const step = iterator.next();\n\n      if (step.done) return step;\n\n      const data = step.value;\n\n      return {\n        value: {node: data.key, attributes: data.attributes},\n        done: false\n      };\n    });\n  }\n\n  /**---------------------------------------------------------------------------\n   * Serialization\n   **---------------------------------------------------------------------------\n   */\n\n  /**\n   * Method used to export the whole graph.\n   *\n   * @return {object} - The serialized graph.\n   */\n  export() {\n    const nodes = new Array(this._nodes.size);\n\n    let i = 0;\n\n    this._nodes.forEach((data, key) => {\n      nodes[i++] = serializeNode(key, data);\n    });\n\n    const edges = new Array(this._edges.size);\n\n    i = 0;\n\n    this._edges.forEach((data, key) => {\n      edges[i++] = serializeEdge(this.type, key, data);\n    });\n\n    return {\n      options: {\n        type: this.type,\n        multi: this.multi,\n        allowSelfLoops: this.allowSelfLoops\n      },\n      attributes: this.getAttributes(),\n      nodes,\n      edges\n    };\n  }\n\n  /**\n   * Method used to import a serialized graph.\n   *\n   * @param  {object|Graph} data  - The serialized graph.\n   * @param  {boolean}      merge - Whether to merge data.\n   * @return {Graph}              - Returns itself for chaining.\n   */\n  import(data, merge = false) {\n    // Importing a Graph instance directly\n    if (data instanceof Graph) {\n      // Nodes\n      data.forEachNode((n, a) => {\n        if (merge) this.mergeNode(n, a);\n        else this.addNode(n, a);\n      });\n\n      // Edges\n      data.forEachEdge((e, a, s, t, _sa, _ta, u) => {\n        if (merge) {\n          if (u) this.mergeUndirectedEdgeWithKey(e, s, t, a);\n          else this.mergeDirectedEdgeWithKey(e, s, t, a);\n        } else {\n          if (u) this.addUndirectedEdgeWithKey(e, s, t, a);\n          else this.addDirectedEdgeWithKey(e, s, t, a);\n        }\n      });\n\n      return this;\n    }\n\n    // Importing a serialized graph\n    if (!isPlainObject(data))\n      throw new InvalidArgumentsGraphError(\n        'Graph.import: invalid argument. Expecting a serialized graph or, alternatively, a Graph instance.'\n      );\n\n    if (data.attributes) {\n      if (!isPlainObject(data.attributes))\n        throw new InvalidArgumentsGraphError(\n          'Graph.import: invalid attributes. Expecting a plain object.'\n        );\n\n      if (merge) this.mergeAttributes(data.attributes);\n      else this.replaceAttributes(data.attributes);\n    }\n\n    let i, l, list, node, edge;\n\n    if (data.nodes) {\n      list = data.nodes;\n\n      if (!Array.isArray(list))\n        throw new InvalidArgumentsGraphError(\n          'Graph.import: invalid nodes. Expecting an array.'\n        );\n\n      for (i = 0, l = list.length; i < l; i++) {\n        node = list[i];\n\n        // Validating\n        validateSerializedNode(node);\n\n        // Adding the node\n        const {key, attributes} = node;\n\n        if (merge) this.mergeNode(key, attributes);\n        else this.addNode(key, attributes);\n      }\n    }\n\n    if (data.edges) {\n      let undirectedByDefault = false;\n\n      if (this.type === 'undirected') {\n        undirectedByDefault = true;\n      }\n\n      list = data.edges;\n\n      if (!Array.isArray(list))\n        throw new InvalidArgumentsGraphError(\n          'Graph.import: invalid edges. Expecting an array.'\n        );\n\n      for (i = 0, l = list.length; i < l; i++) {\n        edge = list[i];\n\n        // Validating\n        validateSerializedEdge(edge);\n\n        // Adding the edge\n        const {\n          source,\n          target,\n          attributes,\n          undirected = undirectedByDefault\n        } = edge;\n\n        let method;\n\n        if ('key' in edge) {\n          method = merge\n            ? undirected\n              ? this.mergeUndirectedEdgeWithKey\n              : this.mergeDirectedEdgeWithKey\n            : undirected\n            ? this.addUndirectedEdgeWithKey\n            : this.addDirectedEdgeWithKey;\n\n          method.call(this, edge.key, source, target, attributes);\n        } else {\n          method = merge\n            ? undirected\n              ? this.mergeUndirectedEdge\n              : this.mergeDirectedEdge\n            : undirected\n            ? this.addUndirectedEdge\n            : this.addDirectedEdge;\n\n          method.call(this, source, target, attributes);\n        }\n      }\n    }\n\n    return this;\n  }\n\n  /**---------------------------------------------------------------------------\n   * Utils\n   **---------------------------------------------------------------------------\n   */\n\n  /**\n   * Method returning a null copy of the graph, i.e. a graph without nodes\n   * & edges but with the exact same options.\n   *\n   * @param  {object} options - Options to merge with the current ones.\n   * @return {Graph}          - The null copy.\n   */\n  nullCopy(options) {\n    const graph = new Graph(assign({}, this._options, options));\n    graph.replaceAttributes(assign({}, this.getAttributes()));\n    return graph;\n  }\n\n  /**\n   * Method returning an empty copy of the graph, i.e. a graph without edges but\n   * with the exact same options.\n   *\n   * @param  {object} options - Options to merge with the current ones.\n   * @return {Graph}          - The empty copy.\n   */\n  emptyCopy(options) {\n    const graph = this.nullCopy(options);\n\n    this._nodes.forEach((nodeData, key) => {\n      const attributes = assign({}, nodeData.attributes);\n\n      // NOTE: no need to emit events since user cannot access the instance yet\n      nodeData = new graph.NodeDataClass(key, attributes);\n      graph._nodes.set(key, nodeData);\n    });\n\n    return graph;\n  }\n\n  /**\n   * Method returning an exact copy of the graph.\n   *\n   * @param  {object} options - Upgrade options.\n   * @return {Graph}          - The copy.\n   */\n  copy(options) {\n    options = options || {};\n\n    if (\n      typeof options.type === 'string' &&\n      options.type !== this.type &&\n      options.type !== 'mixed'\n    )\n      throw new UsageGraphError(\n        `Graph.copy: cannot create an incompatible copy from \"${this.type}\" type to \"${options.type}\" because this would mean losing information about the current graph.`\n      );\n\n    if (\n      typeof options.multi === 'boolean' &&\n      options.multi !== this.multi &&\n      options.multi !== true\n    )\n      throw new UsageGraphError(\n        'Graph.copy: cannot create an incompatible copy by downgrading a multi graph to a simple one because this would mean losing information about the current graph.'\n      );\n\n    if (\n      typeof options.allowSelfLoops === 'boolean' &&\n      options.allowSelfLoops !== this.allowSelfLoops &&\n      options.allowSelfLoops !== true\n    )\n      throw new UsageGraphError(\n        'Graph.copy: cannot create an incompatible copy from a graph allowing self loops to one that does not because this would mean losing information about the current graph.'\n      );\n\n    const graph = this.emptyCopy(options);\n\n    const iterator = this._edges.values();\n\n    let step, edgeData;\n\n    while (((step = iterator.next()), step.done !== true)) {\n      edgeData = step.value;\n\n      // NOTE: no need to emit events since user cannot access the instance yet\n      addEdge(\n        graph,\n        'copy',\n        false,\n        edgeData.undirected,\n        edgeData.key,\n        edgeData.source.key,\n        edgeData.target.key,\n        assign({}, edgeData.attributes)\n      );\n    }\n\n    return graph;\n  }\n\n  /**---------------------------------------------------------------------------\n   * Known methods\n   **---------------------------------------------------------------------------\n   */\n\n  /**\n   * Method used by JavaScript to perform JSON serialization.\n   *\n   * @return {object} - The serialized graph.\n   */\n  toJSON() {\n    return this.export();\n  }\n\n  /**\n   * Method returning [object Graph].\n   */\n  toString() {\n    return '[object Graph]';\n  }\n\n  /**\n   * Method used internally by node's console to display a custom object.\n   *\n   * @return {object} - Formatted object representation of the graph.\n   */\n  inspect() {\n    const nodes = {};\n    this._nodes.forEach((data, key) => {\n      nodes[key] = data.attributes;\n    });\n\n    const edges = {},\n      multiIndex = {};\n\n    this._edges.forEach((data, key) => {\n      const direction = data.undirected ? '--' : '->';\n\n      let label = '';\n\n      let source = data.source.key;\n      let target = data.target.key;\n      let tmp;\n\n      if (data.undirected && source > target) {\n        tmp = source;\n        source = target;\n        target = tmp;\n      }\n\n      const desc = `(${source})${direction}(${target})`;\n\n      if (!key.startsWith('geid_')) {\n        label += `[${key}]: `;\n      } else if (this.multi) {\n        if (typeof multiIndex[desc] === 'undefined') {\n          multiIndex[desc] = 0;\n        } else {\n          multiIndex[desc]++;\n        }\n\n        label += `${multiIndex[desc]}. `;\n      }\n\n      label += desc;\n\n      edges[label] = data.attributes;\n    });\n\n    const dummy = {};\n\n    for (const k in this) {\n      if (\n        this.hasOwnProperty(k) &&\n        !EMITTER_PROPS.has(k) &&\n        typeof this[k] !== 'function' &&\n        typeof k !== 'symbol'\n      )\n        dummy[k] = this[k];\n    }\n\n    dummy.attributes = this._attributes;\n    dummy.nodes = nodes;\n    dummy.edges = edges;\n\n    privateProperty(dummy, 'constructor', this.constructor);\n\n    return dummy;\n  }\n}\n\n/**\n * Attaching methods to the prototype.\n *\n * Here, we are attaching a wide variety of methods to the Graph class'\n * prototype when those are very numerous and when their creation is\n * abstracted.\n */\n\n/**\n * Attaching custom inspect method for node >= 10.\n */\nif (typeof Symbol !== 'undefined')\n  Graph.prototype[Symbol.for('nodejs.util.inspect.custom')] =\n    Graph.prototype.inspect;\n\n/**\n * Related to edge addition.\n */\nEDGE_ADD_METHODS.forEach(method => {\n  ['add', 'merge', 'update'].forEach(verb => {\n    const name = method.name(verb);\n    const fn = verb === 'add' ? addEdge : mergeEdge;\n\n    if (method.generateKey) {\n      Graph.prototype[name] = function (source, target, attributes) {\n        return fn(\n          this,\n          name,\n          true,\n          (method.type || this.type) === 'undirected',\n          null,\n          source,\n          target,\n          attributes,\n          verb === 'update'\n        );\n      };\n    } else {\n      Graph.prototype[name] = function (edge, source, target, attributes) {\n        return fn(\n          this,\n          name,\n          false,\n          (method.type || this.type) === 'undirected',\n          edge,\n          source,\n          target,\n          attributes,\n          verb === 'update'\n        );\n      };\n    }\n  });\n});\n\n/**\n * Attributes-related.\n */\nattachNodeAttributesMethods(Graph);\nattachEdgeAttributesMethods(Graph);\n\n/**\n * Edge iteration-related.\n */\nattachEdgeIterationMethods(Graph);\n\n/**\n * Neighbor iteration-related.\n */\nattachNeighborIterationMethods(Graph);\n","/**\n * Graphology Helper Classes\n * ==========================\n *\n * Building some higher-order classes instantiating the graph with\n * predefinite options.\n */\nimport {assign} from './utils';\nimport Graph from './graph';\n\nimport {\n  InvalidArgumentsGraphError,\n  NotFoundGraphError,\n  UsageGraphError\n} from './errors';\n\n/**\n * Alternative constructors.\n */\nclass DirectedGraph extends Graph {\n  constructor(options) {\n    const finalOptions = assign({type: 'directed'}, options);\n\n    if ('multi' in finalOptions && finalOptions.multi !== false)\n      throw new InvalidArgumentsGraphError(\n        'DirectedGraph.from: inconsistent indication that the graph should be multi in given options!'\n      );\n\n    if (finalOptions.type !== 'directed')\n      throw new InvalidArgumentsGraphError(\n        'DirectedGraph.from: inconsistent \"' +\n          finalOptions.type +\n          '\" type in given options!'\n      );\n\n    super(finalOptions);\n  }\n}\nclass UndirectedGraph extends Graph {\n  constructor(options) {\n    const finalOptions = assign({type: 'undirected'}, options);\n\n    if ('multi' in finalOptions && finalOptions.multi !== false)\n      throw new InvalidArgumentsGraphError(\n        'UndirectedGraph.from: inconsistent indication that the graph should be multi in given options!'\n      );\n\n    if (finalOptions.type !== 'undirected')\n      throw new InvalidArgumentsGraphError(\n        'UndirectedGraph.from: inconsistent \"' +\n          finalOptions.type +\n          '\" type in given options!'\n      );\n\n    super(finalOptions);\n  }\n}\nclass MultiGraph extends Graph {\n  constructor(options) {\n    const finalOptions = assign({multi: true}, options);\n\n    if ('multi' in finalOptions && finalOptions.multi !== true)\n      throw new InvalidArgumentsGraphError(\n        'MultiGraph.from: inconsistent indication that the graph should be simple in given options!'\n      );\n\n    super(finalOptions);\n  }\n}\nclass MultiDirectedGraph extends Graph {\n  constructor(options) {\n    const finalOptions = assign({type: 'directed', multi: true}, options);\n\n    if ('multi' in finalOptions && finalOptions.multi !== true)\n      throw new InvalidArgumentsGraphError(\n        'MultiDirectedGraph.from: inconsistent indication that the graph should be simple in given options!'\n      );\n\n    if (finalOptions.type !== 'directed')\n      throw new InvalidArgumentsGraphError(\n        'MultiDirectedGraph.from: inconsistent \"' +\n          finalOptions.type +\n          '\" type in given options!'\n      );\n\n    super(finalOptions);\n  }\n}\nclass MultiUndirectedGraph extends Graph {\n  constructor(options) {\n    const finalOptions = assign({type: 'undirected', multi: true}, options);\n\n    if ('multi' in finalOptions && finalOptions.multi !== true)\n      throw new InvalidArgumentsGraphError(\n        'MultiUndirectedGraph.from: inconsistent indication that the graph should be simple in given options!'\n      );\n\n    if (finalOptions.type !== 'undirected')\n      throw new InvalidArgumentsGraphError(\n        'MultiUndirectedGraph.from: inconsistent \"' +\n          finalOptions.type +\n          '\" type in given options!'\n      );\n\n    super(finalOptions);\n  }\n}\n\n/**\n * Attaching static #.from method to each of the constructors.\n */\nfunction attachStaticFromMethod(Class) {\n  /**\n   * Builds a graph from serialized data or another graph's data.\n   *\n   * @param  {Graph|SerializedGraph} data      - Hydratation data.\n   * @param  {object}                [options] - Options.\n   * @return {Class}\n   */\n  Class.from = function (data, options) {\n    // Merging given options with serialized ones\n    const finalOptions = assign({}, data.options, options);\n\n    const instance = new Class(finalOptions);\n    instance.import(data);\n\n    return instance;\n  };\n}\n\nattachStaticFromMethod(Graph);\nattachStaticFromMethod(DirectedGraph);\nattachStaticFromMethod(UndirectedGraph);\nattachStaticFromMethod(MultiGraph);\nattachStaticFromMethod(MultiDirectedGraph);\nattachStaticFromMethod(MultiUndirectedGraph);\n\nGraph.Graph = Graph;\nGraph.DirectedGraph = DirectedGraph;\nGraph.UndirectedGraph = UndirectedGraph;\nGraph.MultiGraph = MultiGraph;\nGraph.MultiDirectedGraph = MultiDirectedGraph;\nGraph.MultiUndirectedGraph = MultiUndirectedGraph;\n\nGraph.InvalidArgumentsGraphError = InvalidArgumentsGraphError;\nGraph.NotFoundGraphError = NotFoundGraphError;\nGraph.UsageGraphError = UsageGraphError;\n\nexport {\n  Graph,\n  DirectedGraph,\n  UndirectedGraph,\n  MultiGraph,\n  MultiDirectedGraph,\n  MultiUndirectedGraph\n};\n"],"names":["assign","target","arguments","i","l","length","k","getMatchingEdge","graph","source","type","sourceData","_nodes","get","edge","out","undirected","isPlainObject","value","_typeof","isEmpty","o","privateProperty","name","Object","defineProperty","enumerable","configurable","writable","readOnlyProperty","descriptor","validateHints","hints","attributes","Array","isArray","ReflectOwnKeys","R","Reflect","ReflectApply","apply","receiver","args","Function","prototype","call","ownKeys","getOwnPropertySymbols","getOwnPropertyNames","concat","NumberIsNaN","Number","isNaN","EventEmitter","init","this","eventsModule","exports","events","once","emitter","Promise","resolve","reject","errorListener","err","removeListener","resolver","slice","eventTargetAgnosticAddListener","handler","flags","on","addErrorHandlerIfEventEmitter","_events","undefined","_eventsCount","_maxListeners","defaultMaxListeners","checkListener","listener","TypeError","_getMaxListeners","that","_addListener","prepend","m","existing","warning","create","newListener","emit","unshift","push","warned","w","Error","String","count","console","warn","onceWrapper","fired","wrapFn","_onceWrap","state","wrapped","bind","_listeners","unwrap","evlistener","arr","ret","unwrapListeners","arrayClone","listenerCount","n","copy","addEventListener","wrapListener","arg","removeEventListener","Iterator","next","set","RangeError","getPrototypeOf","setMaxListeners","getMaxListeners","doError","error","er","message","context","len","listeners","addListener","prependListener","prependOnceListener","list","position","originalListener","shift","index","pop","spliceOne","off","removeAllListeners","key","keys","rawListeners","eventNames","Symbol","iterator","Iterator$2","of","done","empty","fromSequence","sequence","is","support","ARRAY_BUFFER_SUPPORT","ArrayBuffer","SYMBOL_SUPPORT","require$$0","require$$1","iter","isView","iterOrNull","take","iterable","step","Infinity","array","GraphError","_Error","_this","_inheritsLoose","_wrapNativeSuper","InvalidArgumentsGraphError","_GraphError","_this2","captureStackTrace","constructor","NotFoundGraphError","_GraphError2","_this3","UsageGraphError","_GraphError3","_this4","MixedNodeData","clear","DirectedNodeData","UndirectedNodeData","EdgeData","inDegree","outDegree","undirectedDegree","undirectedLoops","directedLoops","attach","outKey","inKey","attachMulti","adj","head","previous","detach","detachMulti","findRelevantNodeData","method","mode","nodeOrEdge","nameOrEdge","add1","add2","nodeData","edgeData","arg1","arg2","_edges","NODE_ATTRIBUTES_METHODS","element","attacher","Class","_findRelevantNodeData","data","_findRelevantNodeData3","hasOwnProperty","_findRelevantNodeData4","_findRelevantNodeData5","updater","_findRelevantNodeData6","_findRelevantNodeData7","_findRelevantNodeData8","_findRelevantNodeData9","EDGE_ATTRIBUTES_METHODS","multi","chain","iterables","current","EDGES_ITERATION","direction","forEachSimple","breakable","object","callback","avoid","shouldBreak","forEachMulti","createIterator","sourceAttributes","targetAttributes","forEachForKeySimple","targetData","forEachForKeyMulti","createIteratorForKey","createEdgeArray","size","from","undirectedSize","directedSize","mask","values","forEachEdge","shouldFilter","_data","createEdgeIterator","forEachEdgeForNode","found","fn","createEdgeArrayForNode","edges","createEdgeIteratorForNode","forEachEdgeForPath","createEdgeArrayForPath","createEdgeIteratorForPath","NEIGHBORS_ITERATION","CompositeSetWrapper","A","B","forEachInObjectOnce","visited","neighborData","has","forEachNeighbor","wrap","createDedupedObjectIterator","neighbor","attachNeighborArrayCreator","description","node","neighbors","createNeighborArrayForNode","attachNeighborIteratorCreator","iteratorName","createNeighborIterator","forEachAdjacency","assymetric","disconnectedNodes","hasEdges","validateSerializedNode","validateSerializedEdge","INSTANCE_ID","Math","floor","random","TYPES","Set","EMITTER_PROPS","DEFAULTS","allowSelfLoops","unsafeAddNode","NodeDataClass","addEdge","mustGenerateKey","eventData","_edgeKeyGenerator","isSelfLoop","_undirectedSelfLoopCount","_directedSelfLoopCount","_undirectedSize","_directedSize","mergeEdge","asUpdater","alreadyExistingEdgeData","info","oldAttributes","sourceWasAdded","targetWasAdded","dropEdgeFromData","Graph","_EventEmitter","options","_assertThisInitialized","instancePrefix","edgeId","Map","availableEdgeKey","forEach","prop","_options","_proto","_resetInstanceCounters","hasNode","hasDirectedEdge","hasUndirectedEdge","hasEdge","directedEdge","undirectedEdge","areDirectedNeighbors","areOutNeighbors","areInNeighbors","areUndirectedNeighbors","areNeighbors","areInboundNeighbors","areOutboundNeighbors","directedDegree","inboundDegree","degree","outboundDegree","inDegreeWithoutSelfLoops","outDegreeWithoutSelfLoops","directedDegreeWithoutSelfLoops","undirectedDegreeWithoutSelfLoops","inboundDegreeWithoutSelfLoops","loops","outboundDegreeWithoutSelfLoops","degreeWithoutSelfLoops","extremities","opposite","hasExtremity","isUndirected","isDirected","addNode","mergeNode","updateNode","dropNode","dropEdge","dropDirectedEdge","dropUndirectedEdge","clearEdges","getAttribute","_attributes","getAttributes","hasAttribute","setAttribute","updateAttribute","removeAttribute","replaceAttributes","mergeAttributes","updateAttributes","updateEachNodeAttributes","updateEachEdgeAttributes","forEachAdjacencyEntry","forEachAdjacencyEntryWithOrphans","forEachAssymetricAdjacencyEntry","forEachAssymetricAdjacencyEntryWithOrphans","nodes","forEachNode","findNode","mapNodes","result","order","someNode","everyNode","filterNodes","reduceNodes","initialValue","accumulator","nodeEntries","serialized","serializeNode","serializeEdge","merge","a","e","s","t","_sa","_ta","u","mergeUndirectedEdgeWithKey","mergeDirectedEdgeWithKey","addUndirectedEdgeWithKey","addDirectedEdgeWithKey","_node","undirectedByDefault","_edge","_edge$undirected","mergeUndirectedEdge","mergeDirectedEdge","addUndirectedEdge","addDirectedEdge","nullCopy","emptyCopy","toJSON","toString","inspect","multiIndex","tmp","label","desc","startsWith","dummy","verb","generateKey","_ref","attachNodeAttributesMethods","attachEdgeAttributesMethods","attachEdgeArrayCreator","forEachName","toUpperCase","mapName","ea","sa","ta","filterName","reduceName","attachForEachEdge","findEdgeName","someName","everyName","attachFindEdge","originalName","attachEdgeIteratorCreator","attachEdgeIterationMethods","attachForEachNeighbor","capitalizedSingular","findName","attachFindNeighbor","attachNeighborIterationMethods","DirectedGraph","_Graph","finalOptions","UndirectedGraph","_Graph2","MultiGraph","_Graph3","MultiDirectedGraph","_Graph4","MultiUndirectedGraph","_Graph5","attachStaticFromMethod","instance"],"mappings":"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"}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy