(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	else if(typeof define === 'function' && define.amd)
		define([], factory);
	else if(typeof exports === 'object')
		exports["dagDependencies"] = factory();
	else
		root["Airflow"] = root["Airflow"] || {}, root["Airflow"]["dagDependencies"] = factory();
})(window, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// create a fake namespace object
/******/ 	// mode & 1: value is a module id, require it
/******/ 	// mode & 2: merge all properties of value into the ns
/******/ 	// mode & 4: return value when already ns object
/******/ 	// mode & 8|1: behave like require
/******/ 	__webpack_require__.t = function(value, mode) {
/******/ 		if(mode & 1) value = __webpack_require__(value);
/******/ 		if(mode & 8) return value;
/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ 		var ns = Object.create(null);
/******/ 		__webpack_require__.r(ns);
/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ 		return ns;
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 10);
/******/ })
/************************************************************************/
/******/ ({

/***/ 10:
/***/ (function(module, exports) {

/*!
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*
  global d3, localStorage, dagreD3, nodes, edges, arrange, document,
*/
const highlightColor = '#000000';
const upstreamColor = '#2020A0';
const downstreamColor = '#0000FF';
const initialStrokeWidth = '3px';
const highlightStrokeWidth = '5px';
const duration = 500; // Preparation of DagreD3 data structures

const g = new dagreD3.graphlib.Graph().setGraph({
  nodesep: 15,
  ranksep: 15,
  rankdir: arrange
}).setDefaultEdgeLabel(() => ({
  lineInterpolate: 'basis'
})); // Set all nodes and styles

nodes.forEach(node => {
  g.setNode(node.id, node.value);
}); // Set edges

edges.forEach(edge => {
  g.setEdge(edge.u, edge.v);
});
const render = dagreD3.render();
const svg = d3.select('#graph-svg');
const innerSvg = d3.select('#graph-svg g');
innerSvg.call(render, g); // Returns true if a node's id or its children's id matches search_text

function nodeMatches(nodeId, searchText) {
  if (nodeId.indexOf(searchText) > -1) return true;
  return false;
}

function highlightNodes(nodes, color, strokeWidth) {
  nodes.forEach(nodeid => {
    const myNode = g.node(nodeid).elem;
    d3.select(myNode).selectAll('rect,circle').style('stroke', color).style('stroke-width', strokeWidth);
  });
}

let zoom = null;

function setUpZoomSupport() {
  // Set up zoom support for Graph
  zoom = d3.behavior.zoom().on('zoom', () => {
    innerSvg.attr('transform', `translate(${d3.event.translate})scale(${d3.event.scale})`);
  });
  svg.call(zoom); // Centering the DAG on load
  // Get Dagre Graph dimensions

  const graphWidth = g.graph().width;
  const graphHeight = g.graph().height; // Get SVG dimensions

  const padding = 20;
  const svgBb = svg.node().getBoundingClientRect();
  const width = svgBb.width - padding * 2;
  const height = svgBb.height - padding; // we are not centering the dag vertically
  // Calculate applicable scale for zoom

  const zoomScale = Math.min(Math.min(width / graphWidth, height / graphHeight), 1.5 // cap zoom level to 1.5 so nodes are not too large
  );
  zoom.translate([width / 2 - graphWidth * zoomScale / 2 + padding, padding]);
  zoom.scale(zoomScale);
  zoom.event(innerSvg);
}

function setUpNodeHighlighting(focusItem = null) {
  d3.selectAll('g.node').on('mouseover', function (d) {
    d3.select(this).selectAll('rect').style('stroke', highlightColor);
    highlightNodes(g.predecessors(d), upstreamColor, highlightStrokeWidth);
    highlightNodes(g.successors(d), downstreamColor, highlightStrokeWidth);
    const adjacentNodeNames = [d, ...g.predecessors(d), ...g.successors(d)];
    d3.selectAll('g.nodes g.node').filter(x => !adjacentNodeNames.includes(x)).style('opacity', 0.2);
    const adjacentEdges = g.nodeEdges(d);
    d3.selectAll('g.edgePath')[0] // eslint-disable-next-line no-underscore-dangle
    .filter(x => !adjacentEdges.includes(x.__data__)).forEach(x => {
      d3.select(x).style('opacity', 0.2);
    });
  });
  d3.selectAll('g.node').on('mouseout', function (d) {
    d3.select(this).selectAll('rect,circle').style('stroke', null);
    highlightNodes(g.predecessors(d), null, initialStrokeWidth);
    highlightNodes(g.successors(d), null, initialStrokeWidth);
    d3.selectAll('g.node').style('opacity', 1);
    d3.selectAll('g.node rect').style('stroke-width', initialStrokeWidth);
    d3.selectAll('g.edgePath').style('opacity', 1);

    if (focusItem) {
      localStorage.removeItem(focusItem);
    }
  });
}

function searchboxHighlighting(s) {
  let match = null;
  d3.selectAll('g.nodes g.node').forEach(function forEach(d) {
    if (s === '') {
      d3.select('g.edgePaths').transition().duration(duration).style('opacity', 1);
      d3.select(this).transition().duration(duration).style('opacity', 1).selectAll('rect').style('stroke-width', initialStrokeWidth);
    } else {
      d3.select('g.edgePaths').transition().duration(duration).style('opacity', 0.2);

      if (nodeMatches(d, s)) {
        if (!match) match = this;
        d3.select(this).transition().duration(duration).style('opacity', 1).selectAll('rect').style('stroke-width', highlightStrokeWidth);
      } else {
        d3.select(this).transition().style('opacity', 0.2).duration(duration).selectAll('rect').style('stroke-width', initialStrokeWidth);
      }
    }
  }); // This moves the matched node to the center of the graph area

  if (match) {
    const transform = d3.transform(d3.select(match).attr('transform'));
    const svgBb = svg.node().getBoundingClientRect();
    transform.translate = [svgBb.width / 2 - transform.translate[0], svgBb.height / 2 - transform.translate[1]];
    transform.scale = [1, 1];

    if (zoom !== null) {
      zoom.translate(transform.translate);
      zoom.scale(1);
      zoom.event(innerSvg);
    }
  }
}

setUpNodeHighlighting();
setUpZoomSupport();
d3.select('#searchbox').on('keyup', () => {
  const s = document.getElementById('searchbox').value;
  searchboxHighlighting(s);
});

/***/ })

/******/ });
});