UNPKG

gantt-task-react-powern

Version:

Interactive Gantt Chart for React with TypeScript.

5,036 lines 175 kB
import React, { useMemo, useRef, useState, useEffect } from 'react';
import { useVirtualizer } from '@tanstack/react-virtual';

function _extends() {
  _extends = Object.assign || function (target) {
    for (var i = 1; i < arguments.length; i++) {
      var source = arguments[i];

      for (var key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
          target[key] = source[key];
        }
      }
    }

    return target;
  };

  return _extends.apply(this, arguments);
}

function _unsupportedIterableToArray(o, minLen) {
  if (!o) return;
  if (typeof o === "string") return _arrayLikeToArray(o, minLen);
  var n = Object.prototype.toString.call(o).slice(8, -1);
  if (n === "Object" && o.constructor) n = o.constructor.name;
  if (n === "Map" || n === "Set") return Array.from(o);
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}

function _arrayLikeToArray(arr, len) {
  if (len == null || len > arr.length) len = arr.length;

  for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];

  return arr2;
}

function _createForOfIteratorHelperLoose(o, allowArrayLike) {
  var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
  if (it) return (it = it.call(o)).next.bind(it);

  if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
    if (it) o = it;
    var i = 0;
    return function () {
      if (i >= o.length) return {
        done: true
      };
      return {
        done: false,
        value: o[i++]
      };
    };
  }

  throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}

var ViewMode;

(function (ViewMode) {
  ViewMode["Hour"] = "Hour";
  ViewMode["QuarterDay"] = "Quarter Day";
  ViewMode["HalfDay"] = "Half Day";
  ViewMode["Day"] = "Day";
  ViewMode["Week"] = "Week";
  ViewMode["Month"] = "Month";
  ViewMode["Quarter"] = "Quarter";
  ViewMode["Year"] = "Year";
})(ViewMode || (ViewMode = {}));

var _VIEW_MODE_DEFAULT_VI, _VIEW_MODE_MAX_VISIBL;
var intlDTCache = {};
var getCachedDateTimeFormat = function getCachedDateTimeFormat(locString, opts) {
  if (opts === void 0) {
    opts = {};
  }

  var key = JSON.stringify([locString, opts]);
  var dtf = intlDTCache[key];

  if (!dtf) {
    dtf = new Intl.DateTimeFormat(locString, opts);
    intlDTCache[key] = dtf;
  }

  return dtf;
};
var addToDate = function addToDate(date, quantity, scale) {
  var newDate = new Date(date.getFullYear() + (scale === "year" ? quantity : 0), date.getMonth() + (scale === "month" ? quantity : 0), date.getDate() + (scale === "day" ? quantity : 0), date.getHours() + (scale === "hour" ? quantity : 0), date.getMinutes() + (scale === "minute" ? quantity : 0), date.getSeconds() + (scale === "second" ? quantity : 0), date.getMilliseconds() + (scale === "millisecond" ? quantity : 0));
  return newDate;
};
var startOfDate = function startOfDate(date, scale) {
  var scores = ["millisecond", "second", "minute", "hour", "day", "month", "quarter", "year"];

  var shouldReset = function shouldReset(_scale) {
    var maxScore = scores.indexOf(scale);
    return scores.indexOf(_scale) <= maxScore;
  };

  var newDate = new Date(date.getFullYear(), shouldReset("year") ? 0 : date.getMonth(), shouldReset("month") ? 1 : date.getDate(), shouldReset("day") ? 0 : date.getHours(), shouldReset("hour") ? 0 : date.getMinutes(), shouldReset("minute") ? 0 : date.getSeconds(), shouldReset("second") ? 0 : date.getMilliseconds());
  return newDate;
};

var getFiscalQuarterStartDate = function getFiscalQuarterStartDate(date, quarterStart) {
  var month = date.getMonth();
  var offset = (month - quarterStart + 12) % 12;
  var qStartMonth = (quarterStart + Math.floor(offset / 3) * 3) % 12;
  var year = date.getFullYear();
  if (qStartMonth > month) year -= 1;
  return new Date(year, qStartMonth, 1);
};

var VIEW_MODE_DEFAULT_VISIBLE_COUNT = (_VIEW_MODE_DEFAULT_VI = {}, _VIEW_MODE_DEFAULT_VI[ViewMode.Day] = 14, _VIEW_MODE_DEFAULT_VI[ViewMode.Week] = 6, _VIEW_MODE_DEFAULT_VI[ViewMode.Month] = 6, _VIEW_MODE_DEFAULT_VI[ViewMode.Quarter] = 4, _VIEW_MODE_DEFAULT_VI);
var VIEW_MODE_MAX_VISIBLE_COUNT = (_VIEW_MODE_MAX_VISIBL = {}, _VIEW_MODE_MAX_VISIBL[ViewMode.Day] = 30, _VIEW_MODE_MAX_VISIBL[ViewMode.Week] = 13, _VIEW_MODE_MAX_VISIBL[ViewMode.Month] = 12, _VIEW_MODE_MAX_VISIBL[ViewMode.Quarter] = 8, _VIEW_MODE_MAX_VISIBL);
var ganttDateRange = function ganttDateRange(tasks, viewMode, preStepsCount, quarterStart) {
  var _tasks$, _tasks$2, _tasks$3, _tasks$4;

  if (quarterStart === void 0) {
    quarterStart = 0;
  }

  var newStartDate = ((_tasks$ = tasks[0]) === null || _tasks$ === void 0 ? void 0 : _tasks$.start.getTime()) !== 0 ? ((_tasks$2 = tasks[0]) === null || _tasks$2 === void 0 ? void 0 : _tasks$2.start) || new Date() : new Date();
  var newEndDate = ((_tasks$3 = tasks[0]) === null || _tasks$3 === void 0 ? void 0 : _tasks$3.end.getTime()) !== 0 ? ((_tasks$4 = tasks[0]) === null || _tasks$4 === void 0 ? void 0 : _tasks$4.end) || new Date() : new Date();

  for (var _iterator = _createForOfIteratorHelperLoose(tasks), _step; !(_step = _iterator()).done;) {
    var task = _step.value;

    if (task.start && task.start.getTime() !== 0 && task.start < newStartDate) {
      newStartDate = task.start;
    }

    if (task.end && task.end.getTime() !== 0 && task.end > newEndDate) {
      newEndDate = task.end;
    }

    if (task.actualStart && task.actualStart.getTime() !== 0 && task.actualStart < newStartDate) {
      newStartDate = task.actualStart;
    }

    if (task.actualEnd && task.actualEnd.getTime() !== 0 && task.actualEnd > newEndDate) {
      newEndDate = task.actualEnd;
    }
  }

  switch (viewMode) {
    case ViewMode.Year:
      newStartDate = addToDate(newStartDate, -1, "year");
      newStartDate = startOfDate(newStartDate, "year");
      newEndDate = addToDate(newEndDate, 1, "year");
      newEndDate = startOfDate(newEndDate, "year");
      break;

    case ViewMode.Quarter:
      {
        newStartDate = addToDate(newStartDate, -1 * preStepsCount, "year");
        newStartDate = getFiscalQuarterStartDate(newStartDate, quarterStart);
        newEndDate = addToDate(newEndDate, 1, "year");
        var endQStart = getFiscalQuarterStartDate(newEndDate, quarterStart);
        newEndDate = endQStart < newEndDate ? addToDate(endQStart, 3, "month") : endQStart;
        break;
      }

    case ViewMode.Month:
      newStartDate = addToDate(newStartDate, -1 * preStepsCount, "month");
      newStartDate = startOfDate(newStartDate, "month");
      newEndDate = addToDate(newEndDate, 1, "year");
      newEndDate = startOfDate(newEndDate, "year");
      break;

    case ViewMode.Week:
      newStartDate = startOfDate(newStartDate, "day");
      newStartDate = addToDate(getMonday(newStartDate), -7 * preStepsCount, "day");
      newEndDate = startOfDate(newEndDate, "day");
      newEndDate = addToDate(newEndDate, 1.5, "month");
      break;

    case ViewMode.Day:
      newStartDate = startOfDate(newStartDate, "day");
      newStartDate = addToDate(newStartDate, -1 * preStepsCount, "day");
      newEndDate = startOfDate(newEndDate, "day");
      newEndDate = addToDate(newEndDate, 19, "day");
      break;

    case ViewMode.QuarterDay:
      newStartDate = startOfDate(newStartDate, "day");
      newStartDate = addToDate(newStartDate, -1 * preStepsCount, "day");
      newEndDate = startOfDate(newEndDate, "day");
      newEndDate = addToDate(newEndDate, 66, "hour");
      break;

    case ViewMode.HalfDay:
      newStartDate = startOfDate(newStartDate, "day");
      newStartDate = addToDate(newStartDate, -1 * preStepsCount, "day");
      newEndDate = startOfDate(newEndDate, "day");
      newEndDate = addToDate(newEndDate, 108, "hour");
      break;

    case ViewMode.Hour:
      newStartDate = startOfDate(newStartDate, "hour");
      newStartDate = addToDate(newStartDate, -1 * preStepsCount, "hour");
      newEndDate = startOfDate(newEndDate, "day");
      newEndDate = addToDate(newEndDate, 1, "day");
      break;
  }

  return [newStartDate, newEndDate];
};
var seedDates = function seedDates(startDate, endDate, viewMode) {
  var currentDate = new Date(startDate);
  var dates = [currentDate];

  while (currentDate < endDate) {
    switch (viewMode) {
      case ViewMode.Year:
        currentDate = addToDate(currentDate, 1, "year");
        break;

      case ViewMode.Quarter:
        currentDate = addToDate(currentDate, 3, "month");
        break;

      case ViewMode.Month:
        currentDate = addToDate(currentDate, 1, "month");
        break;

      case ViewMode.Week:
        currentDate = addToDate(currentDate, 7, "day");
        break;

      case ViewMode.Day:
        currentDate = addToDate(currentDate, 1, "day");
        break;

      case ViewMode.HalfDay:
        currentDate = addToDate(currentDate, 12, "hour");
        break;

      case ViewMode.QuarterDay:
        currentDate = addToDate(currentDate, 6, "hour");
        break;

      case ViewMode.Hour:
        currentDate = addToDate(currentDate, 1, "hour");
        break;
    }

    dates.push(currentDate);
  }

  return dates;
};
var getLocalDayOfWeek = function getLocalDayOfWeek(date, locale, format) {
  var bottomValue = getCachedDateTimeFormat(locale, {
    weekday: format
  }).format(date);
  bottomValue = bottomValue.replace(bottomValue[0], bottomValue[0].toLocaleUpperCase());
  return bottomValue;
};

var getMonday = function getMonday(date) {
  var day = date.getDay();
  var diff = date.getDate() - day + (day === 0 ? -6 : 1);
  return new Date(date.setDate(diff));
};

var styles = {"ganttTable":"_3_ygE","ganttTable_Header":"_1nBOt","ganttTable_HeaderSeparator":"_2eZzQ","ganttTable_HeaderResizeHandle":"_ddPJg","ganttTable_HeaderItem":"_WuQ0f","ganttTable_HeaderItemText":"_2X3fk"};

var TaskListHeaderDefault = function TaskListHeaderDefault(_ref) {
  var headerHeight = _ref.headerHeight,
      fontFamily = _ref.fontFamily,
      fontSize = _ref.fontSize,
      rowWidth = _ref.rowWidth,
      scheduleType = _ref.scheduleType,
      allSelected = _ref.allSelected,
      onSelectAll = _ref.onSelectAll,
      columnWidths = _ref.columnWidths,
      onColumnResize = _ref.onColumnResize;

  var widthOf = function widthOf(colId, factor) {
    var _columnWidths$colId;

    return (_columnWidths$colId = columnWidths === null || columnWidths === void 0 ? void 0 : columnWidths[colId]) != null ? _columnWidths$colId : parseInt(rowWidth) * factor;
  };

  var startResize = function startResize(colId, startWidth) {
    return function (e) {
      if (!onColumnResize) return;
      e.preventDefault();
      e.stopPropagation();
      var startX = e.clientX;

      var onMove = function onMove(ev) {
        onColumnResize(colId, startWidth + (ev.clientX - startX));
      };

      var onUp = function onUp() {
        document.removeEventListener("mousemove", onMove);
        document.removeEventListener("mouseup", onUp);
      };

      document.addEventListener("mousemove", onMove);
      document.addEventListener("mouseup", onUp);
    };
  };

  var cell = function cell(colId, factor, content, opts) {
    if (opts === void 0) {
      opts = {};
    }

    var _opts = opts,
        title = _opts.title,
        _opts$resizable = _opts.resizable,
        resizable = _opts$resizable === void 0 ? true : _opts$resizable;
    var width = widthOf(colId, factor);
    return React.createElement("div", {
      className: styles.ganttTable_HeaderItem,
      style: {
        minWidth: width,
        maxWidth: width,
        position: "relative"
      },
      title: title
    }, React.createElement("div", {
      className: styles.ganttTable_HeaderItemText
    }, content), resizable && onColumnResize && React.createElement("div", {
      className: styles.ganttTable_HeaderResizeHandle,
      style: {
        height: headerHeight - 2
      },
      onMouseDown: startResize(colId, width)
    }));
  };

  return React.createElement("div", {
    className: styles.ganttTable,
    style: {
      fontFamily: fontFamily,
      fontSize: fontSize
    }
  }, React.createElement("div", {
    className: styles.ganttTable_Header,
    style: {
      height: headerHeight - 2
    }
  }, onSelectAll && cell("select", 0.3, React.createElement("input", {
    type: "checkbox",
    checked: allSelected,
    onChange: function onChange(e) {
      return onSelectAll(e.target.checked);
    }
  }), {
    resizable: false
  }), cell("id", 0.8, "ID"), cell("wbs", 0.8, "WBS Code / Activity ID"), cell("name", 1.8, "Task"), cell("plannedStart", 0.6, "Planned Start", {
    title: "Planned Start"
  }), cell("plannedEnd", 0.6, "Planned End", {
    title: "Planned End"
  }), scheduleType === "lookAhead" && React.createElement(React.Fragment, null, cell("actualStart", 0.6, "Actual Start", {
    title: "Actual Start"
  }), cell("actualEnd", 0.6, "Actual End", {
    title: "Actual End"
  })), scheduleType === "main" && React.createElement(React.Fragment, null, cell("percentComplete", 0.6, "% Complete", {
    title: "% Complete"
  }), cell("plannedDuration", 0.6, "Planned Duration", {
    title: "Planned Duration"
  }), cell("remainingDuration", 0.7, "Remaining Duration", {
    title: "Remaining Duration"
  }), cell("actualDuration", 0.6, "Actual Duration", {
    title: "Actual Duration"
  }), cell("durationType", 0.8, "Duration Type", {
    title: "Duration Type"
  }))));
};

var styles$1 = {"taskListWrapper":"_3ZbQT","taskListTableRow":"_34SS0","taskListLookAheadRow":"_GzvG4","taskListMilestoneRow":"_3Ykml","taskListCell":"_3lLk3","taskListNameWrapper":"_nI1Xw","taskListExpander":"_2QjE6","taskListExpanderPlaceholder":"_1fnLB","taskListEmptyExpander":"_2TfEi","taskListText":"_2ZvXU"};

var localeDateStringCache = {};

var toLocaleDateStringFactory = function toLocaleDateStringFactory(locale) {
  return function (date, dateTimeOptions) {
    if (!date || date.getTime() === 0) return "";
    var key = date.toString();
    var lds = localeDateStringCache[key];

    if (!lds) {
      lds = date.toLocaleDateString(locale, dateTimeOptions);
      localeDateStringCache[key] = lds;
    }

    return lds;
  };
};

var dateTimeOptions = {
  year: "numeric",
  month: "numeric",
  day: "numeric"
};
var TaskListTableDefault = function TaskListTableDefault(_ref) {
  var rowHeight = _ref.rowHeight,
      rowWidth = _ref.rowWidth,
      tasks = _ref.tasks,
      scheduleType = _ref.scheduleType,
      leafTasks = _ref.leafTasks,
      fontFamily = _ref.fontFamily,
      fontSize = _ref.fontSize,
      locale = _ref.locale,
      onExpanderClick = _ref.onExpanderClick,
      _ref$selectedTasks = _ref.selectedTasks,
      selectedTasks = _ref$selectedTasks === void 0 ? [] : _ref$selectedTasks,
      onTaskSelect = _ref.onTaskSelect,
      _ref$taskLabelRendere = _ref.taskLabelRenderer,
      taskLabelRenderer = _ref$taskLabelRendere === void 0 ? function (t) {
    return " " + t.name;
  } : _ref$taskLabelRendere,
      virtualItems = _ref.virtualItems,
      columnWidths = _ref.columnWidths;

  var widthOf = function widthOf(colId, factor) {
    var _columnWidths$colId;

    return (_columnWidths$colId = columnWidths === null || columnWidths === void 0 ? void 0 : columnWidths[colId]) != null ? _columnWidths$colId : parseInt(rowWidth) * factor;
  };

  var toLocaleDateString = useMemo(function () {
    return toLocaleDateStringFactory(locale);
  }, [locale]);
  var leafTaskIds = useMemo(function () {
    return new Set(leafTasks.map(function (t) {
      return t.id;
    }));
  }, [leafTasks]);

  var hasSelectedAncestor = function hasSelectedAncestor(taskId, selectedSet, allTasks) {
    var task = allTasks.find(function (t) {
      return t.id === taskId;
    });
    if (!task) return false;
    var parentWbs = getParentWbs(task.id);
    if (!parentWbs) return false;
    if (selectedSet.has(parentWbs)) return true;
    return hasSelectedAncestor(parentWbs, selectedSet, allTasks);
  };

  var itemsToRender = virtualItems || tasks.map(function (_, index) {
    return {
      index: index,
      start: index * rowHeight,
      size: rowHeight,
      key: index,
      end: (index + 1) * rowHeight,
      lane: 0,
      measureElement: function measureElement() {}
    };
  });
  return React.createElement("div", {
    className: styles$1.taskListWrapper,
    style: {
      fontFamily: fontFamily,
      fontSize: fontSize
    }
  }, itemsToRender.map(function (vi) {
    var t = tasks[vi.index];
    var expanderSymbol = "";

    if (!(leafTaskIds.has(t.id) || t.type === "milestone")) {
      if (t.hideChildren === false) {
        expanderSymbol = "▼";
      } else if (t.hideChildren === true) {
        expanderSymbol = "►";
      }
    }

    var isSelected = selectedTasks.includes(t.id);
    var isAncestorSelected = hasSelectedAncestor(t.id, new Set(selectedTasks), tasks);
    return React.createElement("div", {
      key: "" + vi.key,
      "data-index": vi.index,
      style: {
        position: "absolute",
        top: 0,
        left: 0,
        width: "100%",
        height: vi.size + "px",
        transform: "translateY(" + vi.start + "px)"
      }
    }, React.createElement("div", {
      className: t.type === "milestone" ? styles$1.taskListMilestoneRow : scheduleType === "lookAhead" ? styles$1.taskListLookAheadRow : styles$1.taskListTableRow,
      style: {
        height: rowHeight
      },
      key: t.id + "row"
    }, onTaskSelect && React.createElement("div", {
      className: styles$1.taskListCell,
      style: {
        minWidth: widthOf("select", 0.3),
        maxWidth: widthOf("select", 0.3)
      }
    }, React.createElement("div", {
      className: styles$1.taskListText,
      style: {
        display: "flex",
        justifyContent: "center",
        alignItems: "center",
        height: "100%",
        paddingLeft: "0",
        paddingRight: "0"
      }
    }, React.createElement("input", {
      type: "checkbox",
      checked: isSelected,
      disabled: isAncestorSelected,
      onChange: function onChange(e) {
        return onTaskSelect(t.id, e.target.checked);
      }
    }))), React.createElement("div", {
      className: styles$1.taskListCell,
      style: {
        minWidth: widthOf("id", 0.8),
        maxWidth: widthOf("id", 0.8)
      },
      title: t.id
    }, React.createElement("div", {
      className: styles$1.taskListNameWrapper,
      style: {
        paddingLeft: t.depth * 4 + "px"
      }
    }, !(leafTaskIds.has(t.id) || t.type === "milestone") ? React.createElement("div", {
      className: styles$1.taskListExpander,
      onClick: function onClick() {
        return onExpanderClick(t);
      }
    }, expanderSymbol) : React.createElement("div", {
      className: styles$1.taskListExpanderPlaceholder
    }), React.createElement("div", {
      className: styles$1.taskListText
    }, t.id, " ", t.actualEnd.getTime() > 0 && t.actualEnd.getTime() < Date.now() ? React.createElement("span", {
      title: "Task Complete",
      style: {
        color: "limegreen",
        fontSize: "16px"
      }
    }, "\u2714") : ""))), React.createElement("div", {
      className: styles$1.taskListCell,
      style: {
        minWidth: widthOf("wbs", 0.8),
        maxWidth: widthOf("wbs", 0.8)
      },
      title: t.optionalId ? t.optionalId : ""
    }, t.optionalId), React.createElement("div", {
      className: styles$1.taskListCell,
      style: {
        minWidth: widthOf("name", 1.8),
        maxWidth: widthOf("name", 1.8)
      },
      title: t.name
    }, React.createElement("div", {
      className: styles$1.taskListText
    }, taskLabelRenderer(t))), React.createElement("div", {
      className: styles$1.taskListCell,
      style: {
        minWidth: widthOf("plannedStart", 0.6),
        maxWidth: widthOf("plannedStart", 0.6)
      }
    }, React.createElement("div", {
      className: styles$1.taskListText
    }, "\xA0", toLocaleDateString(t.start, dateTimeOptions))), React.createElement("div", {
      className: styles$1.taskListCell,
      style: {
        minWidth: widthOf("plannedEnd", 0.6),
        maxWidth: widthOf("plannedEnd", 0.6)
      }
    }, React.createElement("div", {
      className: styles$1.taskListText
    }, "\xA0", toLocaleDateString(t.end, dateTimeOptions))), scheduleType === "lookAhead" && React.createElement("div", {
      className: styles$1.taskListCell,
      style: {
        minWidth: widthOf("actualStart", 0.6),
        maxWidth: widthOf("actualStart", 0.6)
      }
    }, React.createElement("div", {
      className: styles$1.taskListText
    }, "\xA0", toLocaleDateString(t.actualStart, dateTimeOptions))), scheduleType === "lookAhead" && React.createElement("div", {
      className: styles$1.taskListCell,
      style: {
        minWidth: widthOf("actualEnd", 0.6),
        maxWidth: widthOf("actualEnd", 0.6)
      }
    }, React.createElement("div", {
      className: styles$1.taskListText
    }, "\xA0", toLocaleDateString(t.actualEnd, dateTimeOptions))), scheduleType === "main" && function () {
      var _t$progress, _t$durationType;

      var percentComplete = t.percentComplete != null ? t.percentComplete : (_t$progress = t.progress) != null ? _t$progress : 0;
      var plannedDuration = t.plannedDuration != null ? t.plannedDuration : null;
      var remainingDuration = plannedDuration != null ? Math.max(Math.round(plannedDuration - plannedDuration * (percentComplete / 100)), 0) : null;

      var actualDuration = function () {
        if (!t.actualStart || t.actualStart.getTime() === 0) return null;
        var endRef = t.actualEnd && t.actualEnd.getTime() > 0 ? t.actualEnd : new Date();
        return Math.ceil((endRef.getTime() - t.actualStart.getTime()) / (1000 * 60 * 60 * 24));
      }();

      return React.createElement(React.Fragment, null, React.createElement("div", {
        className: styles$1.taskListCell,
        style: {
          minWidth: widthOf("percentComplete", 0.6),
          maxWidth: widthOf("percentComplete", 0.6)
        }
      }, React.createElement("div", {
        className: styles$1.taskListText
      }, "\xA0", percentComplete != null ? percentComplete + "%" : "")), React.createElement("div", {
        className: styles$1.taskListCell,
        style: {
          minWidth: widthOf("plannedDuration", 0.6),
          maxWidth: widthOf("plannedDuration", 0.6)
        }
      }, React.createElement("div", {
        className: styles$1.taskListText
      }, "\xA0", plannedDuration != null ? plannedDuration : "")), React.createElement("div", {
        className: styles$1.taskListCell,
        style: {
          minWidth: widthOf("remainingDuration", 0.7),
          maxWidth: widthOf("remainingDuration", 0.7)
        }
      }, React.createElement("div", {
        className: styles$1.taskListText
      }, "\xA0", remainingDuration != null ? remainingDuration : "")), React.createElement("div", {
        className: styles$1.taskListCell,
        style: {
          minWidth: widthOf("actualDuration", 0.6),
          maxWidth: widthOf("actualDuration", 0.6)
        }
      }, React.createElement("div", {
        className: styles$1.taskListText
      }, "\xA0", actualDuration != null ? actualDuration : "")), React.createElement("div", {
        className: styles$1.taskListCell,
        style: {
          minWidth: widthOf("durationType", 0.8),
          maxWidth: widthOf("durationType", 0.8)
        }
      }, React.createElement("div", {
        className: styles$1.taskListText
      }, "\xA0", (_t$durationType = t.durationType) != null ? _t$durationType : "Activity Calendar")));
    }()));
  }));
};

var styles$2 = {"tooltipDefaultContainer":"_3T42e","tooltipDefaultContainerParagraph":"_29NTg","tooltipDetailsContainer":"_25P-K","tooltipDetailsContainerHidden":"_3gVAq"};

var Tooltip = function Tooltip(_ref) {
  var task = _ref.task,
      type = _ref.type,
      rowHeight = _ref.rowHeight,
      rtl = _ref.rtl,
      svgContainerHeight = _ref.svgContainerHeight,
      svgContainerWidth = _ref.svgContainerWidth,
      scrollX = _ref.scrollX,
      scrollY = _ref.scrollY,
      arrowIndent = _ref.arrowIndent,
      fontSize = _ref.fontSize,
      fontFamily = _ref.fontFamily,
      headerHeight = _ref.headerHeight,
      taskListWidth = _ref.taskListWidth,
      TooltipContent = _ref.TooltipContent,
      isDragging = _ref.isDragging;
  var tooltipRef = useRef(null);

  var _useState = useState(0),
      relatedY = _useState[0],
      setRelatedY = _useState[1];

  var _useState2 = useState(0),
      relatedX = _useState2[0],
      setRelatedX = _useState2[1];

  useEffect(function () {
    if (tooltipRef.current) {
      var tooltipHeight = tooltipRef.current.offsetHeight * 1.1;
      var tooltipWidth = tooltipRef.current.offsetWidth * 1.1;
      var newRelatedY = task.index * rowHeight - scrollY + headerHeight;
      var newRelatedX;

      if (isDragging) {
        newRelatedX = taskListWidth + svgContainerWidth - tooltipWidth - 10;
        newRelatedY = headerHeight + 5;
        setRelatedY(newRelatedY);
        setRelatedX(newRelatedX);
        return;
      }

      if (rtl) {
        newRelatedX = task.x1 - arrowIndent * 1.5 - tooltipWidth - scrollX;

        if (newRelatedX < 0) {
          newRelatedX = task.x2 + arrowIndent * 1.5 - scrollX;
        }

        var tooltipLeftmostPoint = tooltipWidth + newRelatedX;

        if (tooltipLeftmostPoint > svgContainerWidth) {
          newRelatedX = svgContainerWidth - tooltipWidth;
          newRelatedY += rowHeight;
        }
      } else {
        newRelatedX = type == "planned" ? task.x2 + arrowIndent * 1.5 + taskListWidth - scrollX : task.actualx2 + arrowIndent * 1.5 + taskListWidth - scrollX;

        var _tooltipLeftmostPoint = tooltipWidth + newRelatedX;

        var fullChartWidth = taskListWidth + svgContainerWidth;

        if (_tooltipLeftmostPoint > fullChartWidth) {
          newRelatedX = type == "planned" ? task.x1 + taskListWidth - arrowIndent * 1.5 - scrollX - tooltipWidth : task.actualx1 + taskListWidth - arrowIndent * 1.5 - scrollX - tooltipWidth;
        }

        if (newRelatedX < taskListWidth) {
          newRelatedX = svgContainerWidth + taskListWidth - tooltipWidth;
          newRelatedY += rowHeight;
        }
      }

      var tooltipLowerPoint = tooltipHeight + newRelatedY - scrollY;

      if (tooltipLowerPoint > svgContainerHeight - scrollY) {
        newRelatedY = svgContainerHeight - tooltipHeight;
      }

      setRelatedY(newRelatedY);
      setRelatedX(newRelatedX);
    }
  }, [tooltipRef, task, arrowIndent, scrollX, scrollY, headerHeight, taskListWidth, rowHeight, svgContainerHeight, svgContainerWidth, rtl, isDragging]);
  return React.createElement("div", {
    ref: tooltipRef,
    className: relatedX ? styles$2.tooltipDetailsContainer : styles$2.tooltipDetailsContainerHidden,
    style: {
      left: relatedX,
      top: relatedY
    }
  }, React.createElement(TooltipContent, {
    task: task,
    fontSize: fontSize,
    fontFamily: fontFamily,
    type: type
  }));
};
var StandardTooltipContent = function StandardTooltipContent(_ref2) {
  var _task$plannedDuration, _task$actualDuration;

  var task = _ref2.task,
      fontSize = _ref2.fontSize,
      fontFamily = _ref2.fontFamily,
      type = _ref2.type;
  var style = {
    fontSize: fontSize,
    fontFamily: fontFamily
  };
  var computedPlannedDuration = task.start && task.end && task.end.getTime() - task.start.getTime() > 0 ? Math.max(1, Math.round((task.end.getTime() - task.start.getTime()) / (1000 * 60 * 60 * 24))) : (_task$plannedDuration = task.plannedDuration) != null ? _task$plannedDuration : 0;
  var computedActualDuration = task.actualStart && task.actualEnd && task.actualEnd.getTime() - task.actualStart.getTime() > 0 ? Math.max(1, Math.round((task.actualEnd.getTime() - task.actualStart.getTime()) / (1000 * 60 * 60 * 24))) : (_task$actualDuration = task.actualDuration) != null ? _task$actualDuration : 0;
  if (type == "planned") return React.createElement("div", {
    className: styles$2.tooltipDefaultContainer,
    style: style
  }, React.createElement("b", {
    style: {
      fontSize: fontSize + 6
    }
  }, task.name + ": Planned dates: "), React.createElement("b", null, task.start.getMonth() + 1 + "/" + task.start.getDate() + "/" + task.start.getFullYear() + " - " + (task.end.getMonth() + 1) + "/" + task.end.getDate() + "/" + task.end.getFullYear()), task.end.getTime() - task.start.getTime() !== 0 && React.createElement("p", {
    className: styles$2.tooltipDefaultContainerParagraph
  }, "Duration: " + computedPlannedDuration + " day(s)"), React.createElement("p", {
    className: styles$2.tooltipDefaultContainerParagraph
  }, !!task.progress && "Progress: " + task.progress + " %"));else return React.createElement("div", {
    className: styles$2.tooltipDefaultContainer,
    style: style
  }, React.createElement("b", {
    style: {
      fontSize: fontSize + 6
    }
  }, task.name + ": Actual dates: "), React.createElement("b", null, task.actualStart.getMonth() + 1 + "/" + task.actualStart.getDate() + "/" + task.actualStart.getFullYear() + " - " + (task.actualEnd.getMonth() + 1) + "/" + task.actualEnd.getDate() + "/" + task.actualEnd.getFullYear()), task.actualEnd.getTime() - task.actualStart.getTime() !== 0 && React.createElement("p", {
    className: styles$2.tooltipDefaultContainerParagraph
  }, "Duration: " + computedActualDuration + " day(s)"), React.createElement("p", {
    className: styles$2.tooltipDefaultContainerParagraph
  }, !!task.progress && "Progress: " + task.progress + " %"));
};

var styles$3 = {"scroll":"_1eT-t"};

var VerticalScroll = function VerticalScroll(_ref) {
  var scroll = _ref.scroll,
      ganttHeight = _ref.ganttHeight,
      ganttFullHeight = _ref.ganttFullHeight,
      headerHeight = _ref.headerHeight,
      rtl = _ref.rtl,
      onScroll = _ref.onScroll;
  var scrollRef = useRef(null);
  useEffect(function () {
    if (scrollRef.current) {
      scrollRef.current.scrollTop = scroll;
    }
  }, [scroll]);
  return React.createElement("div", {
    style: {
      height: ganttHeight,
      marginTop: headerHeight,
      marginLeft: rtl ? "" : "-1rem",
      marginRight: "1rem"
    },
    className: styles$3.scroll,
    onScroll: onScroll,
    ref: scrollRef
  }, React.createElement("div", {
    style: {
      height: ganttFullHeight,
      width: 1
    }
  }));
};

function getTaskListColumns(scheduleType, hasCheckbox) {
  const columns = [];
  if (hasCheckbox) columns.push({
    id: "select",
    factor: 0.3
  });
  columns.push({
    id: "id",
    factor: 0.8
  }, {
    id: "wbs",
    factor: 0.8
  }, {
    id: "name",
    factor: 1.8
  }, {
    id: "plannedStart",
    factor: 0.6
  }, {
    id: "plannedEnd",
    factor: 0.6
  });

  if (scheduleType === "lookAhead") {
    columns.push({
      id: "actualStart",
      factor: 0.6
    }, {
      id: "actualEnd",
      factor: 0.6
    });
  }

  if (scheduleType === "main") {
    columns.push({
      id: "percentComplete",
      factor: 0.6
    }, {
      id: "plannedDuration",
      factor: 0.6
    }, {
      id: "remainingDuration",
      factor: 0.7
    }, {
      id: "actualDuration",
      factor: 0.6
    }, {
      id: "durationType",
      factor: 0.8
    });
  }

  return columns;
}
const MIN_COLUMN_WIDTH = 40;
function buildDefaultColumnWidths(scheduleType, hasCheckbox, rowWidth) {
  const base = parseInt(rowWidth) || 0;
  const widths = {};

  for (const col of getTaskListColumns(scheduleType, hasCheckbox)) {
    widths[col.id] = base * col.factor;
  }

  return widths;
}

var styles$4 = {"hideScrollbar":"_38emS"};

var TaskList = function TaskList(_ref) {
  var headerHeight = _ref.headerHeight,
      fontFamily = _ref.fontFamily,
      fontSize = _ref.fontSize,
      rowWidth = _ref.rowWidth,
      rowHeight = _ref.rowHeight,
      scrollY = _ref.scrollY,
      tasks = _ref.tasks,
      scheduleType = _ref.scheduleType,
      leafTasks = _ref.leafTasks,
      selectedTask = _ref.selectedTask,
      setSelectedTask = _ref.setSelectedTask,
      onExpanderClick = _ref.onExpanderClick,
      locale = _ref.locale,
      ganttHeight = _ref.ganttHeight,
      taskListRef = _ref.taskListRef,
      horizontalContainerClass = _ref.horizontalContainerClass,
      TaskListHeader = _ref.TaskListHeader,
      TaskListTable = _ref.TaskListTable,
      taskLabelRenderer = _ref.taskLabelRenderer,
      onMultiSelect = _ref.onMultiSelect,
      containerWidth = _ref.containerWidth,
      containerMaxWidth = _ref.containerMaxWidth,
      onContentWidthChange = _ref.onContentWidthChange,
      innerScrollRef = _ref.innerScrollRef,
      externalHorizontalContainerRef = _ref.horizontalContainerRef;
  var internalHorizontalContainerRef = useRef(null);
  var horizontalContainerRef = externalHorizontalContainerRef != null ? externalHorizontalContainerRef : internalHorizontalContainerRef;
  var headerScrollRef = useRef(null);
  useEffect(function () {
    var rowsEl = horizontalContainerRef.current;
    if (!rowsEl) return;

    var onScroll = function onScroll() {
      if (headerScrollRef.current) {
        headerScrollRef.current.scrollLeft = rowsEl.scrollLeft;
      }
    };

    rowsEl.addEventListener("scroll", onScroll);
    return function () {
      return rowsEl.removeEventListener("scroll", onScroll);
    };
  }, [horizontalContainerRef]);

  var _useState = useState([]),
      selectedTasks = _useState[0],
      setSelectedTasks = _useState[1];

  var hasCheckbox = !!onMultiSelect;

  var _useState2 = useState(function () {
    return buildDefaultColumnWidths(scheduleType, hasCheckbox, rowWidth);
  }),
      columnWidths = _useState2[0],
      setColumnWidths = _useState2[1];

  useEffect(function () {
    var defaults = buildDefaultColumnWidths(scheduleType, hasCheckbox, rowWidth);
    setColumnWidths(function (prev) {
      var ids = Object.keys(defaults);
      var sameSet = ids.length === Object.keys(prev).length && ids.every(function (id) {
        return id in prev;
      });
      if (sameSet) return prev;
      var next = {};

      for (var _i = 0, _ids = ids; _i < _ids.length; _i++) {
        var _prev$id;

        var id = _ids[_i];
        next[id] = (_prev$id = prev[id]) != null ? _prev$id : defaults[id];
      }

      return next;
    });
  }, [scheduleType, hasCheckbox, rowWidth]);

  var handleColumnResize = function handleColumnResize(colId, width) {
    setColumnWidths(function (prev) {
      var _extends2;

      return _extends({}, prev, (_extends2 = {}, _extends2[colId] = Math.max(MIN_COLUMN_WIDTH, width), _extends2));
    });
  };

  var contentWidth = useMemo(function () {
    return Object.values(columnWidths).reduce(function (sum, w) {
      return sum + w;
    }, 0);
  }, [columnWidths]);
  useEffect(function () {
    onContentWidthChange === null || onContentWidthChange === void 0 ? void 0 : onContentWidthChange(contentWidth);
  }, [contentWidth, onContentWidthChange]);
  var taskIdsKey = useMemo(function () {
    return tasks.map(function (t) {
      return t.id;
    }).join("|");
  }, [tasks]);
  var selectedTaskIds = useMemo(function () {
    return new Set(selectedTasks);
  }, [selectedTasks]);

  var _useState3 = useState([]),
      pendingTaskSelect = _useState3[0],
      setPendingTaskSelect = _useState3[1];

  var prevSelectedTasksRef = useRef([]);
  var expandedTasks = useRef([]);
  var virtualizer = useVirtualizer({
    count: tasks.length,
    getScrollElement: function getScrollElement() {
      return horizontalContainerRef.current;
    },
    estimateSize: function estimateSize() {
      return rowHeight;
    },
    overscan: 10
  });
  useEffect(function () {
    if (horizontalContainerRef.current) {
      horizontalContainerRef.current.scrollTop = scrollY;
    }
  }, [scrollY]);
  useEffect(function () {
    if (onMultiSelect && JSON.stringify(prevSelectedTasksRef.current) !== JSON.stringify(selectedTasks)) {
      var selectedTaskObjects = tasks.filter(function (task) {
        return selectedTasks.includes(task.id);
      });
      prevSelectedTasksRef.current = [].concat(selectedTasks);
      onMultiSelect(selectedTaskObjects);
    }
  }, [selectedTasks, tasks, onMultiSelect]);
  useEffect(function () {
    if (pendingTaskSelect.length === 0) return;
    var newSelected = new Set(selectedTasks);
    pendingTaskSelect.forEach(function (_ref2) {
      var taskId = _ref2.taskId,
          selected = _ref2.selected;

      if (selected) {
        recursiveOpen(taskId, tasks);
        var descendants = getDescendants(taskId, tasks);
        newSelected.add(taskId);
        descendants.forEach(function (d) {
          return newSelected.add(d);
        });
      } else {
        var _descendants = getDescendants(taskId, tasks);

        newSelected.delete(taskId);

        _descendants.forEach(function (d) {
          return newSelected.delete(d);
        });
      }
    });
    setSelectedTasks(Array.from(newSelected));
    setPendingTaskSelect([]);
  }, [pendingTaskSelect]);
  useEffect(function () {
    expandedTasks.current = expandedTasks.current.filter(function (id) {
      var t = tasks.find(function (task) {
        return task.id === id;
      });
      return t && !t.hideChildren;
    });
    if (selectedTasks.length === 0) return;
    var newSelected = new Set();
    selectedTasks.forEach(function (taskId) {
      if (tasks.find(function (t) {
        return t.id === taskId;
      })) {
        recursiveOpen(taskId, tasks);
        newSelected.add(taskId);
        var descendants = getDescendants(taskId, tasks);
        descendants.forEach(function (d) {
          return newSelected.add(d);
        });
      }
    });
    var newSelectedArray = Array.from(newSelected);

    if (JSON.stringify(newSelectedArray) !== JSON.stringify(selectedTasks)) {
      setSelectedTasks(newSelectedArray);
    }
  }, [taskIdsKey]);

  var getDescendants = function getDescendants(taskId, allTasks) {
    var task = allTasks.find(function (t) {
      return t.id === taskId;
    });
    if (!task) return [];
    var children = allTasks.filter(function (t) {
      return getParentWbs(t.id) === taskId;
    });
    return children.flatMap(function (child) {
      return [child.id].concat(getDescendants(child.id, allTasks));
    });
  };

  var recursiveOpen = function recursiveOpen(taskId, allTasks) {
    var task = allTasks.find(function (t) {
      return t.id === taskId;
    });
    if (!task) return;

    if (!expandedTasks.current.includes(taskId) && task.hideChildren) {
      onExpanderClick(task);
      expandedTasks.current = [].concat(expandedTasks.current, [taskId]);
    }

    var children = allTasks.filter(function (t) {
      return getParentWbs(t.id) === taskId;
    });
    children.forEach(function (c) {
      return recursiveOpen(c.id, allTasks);
    });
  };

  var handleTaskSelect = function handleTaskSelect(taskId, selected) {
    setPendingTaskSelect(function (prev) {
      return [].concat(prev, [{
        taskId: taskId,
        selected: selected
      }]);
    });
  };

  var handleSelectAll = function handleSelectAll(selected) {
    if (selected) {
      setSelectedTasks(tasks.map(function (task) {
        return task.id;
      }));
      setPendingTaskSelect([]);
    } else {
      setSelectedTasks([]);
      setPendingTaskSelect([]);
    }
  };

  var headerProps = {
    headerHeight: headerHeight,
    fontFamily: fontFamily,
    fontSize: fontSize,
    rowWidth: rowWidth,
    scheduleType: scheduleType,
    allSelected: tasks.length > 0 && tasks.every(function (t) {
      return selectedTaskIds.has(t.id);
    }),
    onSelectAll: onMultiSelect ? handleSelectAll : undefined,
    columnWidths: columnWidths,
    onColumnResize: handleColumnResize
  };
  var selectedTaskId = selectedTask ? selectedTask.id : "";
  var tableProps = {
    rowHeight: rowHeight,
    rowWidth: rowWidth,
    fontFamily: fontFamily,
    fontSize: fontSize,
    tasks: tasks,
    leafTasks: leafTasks,
    scheduleType: scheduleType,
    locale: locale,
    selectedTaskId: selectedTaskId,
    setSelectedTask: setSelectedTask,
    onExpanderClick: onExpanderClick,
    selectedTasks: onMultiSelect ? selectedTasks : undefined,
    onTaskSelect: onMultiSelect ? handleTaskSelect : undefined,
    taskLabelRenderer: taskLabelRenderer,
    virtualItems: virtualizer.getVirtualItems(),
    columnWidths: columnWidths
  };
  return React.createElement("div", {
    ref: taskListRef,
    style: containerWidth != null || containerMaxWidth != null ? _extends({}, containerWidth != null ? {
      width: containerWidth
    } : {}, containerMaxWidth != null ? {
      maxWidth: containerMaxWidth
    } : {}, {
      overflow: "hidden",
      flexShrink: 0
    }) : {}
  }, React.createElement("div", {
    ref: innerScrollRef,
    className: styles$4.hideScrollbar,
    style: {
      overflowX: "hidden"
    }
  }, React.createElement("div", {
    ref: headerScrollRef,
    style: {
      overflow: "hidden"
    }
  }, React.createElement(TaskListHeader, Object.assign({}, headerProps))), React.createElement("div", {
    ref: horizontalContainerRef,
    className: horizontalContainerClass,
    style: ganttHeight ? {
      height: ganttHeight
    } : {}
  }, React.createElement("div", {
    style: {
      height: virtualizer.getTotalSize() + "px",
      width: "100%",
      position: "relative"
    }
  }, React.createElement(TaskListTable, Object.assign({}, tableProps))))));
};

function parseTimeToMinutes(t) {
  const parts = t.split(":").map(Number);
  return parts[0] * 60 + parts[1] + (parts[2] ? parts[2] / 60 : 0);
}

function toDateString(date) {
  const y = date.getFullYear();
  const m = String(date.getMonth() + 1).padStart(2, "0");
  const d = String(date.getDate()).padStart(2, "0");
  return `${y}-${m}-${d}`;
}

function isHoliday(date, cal) {
  if (cal.holidays && cal.holidays.length > 0) {
    return cal.holidays.includes(toDateString(date));
  } else {
    return false;
  }
}
function isOffDay(date, cal) {
  if (cal.off_days && cal.off_days.length > 0) {
    return cal.off_days.includes(date.getDay()) || isHoliday(date, cal);
  } else {
    return false;
  }
}
function getShiftsForDay(date, cal) {
  if (isOffDay(date, cal) || !cal.shifts) return [];
  return cal.shifts.map(_ref => {
    let [s, e] = _ref;
    return {
      start: parseTimeToMinutes(s),
      end: parseTimeToMinutes(e)
    };
  });
}
function getWorkingIntervals(start, end, cal) {
  if (start >= end) return [];
  const intervals = [];
  const cursor = new Date(start);
  cursor.setHours(0, 0, 0, 0);

  while (cursor <= end) {
    const shifts = getShiftsForDay(cursor, cal);

    for (const shift of shifts) {
      const shiftStart = new Date(cursor);
      shiftStart.setHours(Math.floor(shift.start / 60), Math.floor(shift.start % 60), Math.round(shift.start % 1 * 60), 0);
      const shiftEnd = new Date(cursor);
      shiftEnd.setHours(Math.floor(shift.end / 60), Math.floor(shift.end % 60), Math.round(shift.end % 1 * 60), 0);
      const intervalStart = shiftStart < start ? start : shiftStart;
      const intervalEnd = shiftEnd > end ? end : shiftEnd;

      if (intervalStart < intervalEnd) {
        intervals.push({
          start: intervalStart,
          end: intervalEnd
        });
      }
    }

    cursor.setDate(cursor.getDate() + 1);
  }

  return intervals;
}
function snapToWorkingTime(date, cal, direction) {
  const MAX_DAYS = 60;
  const result = new Date(date);

  for (let attempt = 0; attempt < MAX_DAYS * 24 * 60; attempt++) {
    const dayStart = new Date(result);
    dayStart.setHours(0, 0, 0, 0);
    const shifts = getShiftsForDay(dayStart, cal);

    if (shifts.length > 0) {
      if (direction === "forward") {
        const currentMins = result.getHours() * 60 + result.getMinutes() + result.getSeconds() / 60;

        for (const shift of shifts) {
          if (currentMins <= shift.end) {
            if (currentMins < shift.start) {
              result.setHours(Math.floor(shift.start / 60), Math.round(shift.start % 60), 0, 0);
            }

            return result;
          }
        }

        result.setDate(result.getDate() + 1);
        result.setHours(0, 0, 0, 0);
      } else {
        const currentMins = result.getHours() * 60 + result.getMinutes() + result.getSeconds() / 60;

        for (let i = shifts.length - 1; i >= 0; i--) {
          if (currentMins >= shifts[i].start) {
            if (currentMins > shifts[i].end) {
              result.setHours(Math.floor(shifts[i].end / 60), Math.round(shifts[i].end % 60), 0, 0);
            }

            return result;
          }
        }

        result.setDate(result.getDate() - 1);
        result.setHours(23, 59, 59, 0);
      }
    } else {
      if (direction === "forward") {
        result.setDate(result.getDate() + 1);
        result.setHours(0, 0, 0, 0);
      } else {
        result.setDate(result.getDate() - 1);
        result.setHours(23, 59, 59, 0);
      }
    }
  }

  return date;
}
function getQuarterNumber(date, quarterStart) {
  const month = date.getMonth();
  const offset = (month - quarterStart + 12) % 12;
  return Math.floor(offset / 3) + 1;
}

var styles$5 = {"gridRow":"_2dZTy","gridRowLookAhead":"_2RRca","gridRowLine":"_3rUKi","gridTick":"_RuwuK","gridTickWeekStart":"_1q0EV","gridTickDashed":"_Zh9jh","darkerGridRow":"_2M-tt"};

const GridBody = _ref => {
  let {
    tasks,
    scheduleType,
    dates,
    rowHeight,
    svgWidth,
    columnWidth,
    todayColor,
    weekendColor,
    rtl,
    virtualItems = [],
    visibleStartY,
    visibleEndY,
    projectCalendar,
    viewMode
  } = _ref;
  const visibleHeight = visibleEndY - visibleStartY;
  const now = new Date();
  const items = virtualItems.length > 0 ? virtualItems : tasks.map((_, i) => ({
    index: i,
    start: i * rowHeight,
    end: (i + 1) * rowHeight,
    size: rowHeight,
    key: i
  }));

  const isDayOff = date => {
    if (projectCalendar) return isOffDay(date, projectCalendar);
    const d = date.getDay();
    return d === 0 || d === 6;
  };

  const isTodayColumn = i => {
    const date = dates[i];
    const next = dates[i + 1];
    if (next && date <= now && next > now) return true;

    if (!next && date <= now) {
      const prev = dates[i - 1];
      const step = prev ? date.getTime() - prev.getTime() : 86400000;
      const end = addToDate(date, step, "millisecond");
      return end > now;
    }

    return false;
  };

  const todayRects = [];
  const offDayRects = [];
  const weekStartDay = (projectCalendar === null || projectCalendar === void 0 ? void 0 : projectCalendar.week_start) ?? 1;

  for (let i = 0, x = 0; i < dates.length; i++, x += columnWidth) {
    if (isTodayColumn(i)) {
      todayRects.push(React.createElement("rect", {
        key: `today-${i}`,
        x: rtl ? x + columnWidth : x,
        y: visibleStartY,
        width: columnWidth,
        height: visibleHeight,
        fill: todayColor
      }));
    }

    if (viewMode !== ViewMode.Month && viewMode !== ViewMode.Quarter) {
      const pEnd = dates[i + 1] ?? addToDate(dates[i], 1, "day");
      const periodMs = pEnd.getTime() - dates[i].getTime();

      if (periodMs > 0) {
        const cursor = new Date(dates[i]);
        cursor.setHours(0, 0, 0, 0);

        while (cursor.getTime() < pEnd.getTime()) {
          if (isDayOff(cursor)) {
            const ds = cursor.getTime() - dates[i].getTime();
            const de = ds + 86400000;
            const startFrac = Math.max(0, ds) / periodMs;
            const endFrac = Math.min(periodMs, de) / periodMs;
            const rw = (endFrac - startFrac) * columnWidth;

            if (rw > 0.5) {
              offDayRects.push(React.createElement("rect", {
                key: `offday-${i}-${cursor.getTime()}`,
                x: x + startFrac * columnWidth,
                y: visibleStartY,
                width: rw,
                height: visibleHeight,
                fill: weekendColor
              }));
            }
          }

          cursor.setDate(cursor.getDate() + 1);
        }
      }
    }
  }

  const isDayView = viewMode === ViewMode.Day;
  const isWeekView = viewMode === ViewMode.Week;
  const tickLines = dates.map((date, i) => {
    let tickClass = styles$5.gridTick;

    if (isDayView) {
      tickClass = date.getDay() === weekStartDay ? styles$5.gridTickWeekStart : styles$5.gridTickDashed;
    } else if (isWeekView) {
      tickClass = styles$5.gridTickWeekStart;
    }

    return React.createElement("line", {
      key: `tick-${i}`,
      x1: i * columnWidth,
      y1: visibleStartY,
      x2: i * columnWidth,
      y2: visibleEndY,
      className: tickClass
    });
  });
  const rowBackgrounds = [];
  const rowLines = [];
  const rowOverlays = [];
  rowLines.push(React.createElement("line", {
    key: "top-line",
    x1: 0,
    y1: visibleStartY,
    x2: svgWidth,
    y2: visibleStartY,
    className: styles$5.gridRowLine
  }));
  const showPerRowOffDays = viewMode !== ViewMode.Month && viewMode !== ViewMode.Quarter;

  for (const vi of items) {
    const task = tasks[vi.index];
    if (!task) break;
    const y = vi.start;
    const isMilestone = task.type === "milestone";
    const rowClass = isMilestone ? styles$5.darkerGridRow : scheduleType === "lookAhead" ? styles$5.gridRowLookAhead : styles$5.gridRow;
    rowBackgrounds.push(React.createElement("rect", {
      key: `bg-${vi.key}`,
      x: 0,
      y: y,
      width: svgWidth,
      height: rowHeight,
      className: rowClass
    }));
    rowLines.push(React.createElement("line", {
      key: `line-${vi.key}`,
      x1: 0,
      y1: y + rowHeight,
      x2: svgWidth,
      y2: y + rowHeight,
      className: styles$5.gridRowLine
    }));

    if (showPerRowOffDays) {
      const rowEven = vi.index % 2 === 1;
      const rowFill = isMilestone ? "#e6e4e4" : scheduleType === "lookAhead" ? "#fff" : rowEven ? "#f5f5f5" : "#fff";
      rowOverlays.push(React.createElement("rect", {
        key: `row-clean-${vi.key}`,
        x: 0,
        y: y,
        width: svgWidth,
        height: rowHeight,
        fill: rowFill
      }));
      const cal = task.calendar;

      if (cal) {
        for (let i = 0, x = 0; i < dates.length; i++, x += columnWidth) {
          const pEnd = dates[i + 1] ?? addToDate(dates[i], 1, "day");
          const periodMs = pEnd.getTime() - dates[i].getTime();
          if (periodMs <= 0) continue;
          const cursor = new Date(dates[i]);
          cursor.setHours(0, 0, 0, 0);

          while (cursor.getTime() < pEnd.getTime()) {
            if (isOffDay(cursor, cal)) {
              const ds = cursor.getTime() - dates[i].getTime();
              const de = ds + 86400000;
              const startFrac = Math.max(0, ds) / periodMs;
              const endFrac = Math.min(periodMs, de) / periodMs;
              const rw = (endFrac - startFrac) * columnWidth;

              if (rw > 0.5) {
                rowOverlays.push(React.createElement("rect", {
                  key: `row-offday-${vi.key}-${cursor.getTime()}`,
                  x: rtl ? x + columnWidth - (startFrac * columnWidth + rw) : x + startFrac * columnWidth,
                  y: y,
                  width: rw,
                  height: rowHeight,
                  fill: weekendColor
                }));
              }
            }

            cursor.setDate(cursor.getDate() + 1);
          }
        }
      }
    }
  }

  return React.createElement("g", {
    className: "gridBody"
  }, React.createElement("g", {
    className: "rows"
  }, rowBackgrounds), React.createElement("g", {
    className: "rowLines"
  }, rowLines), React.createElement("g", {
    className: "offdays"
  }, offDayRects), React.createElement("g", {
    className: "rowOverlays"
  }, rowOverlays), React.createElement("g", {
    className: "ticks"
  }, tickLines), React.createElement("g", {
    className: "today"
  }, todayRects));
};

const Grid = props => {
  return React.createElement("g", {
    className: "grid"
  }, React.createElement(GridBody, Object.assign({}, props)));
};

var styles$6 = {"calendarBottomText":"_9w8d5","calendarTopTick":"_1rLuZ","calendarTickSolid":"_2X-yN","calendarTickDashed":"_2BaXZ","calendarOffDayHeader":"_24p-y","calendarTopText":"_2q1Kt","calendarHeader":"_35nLX","textAnchorStart":"_2Shd-","textAnchorMiddle":"_2XXW4","textAnchorEnd":"_3GdnC"};

const TopPartOfCalendar = _ref => {
  let {
    value,
    x1Line,
    y1Line,
    y2Line,
    xText,
    yText,
    textAnchor = "middle"
  } = _ref;
  const textAnchorClass = textAnchor === "start" ? styles$6.textAnchorStart : textAnchor === "middle" ? styles$6.textAnchorMiddle : styles$6.textAnchorEnd;
  return React.createElement("g", {
    className: "calendarTop"
  }, React.createElement("line", {
    x1: x1Line,
    y1: y1Line,
    x2: x1Line,
    y2: y2Line,
    className: styles$6.calendarTopTick,
    key: value + "line"
  }), React.createElement("text", {
    key: value + "text",
    y: yText,
    x: xText,
    className: `${styles$6.calendarTopText} ${textAnchorClass}`
  }, value));
};

const Calendar = _ref => {
  let {
    dateSetup,
    locale,
    viewMode,
    rtl,
    headerHeight,
    columnWidth,
    fontFamily,
    fontSize,
    projectCalendar,
    weekendColor
  } = _ref;

  const isDayOff = date => {
    if (projectCalendar) return isOffDay(date, projectCalendar);
    return false;
  };

  const shortMonth = date => date.toLocaleString(locale, {
    month: "short"
  });

  const getCalendarValuesForYear = () => {
    const topValues = [];
    const bottomValues = [];
    const topDefaultHeight = headerHeight * 0.5;

    for (let i = 0; i < dateSetup.dates.length; i++) {
      const date = dateSetup.dates[i];
      const bottomValue = date.getFullYear();
      bottomValues.push(React.createElement("text", {
        key: date.getFullYear(),
        y: headerHeight * 0.8,
        x: columnWidth * i + columnWidth * 0.5,
        className: styles$6.calendarBottomText
      }, bottomValue));

      if (i === 0 || date.getFullYear() !== dateSetup.dates[i - 1].getFullYear()) {
        const topValue = date.getFullYear().toString();
        let xText;

        if (rtl) {
          xText = (6 + i + date.getFullYear() + 1) * columnWidth;
        } else {
          xText = (6 + i - date.getFullYear()) * columnWidth;
        }

        topValues.push(React.createElement(TopPartOfCalendar, {
          key: topValue,
          value: topValue,
          x1Line: columnWidth * i,
          y1Line: 0,
          y2Line: headerHeight,
          xText: xText,
          yText: topDefaultHeight * 0.9
        }));
      }
    }

    return [topValues, bottomValues];
  };

  const getCalendarValuesForQuarter = () => {
    const topValues = [];
    const bottomValues = [];
    const offDayRects = [];
    const quarterStart = (projectCalendar === null || projectCalendar === void 0 ? void 0 : projectCalendar.quarter_start) ?? 0;
    const rowH = headerHeight / 3;

    for (let i = 0; i < dateSetup.dates.length; i++) {
      const date = dateSetup.dates[i];
      const qNum = getQuarterNumber(date, quarterStart);

      for (let m = 0; m < 3; m++) {
        const monthDate = addToDate(date, m, "month");
        bottomValues.push(React.createElement("text", {
          key: `qmonth-${i}-${m}`,
          y: headerHeight * 0.9,
          x: columnWidth * i + columnWidth * (m * 2 + 1) / 6,
          className: `${styles$6.calendarTopText} ${styles$6.textAnchorMiddle}`
        }, shortMonth(monthDate)));
      }

      bottomValues.push(React.createElement("text", {
        key: `qlabel-${i}`,
        y: rowH * 1.6,
        x: columnWidth * i + columnWidth * 0.5,
        className: `${styles$6.calendarTopText} ${styles$6.textAnchorMiddle}`
      }, `Qtr ${qNum}`));
      bottomValues.push(React.createElement("line", {
        key: `qsep-${i}`,
        x1: columnWidth * i,
        y1: rowH,
        x2: columnWidth * i,
        y2: headerHeight,
        className: styles$6.calendarTopTick
      }));

      if (i === 0) {
        bottomValues.push(React.createElement("line", {
          key: "qhsep1",
          x1: 0,
          y1: rowH,
          x2: columnWidth * dateSetup.dates.length,
          y2: rowH,
          className: styles$6.calendarTopTick
        }));
        bottomValues.push(React.createElement("line", {
          key: "qhsep2",
          x1: 0,
          y1: rowH * 2,
          x2: columnWidth * dateSetup.dates.length,
          y2: rowH * 2,
          className: styles$6.calendarTopTick
        }));
      }

      if (i === 0 || date.getFullYear() !== dateSetup.dates[i - 1].getFullYear()) {
        const topValue = date.getFullYear().toString();
        let span = 0;

        for (let j = i; j < dateSetup.dates.length && dateSetup.dates[j].getFullYear() === date.getFullYear(); j++) {
          span++;
        }

        const xText = columnWidth * i + columnWidth * span / 2;
        topValues.push(React.createElement(TopPartOfCalendar, {
          key: topValue + i,
          value: topValue,
          x1Line: columnWidth * i,
          y1Line: 0,
          y2Line: rowH,
          xText: xText,
          yText: rowH * 0.7,
          textAnchor: "middle"
        }));
      }
    }

    return [topValues, bottomValues, offDayRects];
  };

  const getCalendarValuesForMonth = () => {
    const topValues = [];
    const bottomValues = [];
    const offDayRects = [];
    const topDefaultHeight = headerHeight * 0.5;
    const quarterStart = (projectCalendar === null || projectCalendar === void 0 ? void 0 : projectCalendar.quarter_start) ?? 0;

    for (let i = 0; i < dateSetup.dates.length; i++) {
      const date = dateSetup.dates[i];
      const bottomValue = shortMonth(date);
      bottomValues.push(React.createElement("text", {
        key: bottomValue + date.getFullYear() + i,
        y: headerHeight * 0.8,
        x: columnWidth * i + columnWidth * 0.5,
        className: `${styles$6.calendarTopText} ${styles$6.textAnchorMiddle}`
      }, bottomValue));
      const qNum = getQuarterNumber(date, quarterStart);
      const prevDate = i > 0 ? dateSetup.dates[i - 1] : null;
      const prevQNum = prevDate ? getQuarterNumber(prevDate, quarterStart) : -1;
      const isNewQuarter = i === 0 || qNum !== prevQNum || date.getFullYear() !== (prevDate ? prevDate.getFullYear() : -1);

      if (isNewQuarter) {
        const topValue = `Qtr ${qNum}, ${date.getFullYear()}`;
        let span = 0;

        for (let j = i; j < dateSetup.dates.length && getQuarterNumber(dateSetup.dates[j], quarterStart) === qNum && dateSetup.dates[j].getFullYear() === date.getFullYear(); j++) {
          span++;
        }

        const xText = rtl ? columnWidth * i + columnWidth * span * 0.5 + columnWidth : columnWidth * i + columnWidth * span / 2;
        topValues.push(React.createElement(TopPartOfCalendar, {
          key: topValue + i,
          value: topValue,
          x1Line: columnWidth * i,
          y1Line: 0,
          y2Line: topDefaultHeight,
          xText: xText,
          yText: topDefaultHeight * 0.7,
          textAnchor: "middle"
        }));

        if (i > 0) {
          bottomValues.push(React.createElement("line", {
            key: `qbound-${i}`,
            x1: columnWidth * i,
            y1: topDefaultHeight,
            x2: columnWidth * i,
            y2: headerHeight,
            className: styles$6.calendarTopTick
          }));
        }
      }
    }

    return [topValues, bottomValues, offDayRects];
  };

  const getCalendarValuesForWeek = () => {
    const topValues = [];
    const bottomValues = [];
    const offDayRects = [];
    let weeksCount = 1;
    const topDefaultHeight = headerHeight * 0.5;
    const dates = dateSetup.dates;

    for (let i = dates.length - 1; i >= 0; i--) {
      const date = dates[i];
      let topValue = "";

      if (i === 0 || date.getMonth() !== dates[i - 1].getMonth()) {
        topValue = `${shortMonth(date)} ${date.getFullYear()}`;
      }

      const bottomValue = date.getDate().toString();
      bottomValues.push(React.createElement("text", {
        key: date.getTime(),
        y: headerHeight * 0.8,
        x: columnWidth * (i + +rtl),
        className: `${styles$6.calendarTopText} ${styles$6.textAnchorStart}`
      }, bottomValue));

      if (topValue) {
        if (i !== dates.length - 1) {
          topValues.push(React.createElement(TopPartOfCalendar, {
            key: topValue + i,
            value: topValue,
            x1Line: columnWidth * i + weeksCount * columnWidth,
            y1Line: 0,
            y2Line: topDefaultHeight,
            xText: columnWidth * i + columnWidth * weeksCount * 0.5,
            yText: topDefaultHeight * 0.9,
            textAnchor: "start"
          }));
        }

        weeksCount = 0;
      }

      weeksCount++;
    }

    return [topValues, bottomValues, offDayRects];
  };

  const getCalendarValuesForDay = () => {
    const topValues = [];
    const bottomValues = [];
    const offDayRects = [];
    const tickLines = [];
    const topDefaultHeight = headerHeight * 0.5;
    const dates = dateSetup.dates;
    const weekStartDay = (projectCalendar === null || projectCalendar === void 0 ? void 0 : projectCalendar.week_start) ?? 1;

    for (let i = 0; i < dates.length; i++) {
      const date = dates[i];

      if (isDayOff(date)) {
        offDayRects.push(React.createElement("rect", {
          key: `offday-header-${i}`,
          x: columnWidth * i,
          y: topDefaultHeight,
          width: columnWidth,
          height: headerHeight - topDefaultHeight,
          fill: weekendColor
        }));
      }

      const isWeekStart = date.getDay() === weekStartDay;
      tickLines.push(React.createElement("line", {
        key: `tick-day-${i}`,
        x1: columnWidth * i,
        y1: topDefaultHeight,
        x2: columnWidth * i,
        y2: headerHeight,
        className: isWeekStart ? styles$6.calendarTickSolid : styles$6.calendarTickDashed
      }));
      const bottomValue = columnWidth > 55 ? `${getLocalDayOfWeek(date, locale, "short")}, ${date.getDate()}` : `${getLocalDayOfWeek(date, locale, "narrow")},${date.getDate()}`;
      bottomValues.push(React.createElement("text", {
        key: date.getTime(),
        y: headerHeight * 0.8,
        x: columnWidth * i + columnWidth * 0.5,
        className: `${styles$6.calendarTopText} ${styles$6.textAnchorMiddle}`
      }, bottomValue));

      if (i + 1 !== dates.length && date.getMonth() !== dates[i + 1].getMonth()) {
        const topValue = `${shortMonth(date)} ${date.getFullYear()}`;
        topValues.push(React.createElement(TopPartOfCalendar, {
          key: topValue + i,
          value: topValue,
          x1Line: columnWidth * (i + 1),
          y1Line: 0,
          y2Line: topDefaultHeight,
          xText: topValues.length === 0 ? columnWidth * (i + 1) * 0.5 : columnWidth * (i + 1) - date.getDate() * columnWidth * 0.5,
          yText: topDefaultHeight * 0.9
        }));
      }

      if (i + 1 === dates.length) {
        const topValue = `${shortMonth(date)} ${date.getFullYear()}`;
        topValues.push(React.createElement(TopPartOfCalendar, {
          key: topValue + "last",
          value: topValue,
          x1Line: columnWidth * (i + 1),
          y1Line: 0,
          y2Line: topDefaultHeight,
          xText: columnWidth * (i + 1) - date.getDate() * columnWidth * 0.5,
          yText: topDefaultHeight * 0.9
        }));
      }
    }

    return [topValues, bottomValues, offDayRects, tickLines];
  };

  const getCalendarValuesForPartOfDay = () => {
    const topValues = [];
    const bottomValues = [];
    const ticks = viewMode === ViewMode.HalfDay ? 2 : 4;
    const topDefaultHeight = headerHeight * 0.5;
    const dates = dateSetup.dates;

    for (let i = 0; i < dates.length; i++) {
      const date = dates[i];
      const bottomValue = getCachedDateTimeFormat(locale, {
        hour: "numeric"
      }).format(date);
      bottomValues.push(React.createElement("text", {
        key: date.getTime(),
        y: headerHeight * 0.8,
        x: columnWidth * (i + +rtl),
        className: `${styles$6.calendarTopText} ${styles$6.textAnchorMiddle}`,
        fontFamily: fontFamily
      }, bottomValue));

      if (i === 0 || date.getDate() !== dates[i - 1].getDate()) {
        const topValue = `${getLocalDayOfWeek(date, locale, "short")}, ${date.getDate()} ${shortMonth(date)}`;
        topValues.push(React.createElement(TopPartOfCalendar, {
          key: topValue + date.getFullYear(),
          value: topValue,
          x1Line: columnWidth * i + ticks * columnWidth,
          y1Line: 0,
          y2Line: topDefaultHeight,
          xText: columnWidth * i + ticks * columnWidth * 0.5,
          yText: topDefaultHeight * 0.9
        }));
      }
    }

    return [topValues, bottomValues];
  };

  const getCalendarValuesForHour = () => {
    const topValues = [];
    const bottomValues = [];
    const topDefaultHeight = headerHeight * 0.5;
    const dates = dateSetup.dates;

    for (let i = 0; i < dates.length; i++) {
      const date = dates[i];
      const bottomValue = getCachedDateTimeFormat(locale, {
        hour: "numeric"
      }).format(date);
      bottomValues.push(React.createElement("text", {
        key: date.getTime(),
        y: headerHeight * 0.8,
        x: columnWidth * (i + +rtl),
        className: styles$6.calendarBottomText,
        fontFamily: fontFamily
      }, bottomValue));

      if (i !== 0 && date.getDate() !== dates[i - 1].getDate()) {
        const displayDate = dates[i - 1];
        const topValue = `${getLocalDayOfWeek(displayDate, locale, "long")}, ${displayDate.getDate()} ${shortMonth(displayDate)}`;
        const topPosition = (date.getHours() - 24) / 2;
        topValues.push(React.createElement(TopPartOfCalendar, {
          key: topValue + displayDate.getFullYear(),
          value: topValue,
          x1Line: columnWidth * i,
          y1Line: 0,
          y2Line: topDefaultHeight,
          xText: columnWidth * (i + topPosition),
          yText: topDefaultHeight * 0.9
        }));
      }
    }

    return [topValues, bottomValues];
  };

  let topValues = [];
  let bottomValues = [];
  let extraValues = [];
  let tickLines = [];

  switch (dateSetup.viewMode) {
    case ViewMode.Year:
      [topValues, bottomValues] = getCalendarValuesForYear();
      break;

    case ViewMode.Quarter:
      {
        const r = getCalendarValuesForQuarter();
        topValues = r[0];
        bottomValues = r[1];
        extraValues = r[2] || [];
        break;
      }

    case ViewMode.Month:
      {
        const r = getCalendarValuesForMonth();
        topValues = r[0];
        bottomValues = r[1];
        extraValues = r[2] || [];
        break;
      }

    case ViewMode.Week:
      {
        const r = getCalendarValuesForWeek();
        topValues = r[0];
        bottomValues = r[1];
        extraValues = r[2] || [];
        break;
      }

    case ViewMode.Day:
      {
        const result = getCalendarValuesForDay();
        topValues = result[0];
        bottomValues = result[1];
        extraValues = result[2];
        tickLines = result[3];
        break;
      }

    case ViewMode.QuarterDay:
    case ViewMode.HalfDay:
      [topValues, bottomValues] = getCalendarValuesForPartOfDay();
      break;

    case ViewMode.Hour:
      [topValues, bottomValues] = getCalendarValuesForHour();
  }

  return React.createElement("g", {
    className: "calendar",
    fontSize: fontSize,
    fontFamily: fontFamily,
    width: columnWidth * dateSetup.dates.length
  }, React.createElement("rect", {
    x: 0,
    y: 0,
    width: columnWidth * dateSetup.dates.length,
    height: headerHeight,
    className: styles$6.calendarHeader
  }), extraValues, tickLines, bottomValues, topValues);
};

// A type of promise-like that resolves synchronously and supports only one observer

const _iteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.iterator || (Symbol.iterator = Symbol("Symbol.iterator"))) : "@@iterator";

const _asyncIteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.asyncIterator || (Symbol.asyncIterator = Symbol("Symbol.asyncIterator"))) : "@@asyncIterator";

// Asynchronously call a function and send errors to recovery continuation
function _catch(body, recover) {
	try {
		var result = body();
	} catch(e) {
		return recover(e);
	}
	if (result && result.then) {
		return result.then(void 0, recover);
	}
	return result;
}

const Arrow = _ref => {
  let {
    taskFrom,
    taskTo,
    rowHeight,
    taskHeight,
    arrowIndent,
    arrowColor,
    dependencyType
  } = _ref;
  let [path, trianglePoints] = drawPathAndTriangle(taskFrom, taskTo, rowHeight, taskHeight, arrowIndent, dependencyType);
  return React.createElement("g", {
    className: "arrow"
  }, React.createElement("path", {
    strokeWidth: "1.5",
    d: path,
    fill: "none",
    stroke: arrowColor
  }), React.createElement("polygon", {
    points: trianglePoints,
    fill: arrowColor
  }));
};

const drawPathAndTriangle = (taskFrom, taskTo, rowHeight, taskHeight, arrowIndent, dependencyType) => {
  const indexCompare = taskFrom.index > taskTo.index ? -1 : 1;
  const taskToEndY = taskTo.y + taskHeight / 2;
  const verticalOffset = indexCompare * (rowHeight / 2);

  const minX = t => {
    if (t.plannedSegments && t.plannedSegments.length > 0) {
      const p = t.plannedSegments[0].x1;
      if (t.actualSegments && t.actualSegments.length > 0) return Math.min(p, t.actualSegments[0].x1);
      return p;
    }

    if (t.actualSegments && t.actualSegments.length > 0) return t.actualSegments[0].x1;
    const candidates = [];
    if (t.x2 > t.x1) candidates.push(t.x1);
    if (t.actualx2 > t.actualx1) candidates.push(t.actualx1);
    return candidates.length > 0 ? Math.min(...candidates) : 0;
  };

  const maxX = t => {
    if (t.plannedSegments && t.plannedSegments.length > 0) {
      const p = t.plannedSegments[t.plannedSegments.length - 1].x2;
      if (t.actualSegments && t.actualSegments.length > 0) return Math.max(p, t.actualSegments[t.actualSegments.length - 1].x2);
      return p;
    }

    if (t.actualSegments && t.actualSegments.length > 0) return t.actualSegments[t.actualSegments.length - 1].x2;
    const candidates = [];
    if (t.x2 > t.x1) candidates.push(t.x2);
    if (t.actualx2 > t.actualx1) candidates.push(t.actualx2);
    return candidates.length > 0 ? Math.max(...candidates) : 0;
  };

  let fromPoint, toPoint;

  switch (dependencyType) {
    case "SS":
      fromPoint = minX(taskFrom);
      toPoint = minX(taskTo);
      break;

    case "SF":
      fromPoint = minX(taskFrom);
      toPoint = maxX(taskTo);
      break;

    case "FS":
      fromPoint = maxX(taskFrom);
      toPoint = minX(taskTo);
      break;

    case "FF":
      fromPoint = maxX(taskFrom);
      toPoint = maxX(taskTo);
      break;
  }

  const arrowPoints = function (x, y, right) {
    if (right === void 0) {
      right = true;
    }

    return right ? `${x},${y} ${x - 5},${y - 5} ${x - 5},${y + 5}` : `${x},${y} ${x + 5},${y - 5} ${x + 5},${y + 5}`;
  };

  let path;
  let trianglePoints;

  switch (dependencyType) {
    case "SS":
      path = `M ${fromPoint} ${taskFrom.y + taskHeight / 2}
              H ${fromPoint + Math.min(toPoint - fromPoint, 0) - 2 * arrowIndent}
              V ${taskToEndY}
              H ${toPoint - 5}`;
      trianglePoints = arrowPoints(toPoint, taskToEndY, true);
      break;

    case "SF":
      path = `M ${fromPoint} ${taskFrom.y + taskHeight / 2}
              H ${fromPoint - 2 * arrowIndent}
              V ${taskFrom.y + taskHeight / 2 + verticalOffset}
                ${fromPoint - toPoint > 4 * arrowIndent ? "" : `H ${toPoint + 2 * arrowIndent}`}
              V ${taskToEndY}
              H ${toPoint + 5}`;
      trianglePoints = arrowPoints(toPoint, taskToEndY, false);
      break;

    case "FS":
      path = `M ${fromPoint} ${taskFrom.y + taskHeight / 2}
              H ${fromPoint + 2 * arrowIndent}
              V ${taskFrom.y + taskHeight / 2 + verticalOffset}
                ${toPoint - fromPoint > 4 * arrowIndent ? "" : `H ${toPoint - 2 * arrowIndent}`}
              V ${taskToEndY}
              H ${toPoint - 5}`;
      trianglePoints = arrowPoints(toPoint, taskToEndY, true);
      break;

    case "FF":
      path = `M ${fromPoint} ${taskFrom.y + taskHeight / 2}
              H ${fromPoint + Math.max(toPoint - fromPoint, 0) + 2 * arrowIndent}
              V ${taskToEndY}
              H ${toPoint + 5}`;
      trianglePoints = arrowPoints(toPoint, taskToEndY, false);
      break;
  }

  return [path, trianglePoints];
};

var convertToBarTasks = function convertToBarTasks(tasks, dates, columnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, rtl, barProgressColor, barProgressSelectedColor, barBackgroundColor, barBackgroundSelectedColor, projectProgressColor, projectProgressSelectedColor, projectBackgroundColor, projectBackgroundSelectedColor, milestoneBackgroundColor, milestoneBackgroundSelectedColor) {
  var barTasks = tasks.map(function (t, i) {
    return convertToBarTask(t, i, dates, columnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, rtl, barProgressColor, barProgressSelectedColor, barBackgroundColor, barBackgroundSelectedColor, projectProgressColor, projectProgressSelectedColor, projectBackgroundColor, projectBackgroundSelectedColor, milestoneBackgroundColor, milestoneBackgroundSelectedColor);
  });
  barTasks = barTasks.map(function (task) {
    var dependencies = task.dependencies || [];

    var _loop = function _loop(j) {
      var dependence = barTasks.findIndex(function (value) {
        return value.id === dependencies[j].id;
      });

      if (dependence !== -1 && task.start.getTime() > 0 && task.end.getTime() > 0) {
        var barchild = _extends({}, task, {
          dependencyType: dependencies[j].type
        });

        barTasks[dependence].barChildren.push(barchild);
      }
    };

    for (var j = 0; j < dependencies.length; j++) {
      _loop(j);
    }

    return task;
  });
  return barTasks;
};

var convertToBarTask = function convertToBarTask(task, index, dates, columnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, rtl, barProgressColor, barProgressSelectedColor, barBackgroundColor, barBackgroundSelectedColor, projectProgressColor, projectProgressSelectedColor, projectBackgroundColor, projectBackgroundSelectedColor, milestoneBackgroundColor, milestoneBackgroundSelectedColor) {
  var barTask;

  switch (task.type) {
    case "milestone":
      barTask = convertToMilestone(task, index, dates, columnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, milestoneBackgroundColor, milestoneBackgroundSelectedColor);
      break;

    case "project":
      barTask = convertToBar(task, index, dates, columnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, rtl, projectProgressColor, projectProgressSelectedColor, projectBackgroundColor, projectBackgroundSelectedColor);
      break;

    default:
      barTask = convertToBar(task, index, dates, columnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, rtl, barProgressColor, barProgressSelectedColor, barBackgroundColor, barBackgroundSelectedColor);
      break;
  }

  return barTask;
};

var convertToBar = function convertToBar(task, index, dates, columnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, rtl, barProgressColor, barProgressSelectedColor, barBackgroundColor, barBackgroundSelectedColor) {
  var x1;
  var x2;
  var actualx1;
  var actualx2;
  var progressStartWidth;
  var progressEndWidth;

  if (rtl) {
    x2 = task.start ? taskXCoordinateRTL(task.start, dates, columnWidth) : -1;
    x1 = task.end ? taskXCoordinateRTL(task.end, dates, columnWidth) : -1;
    actualx1 = task.actualStart ? taskXCoordinateRTL(task.actualStart, dates, columnWidth) : -1;
    actualx2 = task.actualEnd ? taskXCoordinateRTL(task.actualEnd, dates, columnWidth) : -1;
  } else {
    x1 = task.start ? taskXCoordinate(startOfDate(task.start, "day"), dates, columnWidth) : -1;
    x2 = task.end ? taskXCoordinate(addToDate(startOfDate(task.end, "day"), 1, "day"), dates, columnWidth) : -1;
    actualx1 = task.actualStart ? taskXCoordinate(startOfDate(task.actualStart, "day"), dates, columnWidth) : -1;
    actualx2 = task.actualEnd ? taskXCoordinate(addToDate(startOfDate(task.actualEnd, "day"), 1, "day"), dates, columnWidth) : -1;
  }

  progressStartWidth = actualx1 && x1 ? Math.abs(actualx1 - x1) : -1;
  progressEndWidth = actualx2 && x2 ? Math.abs(actualx2 - x2) : -1;
  var typeInternal = task.type;

  var _progressWithByParams = progressWithByParams(actualx1, actualx2, task.progress, rtl),
      progressWidth = _progressWithByParams[0],
      progressX = _progressWithByParams[1];

  var y = taskYCoordinate(index, rowHeight, taskHeight);
  var hideChildren = task.hideChildren || false;
  var plannedSegments;
  var actualSegments;

  if (task.calendar && task.start && task.end && task.start.getTime() > 0) {
    var planEnd = addToDate(startOfDate(task.end, "day"), 1, "day");
    var intervals = getWorkingIntervals(task.start, planEnd, task.calendar);
    var segs = intervals.map(function (iv) {
      return {
        x1: taskXCoordinate(iv.start, dates, columnWidth),
        x2: taskXCoordinate(iv.end, dates, columnWidth)
      };
    }).filter(function (s) {
      return s.x2 > s.x1;
    });
    if (segs.length > 0) plannedSegments = segs;
  }

  if (task.calendar && task.actualStart && task.actualEnd && task.actualStart.getTime() > 0) {
    var actEnd = addToDate(startOfDate(task.actualEnd, "day"), 1, "day");

    var _intervals = getWorkingIntervals(task.actualStart, actEnd, task.calendar);

    var _segs = _intervals.map(function (iv) {
      return {
        x1: taskXCoordinate(iv.start, dates, columnWidth),
        x2: taskXCoordinate(iv.end, dates, columnWidth)
      };
    }).filter(function (s) {
      return s.x2 > s.x1;
    });

    if (_segs.length > 0) actualSegments = _segs;
  }

  var styles = _extends({
    backgroundColor: barBackgroundColor,
    backgroundSelectedColor: barBackgroundSelectedColor,
    progressColor: barProgressColor,
    progressSelectedColor: barProgressSelectedColor
  }, task.styles);

  return _extends({}, task, {
    typeInternal: typeInternal,
    x1: x1,
    x2: x2,
    actualx1: actualx1,
    actualx2: actualx2,
    progressStartWidth: progressStartWidth,
    progressEndWidth: progressEndWidth,
    y: y,
    index: index,
    progressX: progressX,
    progressWidth: progressWidth,
    barCornerRadius: barCornerRadius,
    handleWidth: handleWidth,
    hideChildren: hideChildren,
    height: taskHeight,
    barChildren: [],
    styles: styles,
    plannedSegments: plannedSegments,
    actualSegments: actualSegments
  });
};

var convertToMilestone = function convertToMilestone(task, index, dates, columnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, milestoneBackgroundColor, milestoneBackgroundSelectedColor) {
  var x = task.start && task.end ? taskXCoordinate(task.end, dates, columnWidth) : 0;
  var y = taskYCoordinate(index, rowHeight, taskHeight);
  var x1 = task.start && task.end ? x - taskHeight * 0.5 : 0;
  var x2 = task.start && task.end ? x + taskHeight * 0.5 : 0;
  var rotatedHeight = taskHeight / 1.414;

  var styles = _extends({
    backgroundColor: milestoneBackgroundColor,
    backgroundSelectedColor: milestoneBackgroundSelectedColor,
    progressColor: "",
    progressSelectedColor: ""
  }, task.styles);

  return _extends({}, task, {
    x1: x1,
    x2: x2,
    actualx1: x1,
    actualx2: x2,
    progressStartWidth: 0,
    progressEndWidth: 0,
    y: y,
    index: index,
    progressX: 0,
    progressWidth: 0,
    barCornerRadius: barCornerRadius,
    handleWidth: handleWidth,
    typeInternal: task.type,
    progress: 0,
    height: rotatedHeight,
    hideChildren: undefined,
    barChildren: [],
    styles: styles
  });
};

var taskXCoordinate = function taskXCoordinate(xDate, dates, columnWidth) {
  var index = dates.findIndex(function (d) {
    return d.getTime() >= xDate.getTime();
  }) - 1;

  if (index < 0) {
    if (dates[dates.length - 1].getTime() <= xDate.getTime()) {
      return dates.length * columnWidth;
    } else {
      return 0;
    }
  }

  var remainderMillis = xDate.getTime() - dates[index].getTime();
  var percentOfInterval = remainderMillis / (dates[index + 1].getTime() - dates[index].getTime());
  var x = index * columnWidth + percentOfInterval * columnWidth;
  return x;
};

var taskXCoordinateRTL = function taskXCoordinateRTL(xDate, dates, columnWidth) {
  var x = taskXCoordinate(xDate, dates, columnWidth);
  x += columnWidth;
  return x;
};

var taskYCoordinate = function taskYCoordinate(index, rowHeight, taskHeight) {
  var y = index * rowHeight + (rowHeight - taskHeight) / 2;
  return y;
};

var progressWithByParams = function progressWithByParams(taskX1, taskX2, progress, rtl) {
  var progressWidth = taskX2 > 0 && taskX1 > 0 ? (taskX2 - taskX1) * progress * 0.01 : 0;
  var progressX;

  if (rtl) {
    progressX = taskX2 > 0 ? taskX2 - progressWidth : 0;
  } else {
    progressX = taskX1 > 0 ? taskX1 : 0;
  }

  return [progressWidth, progressX];
};
var getProgressPoint = function getProgressPoint(progressX, taskY, taskHeight) {
  var point = [progressX - 5, taskY + taskHeight, progressX + 5, taskY + taskHeight, progressX, taskY + taskHeight - 8.66];
  return point.join(",");
};

var startByX = function startByX(x, xStep, task) {
  if (x >= task.x2 - task.handleWidth * 2) {
    x = task.x2 - task.handleWidth * 2;
  }

  var steps = Math.round((x - task.x1) / xStep);
  var additionalXValue = steps * xStep;
  var newX = task.x1 + additionalXValue;
  return newX;
};

var startByActualX = function startByActualX(x, xStep, task) {
  if (x >= task.actualx2 - task.handleWidth * 2) {
    x = task.actualx2 - task.handleWidth * 2;
  }

  var steps = Math.round((x - task.actualx1) / xStep);
  var additionalXValue = steps * xStep;
  var newX = task.actualx1 + additionalXValue;
  return newX;
};

var endByX = function endByX(x, xStep, task) {
  if (x <= task.x1 + task.handleWidth * 2) {
    x = task.x1 + task.handleWidth * 2;
  }

  var steps = Math.round((x - task.x2) / xStep);
  var additionalXValue = steps * xStep;
  var newX = task.x2 + additionalXValue;
  return newX;
};

var endByActualX = function endByActualX(x, xStep, task) {
  if (x <= task.actualx1 + task.handleWidth * 2) {
    x = task.actualx1 + task.handleWidth * 2;
  }

  var steps = Math.round((x - task.actualx2) / xStep);
  var additionalXValue = steps * xStep;
  var newX = task.actualx2 + additionalXValue;
  return newX;
};

var moveByX = function moveByX(x, xStep, task) {
  var steps = Math.round((x - task.x1) / xStep);
  var additionalXValue = steps * xStep;
  var newX1 = task.x1 + additionalXValue;
  var newX2 = newX1 + task.x2 - task.x1;
  return [newX1, newX2];
};

var moveByActualX = function moveByActualX(x, xStep, task) {
  var steps = Math.round((x - task.actualx1) / xStep);
  var additionalXValue = steps * xStep;
  var newX1 = task.actualx1 + additionalXValue;
  var newX2 = newX1 + task.actualx2 - task.actualx1;
  return [newX1, newX2];
};

var dateByX = function dateByX(x, taskX, taskDate, xStep, timeStep) {
  var newDate = new Date((x - taskX) / xStep * timeStep + taskDate.getTime());
  newDate = new Date(newDate.getTime() + (newDate.getTimezoneOffset() - taskDate.getTimezoneOffset()) * 60000);
  return newDate;
};

var handleTaskBySVGMouseEvent = function handleTaskBySVGMouseEvent(svgX, action, selectedTask, type, xStep, timeStep, initEventX1Delta, rtl) {
  var result;

  switch (selectedTask.type) {
    case "milestone":
      result = handleTaskBySVGMouseEventForMilestone(svgX, action, selectedTask, xStep, timeStep, initEventX1Delta);
      break;

    default:
      result = handleTaskBySVGMouseEventForBar(svgX, action, selectedTask, type, xStep, timeStep, initEventX1Delta, rtl);
      break;
  }

  return result;
};

var handleTaskBySVGMouseEventForBar = function handleTaskBySVGMouseEventForBar(svgX, action, selectedTask, type, xStep, timeStep, initEventX1Delta, rtl) {
  var changedTask = _extends({}, selectedTask);

  var isChanged = false;

  switch (action) {
    case "start":
      {
        var newX1 = type == "planned" ? startByX(svgX, xStep, selectedTask) : startByActualX(svgX, xStep, selectedTask);
        if (type == "planned") changedTask.x1 = newX1;else if (type == "actual") changedTask.actualx1 = newX1;
        isChanged = changedTask.x1 !== selectedTask.x1 || changedTask.actualx1 !== selectedTask.actualx1;

        if (isChanged) {
          if (rtl) {
            if (type == "planned") changedTask.end = dateByX(newX1, selectedTask.x1, selectedTask.end, xStep, timeStep);
            if (type == "actual") changedTask.actualEnd = dateByX(newX1, selectedTask.actualx1, selectedTask.actualEnd, xStep, timeStep);
          } else {
            if (type == "planned") changedTask.start = dateByX(newX1, selectedTask.x1, selectedTask.start, xStep, timeStep);
            if (type == "actual") changedTask.actualStart = dateByX(newX1, selectedTask.actualx1, selectedTask.actualStart, xStep, timeStep);
          }

          var _progressWithByParams2 = progressWithByParams(changedTask.x1, changedTask.x2, changedTask.progress, rtl),
              progressWidth = _progressWithByParams2[0],
              progressX = _progressWithByParams2[1];

          changedTask.progressWidth = progressWidth;
          changedTask.progressX = progressX;
        }

        break;
      }

    case "end":
      {
        var newX2 = type == "planned" ? endByX(svgX, xStep, selectedTask) : endByActualX(svgX, xStep, selectedTask);
        if (type == "planned") changedTask.x2 = newX2;else if (type == "actual") changedTask.actualx2 = newX2;
        isChanged = changedTask.x2 !== selectedTask.x2 || changedTask.actualx2 !== selectedTask.actualx2;

        if (isChanged) {
          if (rtl) {
            if (type == "planned") changedTask.start = dateByX(newX2, selectedTask.x2, selectedTask.start, xStep, timeStep);
            if (type == "actual") changedTask.actualStart = dateByX(newX2, selectedTask.actualx2, selectedTask.actualStart, xStep, timeStep);
          } else {
            if (type == "planned") changedTask.end = dateByX(newX2, selectedTask.x2, selectedTask.end, xStep, timeStep);
            if (type == "actual") changedTask.actualEnd = dateByX(newX2, selectedTask.actualx2, selectedTask.actualEnd, xStep, timeStep);
          }

          var _progressWithByParams3 = progressWithByParams(changedTask.x1, changedTask.x2, changedTask.progress, rtl),
              _progressWidth = _progressWithByParams3[0],
              _progressX = _progressWithByParams3[1];

          changedTask.progressWidth = _progressWidth;
          changedTask.progressX = _progressX;
        }

        break;
      }

    case "move":
      {
        var _ref = type == "planned" ? moveByX(svgX - initEventX1Delta, xStep, selectedTask) : moveByActualX(svgX - initEventX1Delta, xStep, selectedTask),
            newMoveX1 = _ref[0],
            newMoveX2 = _ref[1];

        if (type == "planned") isChanged = newMoveX1 !== selectedTask.x1;
        if (type == "actual") isChanged = newMoveX1 !== selectedTask.actualx1;

        if (isChanged) {
          if (type == "planned") {
            changedTask.start = dateByX(newMoveX1, selectedTask.x1, selectedTask.start, xStep, timeStep);
            changedTask.end = dateByX(newMoveX2, selectedTask.x2, selectedTask.end, xStep, timeStep);
            changedTask.x1 = newMoveX1;
            changedTask.x2 = newMoveX2;
          }

          if (type == "actual") {
            changedTask.actualStart = dateByX(newMoveX1, selectedTask.actualx1, selectedTask.actualStart, xStep, timeStep);
            changedTask.actualEnd = dateByX(newMoveX2, selectedTask.actualx2, selectedTask.actualEnd, xStep, timeStep);
            changedTask.actualx1 = newMoveX1;
            changedTask.actualx2 = newMoveX2;
          }
        }

        break;
      }
  }

  return {
    isChanged: isChanged,
    changedTask: changedTask
  };
};

var handleTaskBySVGMouseEventForMilestone = function handleTaskBySVGMouseEventForMilestone(svgX, action, selectedTask, xStep, timeStep, initEventX1Delta) {
  var changedTask = _extends({}, selectedTask);

  var isChanged = false;

  switch (action) {
    case "move":
      {
        var _moveByX = moveByX(svgX - initEventX1Delta, xStep, selectedTask),
            newMoveX1 = _moveByX[0],
            newMoveX2 = _moveByX[1];

        isChanged = newMoveX1 !== selectedTask.x1;

        if (isChanged) {
          changedTask.start = dateByX(newMoveX1, selectedTask.x1, selectedTask.start, xStep, timeStep);
          changedTask.end = changedTask.start;
          changedTask.x1 = newMoveX1;
          changedTask.x2 = newMoveX2;
        }

        break;
      }
  }

  return {
    isChanged: isChanged,
    changedTask: changedTask
  };
};

function isKeyboardEvent(event) {
  return event.key !== undefined;
}
function removeHiddenTasks(tasks) {
  var groupedTasks = tasks.filter(function (t) {
    return t.hideChildren && t.type === "project";
  });

  if (groupedTasks.length > 0) {
    var _loop = function _loop(i) {
      var groupedTask = groupedTasks[i];
      var children = getChildren(tasks, groupedTask);
      tasks = tasks.filter(function (t) {
        return children.indexOf(t) === -1;
      });
    };

    for (var i = 0; groupedTasks.length > i; i++) {
      _loop(i);
    }
  }

  return tasks;
}

function getChildren(taskList, task) {
  var tasks = [];

  if (task.type !== "project") {
    tasks = taskList.filter(function (t) {
      return t.dependencies && t.dependencies.map(function (_ref) {
        var id = _ref.id;
        return id;
      }).indexOf(task.id) !== -1;
    });
  } else {
    tasks = taskList.filter(function (t) {
      return t.project && t.project === task.id;
    });
  }

  var taskChildren = [];
  tasks.forEach(function (t) {
    taskChildren.push.apply(taskChildren, getChildren(taskList, t));
  });
  tasks = tasks.concat(tasks, taskChildren);
  return tasks;
}

var sortTasks = function sortTasks(taskA, taskB) {
  var orderA = taskA.displayOrder || Number.MAX_VALUE;
  var orderB = taskB.displayOrder || Number.MAX_VALUE;

  if (orderA > orderB) {
    return 1;
  } else if (orderA < orderB) {
    return -1;
  } else {
    return 0;
  }
};

const BarDisplay = _ref => {
  let {
    x,
    y,
    type,
    width,
    height,
    isSelected,
    progressX,
    progressWidth,
    barCornerRadius,
    styles,
    segments,
    onMouseDown
  } = _ref;

  const getProcessColor = () => {
    return isSelected ? styles.progressSelectedColor : styles.progressColor;
  };

  const getBarColor = () => {
    return isSelected ? styles.backgroundSelectedColor : styles.backgroundColor;
  };

  if (type === "planned") {
    if (segments && segments.length > 0) {
      const totalWidth = width;
      return React.createElement("g", {
        onMouseDown: onMouseDown
      }, segments.map((seg, idx) => React.createElement("rect", {
        key: `seg-${idx}`,
        x: seg.x1,
        width: seg.x2 - seg.x1,
        y: y,
        height: height,
        ry: barCornerRadius,
        rx: barCornerRadius,
        fill: getBarColor(),
        strokeWidth: 2,
        stroke: styles.criticalPathColor
      })), progressWidth > 0 && (() => {
        const rects = [];
        let remaining = progressWidth;

        for (const seg of segments) {
          if (remaining <= 0) break;
          const segW = seg.x2 - seg.x1;
          const ratio = totalWidth > 0 ? segW / totalWidth : 0;
          const pw = Math.min(remaining, progressWidth * ratio);

          if (pw > 0) {
            rects.push(React.createElement("rect", {
              key: `prog-${seg.x1}`,
              x: seg.x1,
              width: pw,
              y: y,
              height: height,
              ry: barCornerRadius,
              rx: barCornerRadius,
              fill: getProcessColor()
            }));
            remaining -= pw;
          }
        }

        return rects;
      })());
    }

    return React.createElement("g", {
      onMouseDown: onMouseDown
    }, React.createElement("rect", {
      x: x,
      width: width,
      y: y,
      height: height,
      ry: barCornerRadius,
      rx: barCornerRadius,
      fill: getBarColor(),
      strokeWidth: 2,
      stroke: styles.criticalPathColor
    }), React.createElement("rect", {
      x: progressX,
      width: progressWidth,
      y: y,
      height: height,
      ry: barCornerRadius,
      rx: barCornerRadius,
      fill: getProcessColor()
    }));
  } else {
    if (segments && segments.length > 0) {
      return React.createElement("g", {
        onMouseDown: onMouseDown
      }, segments.map((seg, idx) => React.createElement("rect", {
        key: `aseg-${idx}`,
        x: seg.x1,
        width: seg.x2 - seg.x1,
        y: y,
        height: height,
        ry: barCornerRadius,
        rx: barCornerRadius,
        fill: styles.taskProgressColor
      })), React.createElement("rect", {
        x: progressX,
        width: progressWidth,
        y: y,
        height: height,
        ry: barCornerRadius,
        rx: barCornerRadius,
        fill: getProcessColor()
      }));
    }

    return React.createElement("g", {
      onMouseDown: onMouseDown
    }, React.createElement("rect", {
      x: x,
      width: width,
      y: y,
      height: height,
      ry: barCornerRadius,
      rx: barCornerRadius,
      fill: styles.taskProgressColor
    }), React.createElement("rect", {
      x: progressX,
      width: progressWidth,
      y: y,
      height: height,
      ry: barCornerRadius,
      rx: barCornerRadius,
      fill: getProcessColor()
    }));
  }
};

var styles$7 = {"barWrapper":"_KxSXS","barHandle":"_3w_5u","barBackground":"_31ERP"};

const BarDateHandle = _ref => {
  let {
    x,
    y,
    width,
    height,
    barCornerRadius,
    onMouseDown
  } = _ref;
  return React.createElement("rect", {
    x: x,
    y: y,
    width: width,
    height: height,
    className: styles$7.barHandle,
    ry: barCornerRadius,
    rx: barCornerRadius,
    onMouseDown: onMouseDown
  });
};

const BarProgressHandle = _ref => {
  return React.createElement("div", null);
};

const Bar = _ref => {
  let {
    task,
    isProgressChangeable,
    isDateChangeable,
    rtl,
    type,
    onEventStart,
    isSelected
  } = _ref;
  const progressPoint = getProgressPoint(+!rtl * task.progressWidth + task.progressX, task.y, task.height);
  const handleHeight = task.height / 2 - 1;
  const plannedSegs = task.plannedSegments;
  const plannedLeftHandleX = plannedSegs !== null && plannedSegs !== void 0 && plannedSegs.length ? plannedSegs[0].x1 : task.x1;
  const plannedRightHandleX = plannedSegs !== null && plannedSegs !== void 0 && plannedSegs.length ? plannedSegs[plannedSegs.length - 1].x2 : task.x2;
  const actualSegs = task.actualSegments;
  const actualLeftHandleX = actualSegs !== null && actualSegs !== void 0 && actualSegs.length ? actualSegs[0].x1 : task.actualx1;
  const actualRightHandleX = actualSegs !== null && actualSegs !== void 0 && actualSegs.length ? actualSegs[actualSegs.length - 1].x2 : task.actualx2;

  if (type == "planned") {
    if ((task === null || task === void 0 ? void 0 : task.x1) >= 0 && (task === null || task === void 0 ? void 0 : task.x2) >= 0 && task.x2 - task.x1 >= 0) return React.createElement("g", {
      className: styles$7.barWrapper,
      tabIndex: 0
    }, React.createElement("rect", {
      x: task.x1,
      y: task.y,
      width: task.x2 - task.x1,
      height: task.height / 2,
      fill: "transparent"
    }), React.createElement(BarDisplay, {
      x: task.x1,
      y: task.y,
      type: type,
      startProgressWidth: task.progressStartWidth,
      endProgressWidth: task.progressEndWidth,
      width: task.x2 - task.x1,
      height: task.height / 2,
      progressX: task.progressX,
      progressWidth: task.progressWidth,
      barCornerRadius: task.barCornerRadius,
      styles: task.styles,
      isSelected: isSelected,
      segments: task.plannedSegments,
      onMouseDown: e => {
        isDateChangeable && onEventStart("move", task, e, "planned");
      }
    }), React.createElement("g", {
      className: "handleGroup"
    }, isDateChangeable && React.createElement("g", null, React.createElement(BarDateHandle, {
      x: plannedLeftHandleX + 1,
      y: task.y + 1,
      width: task.handleWidth,
      height: handleHeight,
      barCornerRadius: task.barCornerRadius,
      onMouseDown: e => {
        onEventStart("start", task, e, "planned");
      }
    }), React.createElement(BarDateHandle, {
      x: plannedRightHandleX - task.handleWidth - 1,
      y: task.y + 1,
      width: task.handleWidth,
      height: handleHeight,
      barCornerRadius: task.barCornerRadius,
      onMouseDown: e => {
        onEventStart("end", task, e, "planned");
      }
    })), isProgressChangeable && React.createElement(BarProgressHandle, {
      progressPoint: progressPoint,
      onMouseDown: e => {
        onEventStart("progress", task, e, "planned");
      }
    })));else return React.createElement("g", {
      className: styles$7.barWrapper,
      tabIndex: 0
    });
  } else if ((task === null || task === void 0 ? void 0 : task.actualx1) >= 0 && (task === null || task === void 0 ? void 0 : task.actualx2) >= 0 && task.actualx2 - task.actualx1 >= 0) {
    return React.createElement("g", {
      className: styles$7.barWrapper,
      tabIndex: 0
    }, React.createElement("rect", {
      x: task.actualx1,
      y: task.y + task.height / 2,
      width: task.actualx2 - task.actualx1,
      height: task.height / 2,
      fill: "transparent"
    }), React.createElement(BarDisplay, {
      x: task.actualx1,
      y: task.y + task.height / 2,
      type: type,
      startProgressWidth: task.progressStartWidth,
      endProgressWidth: task.progressEndWidth,
      width: task.actualx2 - task.actualx1,
      height: task.height / 2,
      progressX: task.progressX,
      progressWidth: task.progressWidth,
      barCornerRadius: task.barCornerRadius,
      styles: task.styles,
      isSelected: isSelected,
      segments: task.actualSegments,
      onMouseDown: e => {
        isDateChangeable && onEventStart("move", task, e, "actual");
      }
    }), React.createElement("g", {
      className: "handleGroup"
    }, isDateChangeable && React.createElement("g", null, React.createElement(BarDateHandle, {
      x: actualLeftHandleX + 1,
      y: task.y + task.height / 2 + 1,
      width: task.handleWidth,
      height: handleHeight,
      barCornerRadius: task.barCornerRadius,
      onMouseDown: e => {
        onEventStart("start", task, e, "actual");
      }
    }), React.createElement(BarDateHandle, {
      x: actualRightHandleX - task.handleWidth - 1,
      y: task.y + task.height / 2 + 1,
      width: task.handleWidth,
      height: handleHeight,
      barCornerRadius: task.barCornerRadius,
      onMouseDown: e => {
        onEventStart("end", task, e, "actual");
      }
    })), isProgressChangeable && React.createElement(BarProgressHandle, {
      progressPoint: progressPoint,
      onMouseDown: e => {
        onEventStart("progress", task, e, "actual");
      }
    })));
  } else {
    return React.createElement("g", {
      className: styles$7.barWrapper,
      tabIndex: 0
    });
  }
};

const BarSmall = _ref => {
  let {
    task,
    type,
    isProgressChangeable,
    isDateChangeable,
    onEventStart,
    isSelected
  } = _ref;
  const progressPoint = getProgressPoint(task.progressWidth + task.x1, task.y, task.height);
  return React.createElement("g", {
    className: styles$7.barWrapper,
    tabIndex: 0
  }, React.createElement(BarDisplay, {
    x: task.x1,
    y: task.y,
    type: type,
    startProgressWidth: task.progressStartWidth,
    endProgressWidth: task.progressEndWidth,
    width: task.x2 - task.x1,
    height: task.height,
    progressX: task.progressX,
    progressWidth: task.progressWidth,
    barCornerRadius: task.barCornerRadius,
    styles: task.styles,
    isSelected: isSelected,
    onMouseDown: e => {
      isDateChangeable && onEventStart("move", task, e);
    }
  }), React.createElement("g", {
    className: "handleGroup"
  }, isProgressChangeable && React.createElement(BarProgressHandle, {
    progressPoint: progressPoint,
    onMouseDown: e => {
      onEventStart("progress", task, e);
    }
  })));
};

var styles$8 = {"milestoneWrapper":"_RRr13","milestoneBackground":"_2P2B1"};

const Milestone = _ref => {
  let {
    task,
    isDateChangeable,
    onEventStart,
    isSelected
  } = _ref;
  const transform = `rotate(45 ${task.x1 + task.height * 0.356} 
    ${task.y + task.height * 0.85})`;

  const getBarColor = () => {
    return isSelected ? task.styles.backgroundSelectedColor : task.styles.backgroundColor;
  };

  return React.createElement("g", {
    tabIndex: 0,
    className: styles$8.milestoneWrapper
  }, React.createElement("rect", {
    fill: getBarColor(),
    x: task.x1,
    width: task.height,
    y: task.y,
    height: task.height,
    rx: task.barCornerRadius,
    ry: task.barCornerRadius,
    transform: transform,
    className: styles$8.milestoneBackground,
    onMouseDown: e => {
      isDateChangeable && onEventStart("move", task, e, "planned");
    },
    onDoubleClick: e => {
      onEventStart("dblclick", task, e);
    }
  }));
};

var styles$9 = {"projectWrapper":"_1KJ6x","projectBackground":"_2RbVy","projectTop":"_2pZMF"};

const Project = _ref => {
  let {
    task,
    isSelected
  } = _ref;
  const barColor = isSelected ? task.styles.backgroundSelectedColor : task.styles.backgroundColor;
  const processColor = isSelected ? task.styles.progressSelectedColor : task.styles.progressColor;
  const projectWith = task.x2 - task.x1;
  const projectLeftTriangle = [task.x1, task.y + task.height / 2 - 1, task.x1, task.y + task.height, task.x1 + 15, task.y + task.height / 2 - 1].join(",");
  const projectRightTriangle = [task.x2, task.y + task.height / 2 - 1, task.x2, task.y + task.height, task.x2 - 15, task.y + task.height / 2 - 1].join(",");
  return React.createElement("g", {
    tabIndex: 0,
    className: styles$9.projectWrapper
  }, React.createElement("rect", {
    fill: barColor,
    x: task.x1,
    width: projectWith,
    y: task.y,
    height: task.height,
    rx: task.barCornerRadius,
    ry: task.barCornerRadius,
    className: styles$9.projectBackground
  }), React.createElement("rect", {
    x: task.progressX,
    width: task.progressWidth,
    y: task.y,
    height: task.height,
    ry: task.barCornerRadius,
    rx: task.barCornerRadius,
    fill: processColor
  }), React.createElement("rect", {
    fill: barColor,
    x: task.x1,
    width: projectWith,
    y: task.y,
    height: task.height / 2,
    rx: task.barCornerRadius,
    ry: task.barCornerRadius,
    className: styles$9.projectTop
  }), React.createElement("polygon", {
    className: styles$9.projectTop,
    points: projectLeftTriangle,
    fill: barColor
  }), React.createElement("polygon", {
    className: styles$9.projectTop,
    points: projectRightTriangle,
    fill: barColor
  }));
};

const TaskItem = props => {
  const {
    task,
    isDelete,
    isSelected,
    onEventStart
  } = { ...props
  };
  const [taskItem, setTaskItem] = useState([React.createElement("div", null)]);
  useEffect(() => {
    switch (task.typeInternal) {
      case "milestone":
        if (task.x1 >= 0 && task.actualx1 >= 0) setTaskItem([React.createElement(Milestone, Object.assign({}, props))]);else setTaskItem([]);
        break;

      case "project":
        if ((task === null || task === void 0 ? void 0 : task.x1) >= 0 && (task === null || task === void 0 ? void 0 : task.x2) >= 0 && task.x2 > task.x1 && (task === null || task === void 0 ? void 0 : task.actualx1) >= 0 && (task === null || task === void 0 ? void 0 : task.actualx2) >= 0 && task.actualx2 > task.actualx1) setTaskItem([React.createElement(Project, Object.assign({}, props))]);else setTaskItem([]);
        break;

      case "smalltask":
        setTaskItem([React.createElement(BarSmall, Object.assign({}, props))]);
        break;

      default:
        {
          let taskItem = [];

          if ((task === null || task === void 0 ? void 0 : task.x1) >= 0 && (task === null || task === void 0 ? void 0 : task.x2) >= 0) {
            taskItem.push(React.createElement(Bar, Object.assign({}, props, {
              type: "planned"
            })));
          }

          if ((task === null || task === void 0 ? void 0 : task.actualx1) >= 0 && (task === null || task === void 0 ? void 0 : task.actualx2) >= 0) {
            taskItem.push(React.createElement(Bar, Object.assign({}, props, {
              type: "actual"
            })));
          }

          setTaskItem(taskItem);
        }
        break;
    }
  }, [task, isSelected]);
  return React.createElement("g", null, React.createElement("g", {
    onKeyDown: e => {
      switch (e.key) {
        case "Delete":
          {
            if (isDelete) onEventStart("delete", task, e, "planned");
            break;
          }
      }

      e.stopPropagation();
    },
    onMouseEnter: e => {
      onEventStart("mouseenter", task, e, "planned");
    },
    onMouseLeave: e => {
      onEventStart("mouseleave", task, e, "planned");
    },
    onDoubleClick: e => {
      onEventStart("dblclick", task, e, "planned");
    },
    onClick: e => {
      onEventStart("click", task, e, "planned");
    }
  }, taskItem[0]), React.createElement("g", {
    onKeyDown: e => {
      switch (e.key) {
        case "Delete":
          {
            if (isDelete) onEventStart("delete", task, e, "actual");
            break;
          }
      }

      e.stopPropagation();
    },
    onMouseEnter: e => {
      onEventStart("mouseenter", task, e, "actual");
    },
    onMouseLeave: e => {
      onEventStart("mouseleave", task, e, "actual");
    },
    onDoubleClick: e => {
      onEventStart("dblclick", task, e, "actual");
    },
    onClick: e => {
      onEventStart("click", task, e, "actual");
    }
  }, taskItem[1]));
};

const TaskGanttContent = _ref => {
  var _svg$current;

  let {
    tasks,
    dates,
    ganttEvent,
    selectedTask,
    rowHeight,
    columnWidth,
    timeStep,
    svg,
    taskHeight,
    arrowIndent,
    fontFamily,
    fontSize,
    rtl,
    virtualItems = [],
    setGanttEvent,
    setFailedTask,
    setSelectedTask,
    onBarTasksUpdate,
    onDateChange,
    onProgressChange,
    onDoubleClick,
    onClick,
    onDelete,
    onCalendarError,
    projectCalendar,
    visibleStartY,
    visibleEndY,
    sliderTime
  } = _ref;
  const point = svg === null || svg === void 0 ? void 0 : (_svg$current = svg.current) === null || _svg$current === void 0 ? void 0 : _svg$current.createSVGPoint();
  const [xStep, setXStep] = useState(0);
  const [initEventX1Delta, setInitEventX1Delta] = useState(0);
  const [isMoving, setIsMoving] = useState(false);
  useEffect(() => {
    if (dates.length < 2) {
      setXStep(timeStep * columnWidth / 86400000);
      return;
    }

    const dateDelta = dates[1].getTime() - dates[0].getTime() - dates[1].getTimezoneOffset() * 60 * 1000 + dates[0].getTimezoneOffset() * 60 * 1000;
    const newXStep = timeStep * columnWidth / dateDelta;
    setXStep(newXStep);
  }, [columnWidth, dates, timeStep]);
  useEffect(() => {
    const handleMouseMove = function (event) {
      try {
        var _svg$current$getScree;

        if (!ganttEvent.changedTask || !point || !(svg !== null && svg !== void 0 && svg.current)) return Promise.resolve();
        event.preventDefault();
        point.x = event.clientX;
        const cursor = point.matrixTransform(svg === null || svg === void 0 ? void 0 : (_svg$current$getScree = svg.current.getScreenCTM()) === null || _svg$current$getScree === void 0 ? void 0 : _svg$current$getScree.inverse());
        const {
          isChanged,
          changedTask
        } = handleTaskBySVGMouseEvent(cursor.x, ganttEvent.action, ganttEvent.changedTask, ganttEvent.type, xStep, timeStep, initEventX1Delta, rtl);

        if (isChanged) {
          let finalTask = { ...changedTask
          };
          const dragType = ganttEvent.type;

          if (changedTask.calendar && (ganttEvent.action === "end" || ganttEvent.action === "start" || ganttEvent.action === "move")) {
            const cal = finalTask.calendar;

            if (dragType === "actual") {
              if (ganttEvent.action === "end") {
                const snapped = snapToWorkingTime(finalTask.actualEnd, cal, "forward");
                finalTask.actualEnd = snapped;
                finalTask.actualx2 = taskXCoordinate(snapped, dates, columnWidth);
              } else if (ganttEvent.action === "start") {
                const snapped = snapToWorkingTime(finalTask.actualStart, cal, "forward");
                finalTask.actualStart = snapped;
                finalTask.actualx1 = taskXCoordinate(snapped, dates, columnWidth);
              } else {
                const snapped = snapToWorkingTime(finalTask.actualStart, cal, "forward");
                const delta = snapped.getTime() - finalTask.actualStart.getTime();
                finalTask.actualStart = snapped;
                finalTask.actualEnd = new Date(finalTask.actualEnd.getTime() + delta);
                finalTask.actualx1 = taskXCoordinate(finalTask.actualStart, dates, columnWidth);
                finalTask.actualx2 = taskXCoordinate(finalTask.actualEnd, dates, columnWidth);
              }

              const actEnd = addToDate(startOfDate(finalTask.actualEnd, "day"), 1, "day");
              const actIntervals = getWorkingIntervals(finalTask.actualStart, actEnd, cal);
              const actSegs = actIntervals.map(iv => ({
                x1: taskXCoordinate(iv.start, dates, columnWidth),
                x2: taskXCoordinate(iv.end, dates, columnWidth)
              })).filter(s => s.x2 > s.x1);
              finalTask.actualSegments = actSegs.length > 0 ? actSegs : undefined;
              const actDays = Math.max(1, Math.round((finalTask.actualEnd.getTime() - finalTask.actualStart.getTime()) / (1000 * 60 * 60 * 24)));
              finalTask.actualDuration = actDays;
            } else {
              if (ganttEvent.action === "end") {
                const snapped = snapToWorkingTime(finalTask.end, cal, "forward");
                finalTask.end = snapped;
                finalTask.x2 = taskXCoordinate(snapped, dates, columnWidth);
              } else if (ganttEvent.action === "start") {
                const snapped = snapToWorkingTime(finalTask.start, cal, "forward");
                finalTask.start = snapped;
                finalTask.x1 = taskXCoordinate(snapped, dates, columnWidth);
              } else {
                const snapped = snapToWorkingTime(finalTask.start, cal, "forward");
                const delta = snapped.getTime() - finalTask.start.getTime();
                finalTask.start = snapped;
                finalTask.end = new Date(finalTask.end.getTime() + delta);
                finalTask.x1 = taskXCoordinate(finalTask.start, dates, columnWidth);
                finalTask.x2 = taskXCoordinate(finalTask.end, dates, columnWidth);
              }

              const planEnd = addToDate(startOfDate(finalTask.end, "day"), 1, "day");
              const planIntervals = getWorkingIntervals(finalTask.start, planEnd, cal);
              const planSegs = planIntervals.map(iv => ({
                x1: taskXCoordinate(iv.start, dates, columnWidth),
                x2: taskXCoordinate(iv.end, dates, columnWidth)
              })).filter(s => s.x2 > s.x1);
              finalTask.plannedSegments = planSegs.length > 0 ? planSegs : undefined;
              const planDays = Math.max(1, Math.round((finalTask.end.getTime() - finalTask.start.getTime()) / (1000 * 60 * 60 * 24)));
              finalTask.plannedDuration = planDays;
            }
          } else {
            if (dragType === "actual") {
              const actDays = Math.max(1, Math.round((finalTask.actualEnd.getTime() - finalTask.actualStart.getTime()) / (1000 * 60 * 60 * 24)));
              finalTask.actualDuration = actDays;
            } else {
              const planDays = Math.max(1, Math.round((finalTask.end.getTime() - finalTask.start.getTime()) / (1000 * 60 * 60 * 24)));
              finalTask.plannedDuration = planDays;
            }
          }

          setGanttEvent({
            action: ganttEvent.action,
            changedTask: finalTask,
            type: dragType
          });
        }

        return Promise.resolve();
      } catch (e) {
        return Promise.reject(e);
      }
    };

    const handleMouseUp = function (event) {
      try {
        var _svg$current$getScree2;

        function _temp5() {
          if (!operationSuccess) {
            setFailedTask(originalSelectedTask);
          }
        }

        const {
          action,
          originalSelectedTask,
          changedTask,
          type
        } = ganttEvent;
        if (!changedTask || !point || !(svg !== null && svg !== void 0 && svg.current) || !originalSelectedTask) return Promise.resolve();
        event.preventDefault();
        point.x = event.clientX;
        const cursor = point.matrixTransform(svg === null || svg === void 0 ? void 0 : (_svg$current$getScree2 = svg.current.getScreenCTM()) === null || _svg$current$getScree2 === void 0 ? void 0 : _svg$current$getScree2.inverse());
        const {
          changedTask: newChangedTask
        } = handleTaskBySVGMouseEvent(cursor.x, action, changedTask, type, xStep, timeStep, initEventX1Delta, rtl);
        const isNotLikeOriginal = originalSelectedTask.start !== newChangedTask.start || originalSelectedTask.end !== newChangedTask.end || originalSelectedTask.actualStart !== newChangedTask.actualStart || originalSelectedTask.actualEnd !== newChangedTask.actualEnd || originalSelectedTask.progress !== newChangedTask.progress;
        const dropType = type;

        if (newChangedTask.calendar && (action === "move" || action === "end" || action === "start")) {
          const cal = newChangedTask.calendar;

          if (dropType === "actual") {
            if (action === "end") {
              const snappedEnd = snapToWorkingTime(newChangedTask.actualEnd, cal, "forward");
              newChangedTask.actualEnd = snappedEnd;
              newChangedTask.actualx2 = taskXCoordinate(snappedEnd, dates, columnWidth);
            } else if (action === "start") {
              const snappedStart = snapToWorkingTime(newChangedTask.actualStart, cal, "forward");

              if (snappedStart >= newChangedTask.actualEnd) {
                setFailedTask(originalSelectedTask);
                onCalendarError === null || onCalendarError === void 0 ? void 0 : onCalendarError(newChangedTask, "No working time in selected range");
                setGanttEvent({
                  action: ""
                });
                setIsMoving(false);
                svg.current.removeEventListener("mousemove", handleMouseMove);
                svg.current.removeEventListener("mouseup", handleMouseUp);
                return Promise.resolve();
              }

              newChangedTask.actualStart = snappedStart;
              newChangedTask.actualx1 = taskXCoordinate(snappedStart, dates, columnWidth);
            } else {
              const snappedStart = snapToWorkingTime(newChangedTask.actualStart, cal, "forward");
              const delta = snappedStart.getTime() - newChangedTask.actualStart.getTime();
              newChangedTask.actualStart = snappedStart;
              newChangedTask.actualEnd = new Date(newChangedTask.actualEnd.getTime() + delta);
              newChangedTask.actualx1 = taskXCoordinate(snappedStart, dates, columnWidth);
              newChangedTask.actualx2 = taskXCoordinate(newChangedTask.actualEnd, dates, columnWidth);
            }

            const actEnd = addToDate(startOfDate(newChangedTask.actualEnd, "day"), 1, "day");
            const actIntervals = getWorkingIntervals(newChangedTask.actualStart, actEnd, cal);
            const actSegs = actIntervals.map(iv => ({
              x1: taskXCoordinate(iv.start, dates, columnWidth),
              x2: taskXCoordinate(iv.end, dates, columnWidth)
            })).filter(s => s.x2 > s.x1);
            newChangedTask.actualSegments = actSegs.length > 0 ? actSegs : undefined;
            const actDays = Math.max(1, Math.round((newChangedTask.actualEnd.getTime() - newChangedTask.actualStart.getTime()) / (1000 * 60 * 60 * 24)));
            newChangedTask.actualDuration = actDays;
          } else {
            if (action === "end") {
              const snappedEnd = snapToWorkingTime(newChangedTask.end, cal, "forward");
              newChangedTask.end = snappedEnd;
              newChangedTask.x2 = taskXCoordinate(snappedEnd, dates, columnWidth);
            } else if (action === "start") {
              const snappedStart = snapToWorkingTime(newChangedTask.start, cal, "forward");

              if (snappedStart >= newChangedTask.end) {
                setFailedTask(originalSelectedTask);
                onCalendarError === null || onCalendarError === void 0 ? void 0 : onCalendarError(newChangedTask, "No working time in selected range");
                setGanttEvent({
                  action: ""
                });
                setIsMoving(false);
                svg.current.removeEventListener("mousemove", handleMouseMove);
                svg.current.removeEventListener("mouseup", handleMouseUp);
                return Promise.resolve();
              }

              newChangedTask.start = snappedStart;
              newChangedTask.x1 = taskXCoordinate(snappedStart, dates, columnWidth);
            } else {
              const snappedStart = snapToWorkingTime(newChangedTask.start, cal, "forward");
              const delta = snappedStart.getTime() - newChangedTask.start.getTime();
              newChangedTask.start = snappedStart;
              newChangedTask.end = new Date(newChangedTask.end.getTime() + delta);
              newChangedTask.x1 = taskXCoordinate(snappedStart, dates, columnWidth);
              newChangedTask.x2 = taskXCoordinate(newChangedTask.end, dates, columnWidth);
            }

            const planEnd = addToDate(startOfDate(newChangedTask.end, "day"), 1, "day");
            const planIntervals = getWorkingIntervals(newChangedTask.start, planEnd, cal);
            const planSegs = planIntervals.map(iv => ({
              x1: taskXCoordinate(iv.start, dates, columnWidth),
              x2: taskXCoordinate(iv.end, dates, columnWidth)
            })).filter(s => s.x2 > s.x1);
            newChangedTask.plannedSegments = planSegs.length > 0 ? planSegs : undefined;
            const planDays = Math.max(1, Math.round((newChangedTask.end.getTime() - newChangedTask.start.getTime()) / (1000 * 60 * 60 * 24)));
            newChangedTask.plannedDuration = planDays;
          }
        } else if (action === "move" || action === "end" || action === "start") {
          if (dropType === "actual") {
            const actDays = Math.max(1, Math.round((newChangedTask.actualEnd.getTime() - newChangedTask.actualStart.getTime()) / (1000 * 60 * 60 * 24)));
            newChangedTask.actualDuration = actDays;
          } else {
            const planDays = Math.max(1, Math.round((newChangedTask.end.getTime() - newChangedTask.start.getTime()) / (1000 * 60 * 60 * 24)));
            newChangedTask.plannedDuration = planDays;
          }
        }

        svg.current.removeEventListener("mousemove", handleMouseMove);
        svg.current.removeEventListener("mouseup", handleMouseUp);

        if (onBarTasksUpdate && isNotLikeOriginal) {
          onBarTasksUpdate(newChangedTask);
        }

        setGanttEvent({
          action: ""
        });
        setIsMoving(false);
        let operationSuccess = true;

        const _temp4 = function () {
          if ((action === "move" || action === "end" || action === "start") && onDateChange && isNotLikeOriginal) {
            const _temp = _catch(function () {
              return Promise.resolve(onDateChange(newChangedTask, newChangedTask.barChildren)).then(function (result) {
                if (result !== undefined) {
                  operationSuccess = result;
                }
              });
            }, function () {
              operationSuccess = false;
            });

            if (_temp && _temp.then) return _temp.then(function () {});
          } else {
            const _temp3 = function () {
              if (onProgressChange && isNotLikeOriginal) {
                const _temp2 = _catch(function () {
                  return Promise.resolve(onProgressChange(newChangedTask, newChangedTask.barChildren)).then(function (result) {
                    if (result !== undefined) {
                      operationSuccess = result;
                    }
                  });
                }, function () {
                  operationSuccess = false;
                });

                if (_temp2 && _temp2.then) return _temp2.then(function () {});
              }
            }();

            if (_temp3 && _temp3.then) return _temp3.then(function () {});
          }
        }();

        return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp5) : _temp5(_temp4));
      } catch (e) {
        return Promise.reject(e);
      }
    };

    if (!isMoving && (ganttEvent.action === "move" || ganttEvent.action === "end" || ganttEvent.action === "start" || ganttEvent.action === "progress") && svg !== null && svg !== void 0 && svg.current) {
      svg.current.addEventListener("mousemove", handleMouseMove);
      svg.current.addEventListener("mouseup", handleMouseUp);
      setIsMoving(true);
    }
  }, [ganttEvent, xStep, initEventX1Delta, onProgressChange, timeStep, onDateChange, onCalendarError, projectCalendar, svg, isMoving, point, rtl, setFailedTask, setGanttEvent, onBarTasksUpdate, dates, columnWidth]);

  const handleBarEventStart = function (action, task, event, type) {
    try {
      return Promise.resolve(function () {
        if (!event) {
          if (action === "select") {
            setSelectedTask(task.id);
          }
        } else return function () {
          if (isKeyboardEvent(event)) {
            const _temp8 = function () {
              if (action === "delete") {
                const _temp7 = function () {
                  if (onDelete) {
                    const _temp6 = _catch(function () {
                      return Promise.resolve(onDelete(task)).then(function (result) {
                        if (result !== undefined && result) {
                          setGanttEvent({
                            action,
                            changedTask: task
                          });
                        }
                      });
                    }, function (error) {
                      console.error("Error on Delete. " + error);
                    });

                    if (_temp6 && _temp6.then) return _temp6.then(function () {});
                  }
                }();

                if (_temp7 && _temp7.then) return _temp7.then(function () {});
              }
            }();

            if (_temp8 && _temp8.then) return _temp8.then(function () {});
          } else if (action === "mouseenter") {
            if (!ganttEvent.action) {
              setGanttEvent({
                action,
                changedTask: task,
                originalSelectedTask: task,
                type: type
              });
            }
          } else if (action === "mouseleave") {
            if (ganttEvent.action === "mouseenter") {
              setGanttEvent({
                action: ""
              });
            }
          } else if (action === "dblclick") {
            !!onDoubleClick && onDoubleClick(task);
          } else if (action === "click") {
            !!onClick && onClick(task);
          } else if (action === "move") {
            var _svg$current$getScree3;

            if (!(svg !== null && svg !== void 0 && svg.current) || !point) return;
            point.x = event.clientX;
            const cursor = point.matrixTransform((_svg$current$getScree3 = svg.current.getScreenCTM()) === null || _svg$current$getScree3 === void 0 ? void 0 : _svg$current$getScree3.inverse());
            if (type == "planned") setInitEventX1Delta(cursor.x - task.x1);else if (type == "actual") setInitEventX1Delta(cursor.x - task.actualx1);
            setGanttEvent({
              action,
              changedTask: task,
              originalSelectedTask: task,
              type: type
            });
          } else {
            setGanttEvent({
              action,
              changedTask: task,
              originalSelectedTask: task,
              type: type
            });
          }
        }();
      }());
    } catch (e) {
      return Promise.reject(e);
    }
  };

  const getArrows = (isCritical, criticalPathType) => {
    return tasks.flatMap(_task => {
      const a = ganttEvent.action;
      const isDraggingThis = (a === "move" || a === "start" || a === "end" || a === "progress") && !!ganttEvent.changedTask && ganttEvent.changedTask.id === _task.id;

      const _live = isDraggingThis ? { ...ganttEvent.changedTask,
        y: _task.y
      } : _task;

      const task = _live.start.getTime() > 0 && _live.end.getTime() > 0 ? _live : undefined;

      if (!task) {
        return [];
      }

      return task.barChildren.map(child => {
        const taskTo = tasks[child.index];
        const fromDrawable = task.x2 > task.x1 || task.actualx2 > task.actualx1;
        const toDrawable = !!taskTo && (taskTo.x2 > taskTo.x1 || taskTo.actualx2 > taskTo.actualx1);

        if (fromDrawable && toDrawable) {
          var _task$criticalPathArr;

          const criticalTask = (_task$criticalPathArr = task.criticalPathArrows) === null || _task$criticalPathArr === void 0 ? void 0 : _task$criticalPathArr.find(arrow => arrow.taskId === taskTo.id && (!!arrow.criticalPathType ? arrow.criticalPathType === criticalPathType : !criticalPathType));
          const yFrom = task.y + taskHeight / 2;
          const yTo = taskTo.y + taskHeight / 2;
          const minY = Math.min(yFrom, yTo);
          const maxY = Math.max(yFrom, yTo);

          if (maxY < visibleStartY || minY > visibleEndY) {
            return null;
          }

          if (!!criticalTask === isCritical) {
            return React.createElement(Arrow, {
              key: `Arrow from ${task.id} to ${taskTo.id}${isCritical ? "-critical" : ""}`,
              taskFrom: task,
              taskTo: taskTo,
              rowHeight: rowHeight,
              dependencyType: child.dependencyType,
              taskHeight: taskHeight,
              arrowIndent: arrowIndent,
              arrowColor: (criticalTask === null || criticalTask === void 0 ? void 0 : criticalTask.arrowColor) || "#808080"
            });
          }
        }

        return null;
      }).filter(Boolean);
    });
  };

  const lineX = sliderTime !== undefined ? taskXCoordinate(new Date(sliderTime), dates, columnWidth) : null;
  const totalHeight = tasks.length * rowHeight;
  return React.createElement("g", {
    className: "content"
  }, lineX !== null && lineX > 0 && React.createElement("line", {
    x1: lineX,
    y1: 0,
    x2: lineX,
    y2: totalHeight,
    stroke: "blue",
    strokeWidth: 2,
    pointerEvents: "none",
    opacity: 0.8
  }), React.createElement("g", {
    className: "arrows"
  }, getArrows(false), getArrows(true, "secondary"), getArrows(true, "primary")), React.createElement("g", {
    className: "bar",
    fontFamily: fontFamily,
    fontSize: fontSize
  }, virtualItems.map(vi => {
    const _task = tasks[vi.index];
    const task = ganttEvent.changedTask && ganttEvent.changedTask.id === _task.id ? { ...ganttEvent.changedTask,
      y: 0
    } : { ..._task,
      y: 0
    };

    if (!task && _task.typeInternal === "milestone") {
      return React.createElement("g", {
        key: _task.id,
        transform: `translate(0, ${vi.start})`
      }, React.createElement(Milestone, {
        task: task,
        arrowIndent: arrowIndent,
        taskHeight: taskHeight,
        isProgressChangeable: false,
        isDateChangeable: false,
        isDelete: !_task.isDisabled,
        onEventStart: handleBarEventStart,
        isSelected: !!selectedTask && _task.id === selectedTask.id,
        rtl: rtl
      }));
    }

    if (!task) {
      return React.createElement("g", {
        key: _task.id,
        transform: `translate(0, ${vi.start})`,
        style: {
          height: taskHeight
        }
      });
    }

    return React.createElement("g", {
      key: task.id,
      transform: `translate(0, ${vi.start})`
    }, React.createElement(TaskItem, {
      task: task,
      arrowIndent: arrowIndent,
      taskHeight: taskHeight,
      isProgressChangeable: !!onProgressChange && !task.isDisabled,
      isDateChangeable: !!onDateChange && !task.isDisabled,
      isDelete: !task.isDisabled,
      onEventStart: handleBarEventStart,
      isSelected: !!selectedTask && task.id === selectedTask.id,
      rtl: rtl
    }));
  })));
};

var styles$a = {"ganttVerticalContainer":"_CZjuD","horizontalContainer":"_2B2zv","wrapper":"_3eULf","alertContainer":"_2AxB2","success":"_1a-EU","warning":"_1TP0x","error":"_2TeAI","alertDismissCheckbox":"_3cBUj","alertCloseButton":"_5jQM6","spinner":"_3HJjy","spin":"_1W2rn"};

var TaskGantt = function TaskGantt(_ref) {
  var gridProps = _ref.gridProps,
      calendarProps = _ref.calendarProps,
      barProps = _ref.barProps,
      ganttHeight = _ref.ganttHeight,
      scrollY = _ref.scrollY,
      scrollX = _ref.scrollX;
  var ganttSVGRef = useRef(null);
  var horizontalContainerRef = useRef(null);
  var verticalGanttContainerRef = useRef(null);

  var newBarProps = _extends({}, barProps, {
    svg: ganttSVGRef,
    ganttHeight: ganttHeight,
    scrollY: scrollY
  });

  var buffer = barProps.rowHeight * 10;
  var visibleStartY = scrollY - buffer;
  var visibleEndY = scrollY + ganttHeight + buffer;
  var virtualizer = useVirtualizer({
    count: barProps.tasks.length,
    getScrollElement: function getScrollElement() {
      return horizontalContainerRef.current;
    },
    estimateSize: function estimateSize() {
      return barProps.rowHeight;
    },
    overscan: 10
  });
  useEffect(function () {
    if (horizontalContainerRef.current) {
      horizontalContainerRef.current.scrollTop = scrollY;
    }
  }, [scrollY]);
  useEffect(function () {
    if (verticalGanttContainerRef.current) {
      verticalGanttContainerRef.current.scrollLeft = scrollX;
    }
  }, [scrollX]);
  return React.createElement("div", {
    className: styles$a.ganttVerticalContainer,
    ref: verticalGanttContainerRef,
    dir: "ltr"
  }, React.createElement("svg", {
    xmlns: "http://www.w3.org/2000/svg",
    width: gridProps.svgWidth,
    height: calendarProps.headerHeight,
    fontFamily: barProps.fontFamily
  }, React.createElement(Calendar, Object.assign({}, calendarProps))), React.createElement("div", {
    ref: horizontalContainerRef,
    className: styles$a.horizontalContainer,
    style: ganttHeight ? {
      height: ganttHeight,
      width: gridProps.svgWidth
    } : {
      width: gridProps.svgWidth
    }
  }, React.createElement("svg", {
    xmlns: "http://www.w3.org/2000/svg",
    width: gridProps.svgWidth,
    height: virtualizer.getTotalSize(),
    fontFamily: barProps.fontFamily,
    ref: ganttSVGRef
  }, React.createElement(Grid, Object.assign({}, gridProps, {
    virtualItems: virtualizer.getVirtualItems(),
    visibleStartY: visibleStartY,
    visibleEndY: visibleEndY
  })), React.createElement(TaskGanttContent, Object.assign({}, newBarProps, {
    visibleStartY: visibleStartY,
    visibleEndY: visibleEndY,
    virtualItems: virtualizer.getVirtualItems()
  })))));
};

var hScrollStyles = {"scrollWrapper":"_2k9Ys","scroll":"_19jgW"};

var HorizontalScroll = function HorizontalScroll(_ref) {
  var scroll = _ref.scroll,
      svgWidth = _ref.svgWidth,
      taskListWidth = _ref.taskListWidth,
      rtl = _ref.rtl,
      onScroll = _ref.onScroll;
  var scrollRef = useRef(null);
  useEffect(function () {
    if (scrollRef.current) {
      scrollRef.current.scrollLeft = scroll;
    }
  }, [scroll]);
  return React.createElement("div", {
    dir: "ltr",
    style: {
      margin: rtl ? "0px " + taskListWidth + "px 0px 0px" : "0px 0px 0px " + taskListWidth + "px"
    },
    className: hScrollStyles.scrollWrapper,
    onScroll: onScroll,
    ref: scrollRef
  }, React.createElement("div", {
    style: {
      width: svgWidth
    },
    className: hScrollStyles.scroll
  }));
};

var GANTT_MIN_WIDTH_RATIO = 0.4;
var TABLE_GANTT_DIVIDER_WIDTH = 20;
var Gantt = function Gantt(_ref) {
  var _ref2;

  var tasks = _ref.tasks,
      primaryPath = _ref.primaryPath,
      secondaryPath = _ref.secondaryPath,
      _ref$leafTasks = _ref.leafTasks,
      leafTasks = _ref$leafTasks === void 0 ? [] : _ref$leafTasks,
      _ref$scheduleType = _ref.scheduleType,
      scheduleType = _ref$scheduleType === void 0 ? "main" : _ref$scheduleType,
      _ref$startDate = _ref.startDate,
      startDate = _ref$startDate === void 0 ? new Date() : _ref$startDate,
      _ref$endDate = _ref.endDate,
      endDate = _ref$endDate === void 0 ? new Date() : _ref$endDate,
      _ref$headerHeight = _ref.headerHeight,
      headerHeight = _ref$headerHeight === void 0 ? 50 : _ref$headerHeight,
      columnWidthProp = _ref.columnWidth,
      _ref$listCellWidth = _ref.listCellWidth,
      listCellWidth = _ref$listCellWidth === void 0 ? "155px" : _ref$listCellWidth,
      _ref$rowHeight = _ref.rowHeight,
      rowHeight = _ref$rowHeight === void 0 ? 50 : _ref$rowHeight,
      _ref$ganttHeight = _ref.ganttHeight,
      ganttHeight = _ref$ganttHeight === void 0 ? 0 : _ref$ganttHeight,
      _ref$viewMode = _ref.viewMode,
      viewMode = _ref$viewMode === void 0 ? ViewMode.Day : _ref$viewMode,
      _ref$preStepsCount = _ref.preStepsCount,
      preStepsCount = _ref$preStepsCount === void 0 ? 1 : _ref$preStepsCount,
      _ref$locale = _ref.locale,
      locale = _ref$locale === void 0 ? "en-US" : _ref$locale,
      _ref$barFill = _ref.barFill,
      barFill = _ref$barFill === void 0 ? 60 : _ref$barFill,
      _ref$barCornerRadius = _ref.barCornerRadius,
      barCornerRadius = _ref$barCornerRadius === void 0 ? 3 : _ref$barCornerRadius,
      _ref$barProgressColor = _ref.barProgressColor,
      barProgressColor = _ref$barProgressColor === void 0 ? "#a3a3ff" : _ref$barProgressColor,
      _ref$barProgressSelec = _ref.barProgressSelectedColor,
      barProgressSelectedColor = _ref$barProgressSelec === void 0 ? "#8282f5" : _ref$barProgressSelec,
      _ref$barBackgroundCol = _ref.barBackgroundColor,
      barBackgroundColor = _ref$barBackgroundCol === void 0 ? "#b8c2cc" : _ref$barBackgroundCol,
      _ref$barBackgroundSel = _ref.barBackgroundSelectedColor,
      barBackgroundSelectedColor = _ref$barBackgroundSel === void 0 ? "#aeb8c2" : _ref$barBackgroundSel,
      _ref$projectProgressC = _ref.projectProgressColor,
      projectProgressColor = _ref$projectProgressC === void 0 ? "#7db59a" : _ref$projectProgressC,
      _ref$projectProgressS = _ref.projectProgressSelectedColor,
      projectProgressSelectedColor = _ref$projectProgressS === void 0 ? "#59a985" : _ref$projectProgressS,
      _ref$projectBackgroun = _ref.projectBackgroundColor,
      projectBackgroundColor = _ref$projectBackgroun === void 0 ? "#fac465" : _ref$projectBackgroun,
      _ref$projectBackgroun2 = _ref.projectBackgroundSelectedColor,
      projectBackgroundSelectedColor = _ref$projectBackgroun2 === void 0 ? "#f7bb53" : _ref$projectBackgroun2,
      _ref$milestoneBackgro = _ref.milestoneBackgroundColor,
      milestoneBackgroundColor = _ref$milestoneBackgro === void 0 ? "#f1c453" : _ref$milestoneBackgro,
      _ref$milestoneBackgro2 = _ref.milestoneBackgroundSelectedColor,
      milestoneBackgroundSelectedColor = _ref$milestoneBackgro2 === void 0 ? "#f29e4c" : _ref$milestoneBackgro2,
      _ref$rtl = _ref.rtl,
      rtl = _ref$rtl === void 0 ? false : _ref$rtl,
      _ref$handleWidth = _ref.handleWidth,
      handleWidth = _ref$handleWidth === void 0 ? 8 : _ref$handleWidth,
      _ref$timeStep = _ref.timeStep,
      timeStep = _ref$timeStep === void 0 ? 300000 : _ref$timeStep,
      _ref$arrowColor = _ref.arrowColor,
      arrowColor = _ref$arrowColor === void 0 ? "grey" : _ref$arrowColor,
      _ref$fontFamily = _ref.fontFamily,
      fontFamily = _ref$fontFamily === void 0 ? "Arial, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue" : _ref$fontFamily,
      _ref$fontSize = _ref.fontSize,
      fontSize = _ref$fontSize === void 0 ? "14px" : _ref$fontSize,
      _ref$arrowIndent = _ref.arrowIndent,
      arrowIndent = _ref$arrowIndent === void 0 ? 20 : _ref$arrowIndent,
      _ref$todayColor = _ref.todayColor,
      todayColor = _ref$todayColor === void 0 ? "rgba(252, 248, 227, 0.5)" : _ref$todayColor,
      _ref$weekendColor = _ref.weekendColor,
      weekendColor = _ref$weekendColor === void 0 ? "#e6e4e4" : _ref$weekendColor,
      viewDate = _ref.viewDate,
      _ref$TooltipContent = _ref.TooltipContent,
      TooltipContent = _ref$TooltipContent === void 0 ? StandardTooltipContent : _ref$TooltipContent,
      _ref$TaskListHeader = _ref.TaskListHeader,
      TaskListHeader = _ref$TaskListHeader === void 0 ? TaskListHeaderDefault : _ref$TaskListHeader,
      _ref$TaskListTable = _ref.TaskListTable,
      TaskListTable = _ref$TaskListTable === void 0 ? TaskListTableDefault : _ref$TaskListTable,
      onDateChange = _ref.onDateChange,
      onProgressChange = _ref.onProgressChange,
      onDoubleClick = _ref.onDoubleClick,
      onClick = _ref.onClick,
      onDelete = _ref.onDelete,
      onSelect = _ref.onSelect,
      onExpanderClick = _ref.onExpanderClick,
      onMultiSelect = _ref.onMultiSelect,
      taskLabelRenderer = _ref.taskLabelRenderer,
      _ref$delayToRender = _ref.delayToRender,
      delayToRender = _ref$delayToRender === void 0 ? 500 : _ref$delayToRender,
      _ref$shouldNotShowLoa = _ref.shouldNotShowLoadingOverlay,
      shouldNotShowLoadingOverlay = _ref$shouldNotShowLoa === void 0 ? true : _ref$shouldNotShowLoa,
      projectCalendar = _ref.projectCalendar,
      onCalendarError = _ref.onCalendarError,
      sliderTime = _ref.sliderTime;
  var wrapperRef = useRef(null);
  var taskListRef = useRef(null);
  var isDraggingTable = useRef(false);
  var userResizedRef = useRef(false);
  var dragStartX = useRef(0);
  var dragStartWidth = useRef(0);
  var dragMaxWidth = useRef(Infinity);

  var _useState = useState(null),
      tableContainerWidth = _useState[0],
      setTableContainerWidth = _useState[1];

  var tableInnerScrollRef = useRef(null);
  var tableHorizontalContainerRef = useRef(null);
  var tableHScrollRef = useRef(null);

  var _useState2 = useState(0),
      tableContentWidth = _useState2[0],
      setTableContentWidth = _useState2[1];

  var _useState3 = useState(function () {
    var _ganttDateRange = ganttDateRange(tasks, viewMode, preStepsCount),
        startDateRange = _ganttDateRange[0],
        endDateRange = _ganttDateRange[1];

    if (scheduleType === "lookAhead") {
      return {
        viewMode: viewMode,
        dates: seedDates(startDate, endDate, viewMode)
      };
    }

    return {
      viewMode: viewMode,
      dates: seedDates(startDateRange, endDateRange, viewMode)
    };
  }),
      dateSetup = _useState3[0],
      setDateSetup = _useState3[1];

  var _useState4 = useState(undefined),
      currentViewDate = _useState4[0],
      setCurrentViewDate = _useState4[1];

  var _useState5 = useState(0),
      taskListWidth = _useState5[0],
      setTaskListWidth = _useState5[1];

  var _useState6 = useState(0),
      wrapperWidth = _useState6[0],
      setWrapperWidth = _useState6[1];

  var maxTableWidth = wrapperWidth > 0 ? Math.max(100, wrapperWidth * (1 - GANTT_MIN_WIDTH_RATIO) - TABLE_GANTT_DIVIDER_WIDTH) : Infinity;
  var tableCap = Math.min(maxTableWidth, tableContentWidth > 0 ? tableContentWidth : Infinity);

  var handleTableResizeMouseDown = function handleTableResizeMouseDown(e) {
    var _taskListRef$current$, _taskListRef$current;

    isDraggingTable.current = true;
    userResizedRef.current = true;
    dragStartX.current = e.clientX;
    dragStartWidth.current = tableContainerWidth != null ? tableContainerWidth : (_taskListRef$current$ = (_taskListRef$current = taskListRef.current) === null || _taskListRef$current === void 0 ? void 0 : _taskListRef$current.offsetWidth) != null ? _taskListRef$current$ : 0;
    dragMaxWidth.current = tableCap;
    e.preventDefault();
  };

  useEffect(function () {
    var onMouseMove = function onMouseMove(e) {
      if (!isDraggingTable.current) return;
      var newWidth = Math.min(dragMaxWidth.current, Math.max(100, dragStartWidth.current + (e.clientX - dragStartX.current)));
      setTableContainerWidth(newWidth);
      setTaskListWidth(newWidth);
    };

    var onMouseUp = function onMouseUp() {
      isDraggingTable.current = false;
    };

    document.addEventListener("mousemove", onMouseMove);
    document.addEventListener("mouseup", onMouseUp);
    return function () {
      document.removeEventListener("mousemove", onMouseMove);
      document.removeEventListener("mouseup", onMouseUp);
    };
  }, []);

  var _useState7 = useState(0),
      svgContainerWidth = _useState7[0],
      setSvgContainerWidth = _useState7[1];

  var _useState8 = useState(ganttHeight),
      svgContainerHeight = _useState8[0],
      setSvgContainerHeight = _useState8[1];

  var _useState9 = useState([]),
      barTasks = _useState9[0],
      setBarTasks = _useState9[1];

  var debounceRef = useRef(null);

  var _useState10 = useState({
    action: ""
  }),
      ganttEvent = _useState10[0],
      setGanttEvent = _useState10[1];

  var handleBarTasksUpdate = function handleBarTasksUpdate(task) {
    setBarTasks(function (prev) {
      return prev.map(function (t) {
        return t.id === task.id ? task : t;
      });
    });
  };

  var taskHeight = useMemo(function () {
    return rowHeight * barFill / 100;
  }, [rowHeight, barFill]);

  var _useState11 = useState(),
      selectedTask = _useState11[0],
      setSelectedTask = _useState11[1];

  var _useState12 = useState(null),
      failedTask = _useState12[0],
      setFailedTask = _useState12[1];

  var _useState13 = useState(null),
      computedColumnWidth = _useState13[0],
      setComputedColumnWidth = _useState13[1];

  var computedForViewModeRef = useRef(null);
  useEffect(function () {
    if (columnWidthProp != null) return;
    if (svgContainerWidth <= 0) return;
    var minVisible = VIEW_MODE_DEFAULT_VISIBLE_COUNT[viewMode];
    if (!minVisible) return;
    var maxVisible = VIEW_MODE_MAX_VISIBLE_COUNT[viewMode];
    var prevViewMode = computedForViewModeRef.current;

    if (prevViewMode != null && prevViewMode !== viewMode && computedColumnWidth != null) {
      var visible = svgContainerWidth / computedColumnWidth;
      var oldMin = VIEW_MODE_DEFAULT_VISIBLE_COUNT[prevViewMode];
      var oldMax = VIEW_MODE_MAX_VISIBLE_COUNT[prevViewMode];
      var _next = computedColumnWidth;

      if (maxVisible && oldMin != null && oldMax != null && oldMax > oldMin) {
        var t = Math.min(1, Math.max(0, (visible - oldMin) / (oldMax - oldMin)));
        var targetVisible = minVisible + t * (maxVisible - minVisible);
        _next = Math.floor(svgContainerWidth / targetVisible);
      } else if (visible < minVisible) {
        _next = Math.floor(svgContainerWidth / minVisible);
      } else if (maxVisible && visible > maxVisible) {
        _next = Math.ceil(svgContainerWidth / maxVisible);
      }

      _next = Math.max(20, _next);
      computedForViewModeRef.current = viewMode;
      userResizedRef.current = true;

      if (_next !== computedColumnWidth) {
        setComputedColumnWidth(_next);
      }

      return;
    }

    var alreadySnappedForView = computedForViewModeRef.current === viewMode && computedColumnWidth != null;
    if (userResizedRef.current && alreadySnappedForView) return;
    var next = Math.max(20, Math.floor(svgContainerWidth / minVisible));
    computedForViewModeRef.current = viewMode;

    if (next !== computedColumnWidth) {
      setComputedColumnWidth(next);
    }
  }, [viewMode, svgContainerWidth, columnWidthProp, computedColumnWidth]);
  var columnWidth = (_ref2 = columnWidthProp != null ? columnWidthProp : computedColumnWidth) != null ? _ref2 : 60;
  var effectiveColumnWidth = useMemo(function () {
    if (svgContainerWidth <= 0 || dateSetup.dates.length <= 0) return columnWidth;

    if (columnWidthProp == null) {
      var maxVisible = VIEW_MODE_MAX_VISIBLE_COUNT[viewMode];

      if (maxVisible) {
        return Math.max(columnWidth, Math.ceil(svgContainerWidth / maxVisible));
      }

      return columnWidth;
    }

    return Math.max(columnWidth, Math.ceil(svgContainerWidth / dateSetup.dates.length));
  }, [columnWidth, columnWidthProp, viewMode, svgContainerWidth, dateSetup.dates.length]);
  var svgWidth = effectiveColumnWidth < 55 ? (dateSetup.dates.length + 0.5) * effectiveColumnWidth : dateSetup.dates.length * effectiveColumnWidth;
  var ganttFullHeight = useMemo(function () {
    return barTasks.length * rowHeight;
  }, [barTasks.length, rowHeight]);

  var _useState14 = useState(0),
      scrollY = _useState14[0],
      setScrollY = _useState14[1];

  var _useState15 = useState(-1),
      scrollX = _useState15[0],
      setScrollX = _useState15[1];

  var _useState16 = useState(false),
      ignoreScrollEvent = _useState16[0],
      setIgnoreScrollEvent = _useState16[1];

  var _useState17 = useState(0),
      lastTouchX = _useState17[0],
      setLastTouchX = _useState17[1];

  var _useState18 = useState(0),
      lastTouchY = _useState18[0],
      setLastTouchY = _useState18[1];

  var _useState19 = useState(false),
      isProcessing = _useState19[0],
      setIsProcessing = _useState19[1];

  var buffer = rowHeight * 10;
  var visibleStartY = scrollY - buffer;
  var visibleEndY = scrollY + ganttHeight + buffer;
  useEffect(function () {
    if (scheduleType === "lookAhead" && startDate && endDate) {
      setDateSetup({
        viewMode: viewMode,
        dates: seedDates(startDate, endDate, viewMode)
      });
    }
  }, [startDate, endDate]);
  useEffect(function () {
    if (debounceRef.current) {
      clearTimeout(debounceRef.current);
    }

    if (!shouldNotShowLoadingOverlay) {
      setIsProcessing(true);
    }

    debounceRef.current = setTimeout(function () {
      var _projectCalendar$quar;

      var filteredTasks;
      filteredTasks = removeHiddenTasks(tasks);
      filteredTasks = filteredTasks.sort(sortTasks);

      var _ganttDateRange2 = ganttDateRange(filteredTasks, viewMode, preStepsCount, (_projectCalendar$quar = projectCalendar === null || projectCalendar === void 0 ? void 0 : projectCalendar.quarter_start) != null ? _projectCalendar$quar : 0),
          startDateRange = _ganttDateRange2[0],
          endDateRange = _ganttDateRange2[1];

      var newDates = seedDates(startDateRange, endDateRange, viewMode);

      if (scheduleType === "lookAhead") {
        newDates = seedDates(startDate, endDate, viewMode);
      }

      if (rtl) {
        newDates = newDates.reverse();

        if (scrollX === -1) {
          setScrollX(newDates.length * effectiveColumnWidth);
        }
      }

      if (scheduleType !== "lookAhead") {
        setDateSetup({
          dates: seedDates(startDateRange, endDateRange, viewMode),
          viewMode: viewMode
        });
      }

      uncolorAll(tasks);

      if (scheduleType !== "lookAhead") {
        colorPath(secondaryPath, "#00ff00", tasks, "secondary");
        colorPath(primaryPath, "#ff0000", tasks, "primary");
      }

      setBarTasks(convertToBarTasks(filteredTasks, newDates, effectiveColumnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, rtl, barProgressColor, barProgressSelectedColor, barBackgroundColor, barBackgroundSelectedColor, projectProgressColor, projectProgressSelectedColor, projectBackgroundColor, projectBackgroundSelectedColor, milestoneBackgroundColor, milestoneBackgroundSelectedColor));
      setIsProcessing(false);
    }, delayToRender);
  }, [tasks, viewMode, preStepsCount, rowHeight, barCornerRadius, taskHeight, handleWidth, barProgressColor, barProgressSelectedColor, barBackgroundColor, barBackgroundSelectedColor, projectProgressColor, projectProgressSelectedColor, projectBackgroundColor, projectBackgroundSelectedColor, milestoneBackgroundColor, milestoneBackgroundSelectedColor, rtl, shouldNotShowLoadingOverlay, effectiveColumnWidth, projectCalendar]);
  useEffect(function () {
    return function () {
      clearTimeout(debounceRef.current);
    };
  }, []);
  useEffect(function () {
    if (viewMode === dateSetup.viewMode && (viewDate && !currentViewDate || viewDate && (currentViewDate === null || currentViewDate === void 0 ? void 0 : currentViewDate.valueOf()) !== viewDate.valueOf())) {
      var dates = dateSetup.dates;
      var index = dates.findIndex(function (d, i) {
        return viewDate.valueOf() >= d.valueOf() && i + 1 !== dates.length && viewDate.valueOf() < dates[i + 1].valueOf();
      });

      if (index === -1) {
        return;
      }

      setCurrentViewDate(viewDate);
      setScrollX(effectiveColumnWidth * index);
    }
  }, [viewDate, effectiveColumnWidth, dateSetup.dates, dateSetup.viewMode, viewMode, currentViewDate, setCurrentViewDate]);
  useEffect(function () {
    var changedTask = ganttEvent.changedTask,
        action = ganttEvent.action;

    if (changedTask) {
      if (action === "delete") {
        setGanttEvent({
          action: ""
        });
        setBarTasks(barTasks.filter(function (t) {
          return t.id !== changedTask.id;
        }));
      }
    }
  }, [ganttEvent, barTasks]);
  useEffect(function () {
    if (failedTask) {
      setBarTasks(barTasks.map(function (t) {
        return t.id !== failedTask.id ? t : failedTask;
      }));
      setFailedTask(null);
    }
  }, [failedTask, barTasks]);
  useEffect(function () {
    if (!listCellWidth) {
      setTaskListWidth(0);
    }

    if (taskListRef.current) {
      setTaskListWidth(taskListRef.current.offsetWidth);
    }
  }, [taskListRef, listCellWidth]);
  useEffect(function () {
    if (!listCellWidth || !taskListRef.current) return;
    if (typeof ResizeObserver === "undefined") return;

    var measure = function measure() {
      if (taskListRef.current) {
        setTaskListWidth(taskListRef.current.offsetWidth);
      }
    };

    var observer = new ResizeObserver(measure);
    observer.observe(taskListRef.current);
    measure();
    return function () {
      return observer.disconnect();
    };
  }, [listCellWidth, scheduleType]);
  useEffect(function () {
    if (wrapperRef.current) {
      setSvgContainerWidth(wrapperRef.current.offsetWidth - taskListWidth - 20);
    }
  }, [wrapperRef, taskListWidth, wrapperWidth]);
  useEffect(function () {
    var node = wrapperRef.current;
    if (!node) return;

    if (typeof ResizeObserver === "undefined") {
      setWrapperWidth(node.offsetWidth);
      return;
    }

    var measure = function measure() {
      return setWrapperWidth(node.offsetWidth);
    };

    var observer = new ResizeObserver(measure);
    observer.observe(node);
    measure();
    return function () {
      return observer.disconnect();
    };
  }, []);
  useEffect(function () {
    if (ganttHeight) {
      setSvgContainerHeight(ganttHeight + headerHeight);
    } else {
      setSvgContainerHeight(tasks.length * rowHeight + headerHeight);
    }
  }, [ganttHeight, tasks, headerHeight, rowHeight]);
  useEffect(function () {
    var _wrapperRef$current, _wrapperRef$current2, _wrapperRef$current3, _wrapperRef$current4;

    var handleWheel = function handleWheel(event) {
      if (event.shiftKey || event.deltaX) {
        var scrollMove = event.deltaX ? event.deltaX : event.deltaY;
        var newScrollX = scrollX + scrollMove;

        if (newScrollX < 0) {
          newScrollX = 0;
        } else if (newScrollX > svgWidth) {
          newScrollX = svgWidth;
        }

        setScrollX(newScrollX);
        event.preventDefault();
      } else if (ganttHeight) {
        var newScrollY = scrollY + event.deltaY;

        if (newScrollY < 0) {
          newScrollY = 0;
        } else if (newScrollY > ganttFullHeight - ganttHeight) {
          newScrollY = ganttFullHeight - ganttHeight;
        }

        if (newScrollY !== scrollY) {
          setScrollY(newScrollY);
          event.preventDefault();
        }
      }

      setIgnoreScrollEvent(true);
    };

    var handleLogTouch = function handleLogTouch(event) {
      if (event) {
        setLastTouchX(event.changedTouches[0].pageX);
        setLastTouchY(event.changedTouches[0].pageY);
      }
    };

    var handleTouch = function handleTouch(event) {
      if (event.changedTouches[0].pageX || event.changedTouches[0].pageY) {
        var deltaX = event.changedTouches[0].pageX - lastTouchX;
        var deltaY = event.changedTouches[0].pageY - lastTouchY;

        if (Math.abs(deltaX) > Math.abs(deltaY)) {
          var newScrollX = scrollX - deltaX / 3;

          if (newScrollX > 0 && newScrollX < 1600) {
            setScrollX(newScrollX);
          } else if (newScrollX < 0) {
            setScrollX(0);
          } else {
            setScrollX(1600);
          }
        } else {
          var newScrollY = scrollY - deltaY;

          if (newScrollY > 0 && newScrollY < 1600) {
            setScrollY(newScrollY);
          } else if (newScrollY < 0) {
            setScrollY(0);
          } else {
            setScrollY(1600);
          }
        }

        setLastTouchX(event.changedTouches[0].pageX);
        setLastTouchY(event.changedTouches[0].pageY);
      }

      setIgnoreScrollEvent(true);
    };

    (_wrapperRef$current = wrapperRef.current) === null || _wrapperRef$current === void 0 ? void 0 : _wrapperRef$current.addEventListener("wheel", handleWheel, {
      passive: false
    });
    (_wrapperRef$current2 = wrapperRef.current) === null || _wrapperRef$current2 === void 0 ? void 0 : _wrapperRef$current2.addEventListener("touchmove", handleTouch, {
      passive: false
    });
    (_wrapperRef$current3 = wrapperRef.current) === null || _wrapperRef$current3 === void 0 ? void 0 : _wrapperRef$current3.addEventListener("touchstart", handleLogTouch, {
      passive: false
    });
    (_wrapperRef$current4 = wrapperRef.current) === null || _wrapperRef$current4 === void 0 ? void 0 : _wrapperRef$current4.addEventListener("touchend", handleLogTouch, {
      passive: false
    });
    return function () {
      var _wrapperRef$current5, _wrapperRef$current6, _wrapperRef$current7, _wrapperRef$current8;

      (_wrapperRef$current5 = wrapperRef.current) === null || _wrapperRef$current5 === void 0 ? void 0 : _wrapperRef$current5.removeEventListener("wheel", handleWheel);
      (_wrapperRef$current6 = wrapperRef.current) === null || _wrapperRef$current6 === void 0 ? void 0 : _wrapperRef$current6.removeEventListener("touchmove", handleTouch);
      (_wrapperRef$current7 = wrapperRef.current) === null || _wrapperRef$current7 === void 0 ? void 0 : _wrapperRef$current7.removeEventListener("touchend", handleLogTouch);
      (_wrapperRef$current8 = wrapperRef.current) === null || _wrapperRef$current8 === void 0 ? void 0 : _wrapperRef$current8.removeEventListener("touchend", handleLogTouch);
    };
  }, [wrapperRef, scrollY, scrollX, ganttHeight, svgWidth, rtl, ganttFullHeight]);

  var handleScrollY = function handleScrollY(event) {
    if (scrollY !== event.currentTarget.scrollTop && !ignoreScrollEvent) {
      setScrollY(event.currentTarget.scrollTop);
      setIgnoreScrollEvent(true);
    } else {
      setIgnoreScrollEvent(false);
    }
  };

  var handleScrollX = function handleScrollX(event) {
    if (scrollX !== event.currentTarget.scrollLeft && !ignoreScrollEvent) {
      setScrollX(event.currentTarget.scrollLeft);
      setIgnoreScrollEvent(true);
    } else {
      setIgnoreScrollEvent(false);
    }
  };

  var handleKeyDown = function handleKeyDown(event) {
    event.preventDefault();
    var newScrollY = scrollY;
    var newScrollX = scrollX;
    var isX = true;

    switch (event.key) {
      case "Down":
      case "ArrowDown":
        newScrollY += rowHeight;
        isX = false;
        break;

      case "Up":
      case "ArrowUp":
        newScrollY -= rowHeight;
        isX = false;
        break;

      case "Left":
      case "ArrowLeft":
        newScrollX -= effectiveColumnWidth;
        break;

      case "Right":
      case "ArrowRight":
        newScrollX += effectiveColumnWidth;
        break;
    }

    if (isX) {
      if (newScrollX < 0) {
        newScrollX = 0;
      } else if (newScrollX > svgWidth) {
        newScrollX = svgWidth;
      }

      setScrollX(newScrollX);
    } else {
      if (newScrollY < 0) {
        newScrollY = 0;
      } else if (newScrollY > ganttFullHeight - ganttHeight) {
        newScrollY = ganttFullHeight - ganttHeight;
      }

      setScrollY(newScrollY);
    }

    setIgnoreScrollEvent(true);
  };

  var handleSelectedTask = function handleSelectedTask(taskId) {
    var newSelectedTask = barTasks.find(function (t) {
      return t.id === taskId;
    });
    var oldSelectedTask = barTasks.find(function (t) {
      return !!selectedTask && t.id === selectedTask.id;
    });

    if (onSelect) {
      if (oldSelectedTask) {
        onSelect(oldSelectedTask, false);
      }

      if (newSelectedTask) {
        onSelect(newSelectedTask, true);
      }
    }

    setSelectedTask(newSelectedTask);
  };

  var handleExpanderClick = function handleExpanderClick(task) {
    if (onExpanderClick && task.hideChildren !== undefined) {
      onExpanderClick(_extends({}, task, {
        hideChildren: !task.hideChildren
      }));
    }
  };

  var gridProps = {
    columnWidth: effectiveColumnWidth,
    svgWidth: svgWidth,
    tasks: tasks,
    scheduleType: scheduleType,
    rowHeight: rowHeight,
    dates: dateSetup.dates,
    todayColor: todayColor,
    weekendColor: weekendColor,
    rtl: rtl,
    visibleStartY: visibleStartY,
    visibleEndY: visibleEndY,
    projectCalendar: projectCalendar,
    viewMode: viewMode
  };
  var calendarProps = {
    dateSetup: dateSetup,
    locale: locale,
    viewMode: viewMode,
    headerHeight: headerHeight,
    columnWidth: effectiveColumnWidth,
    fontFamily: fontFamily,
    fontSize: fontSize,
    rtl: rtl,
    projectCalendar: projectCalendar,
    weekendColor: weekendColor
  };
  var barProps = {
    tasks: barTasks,
    dates: dateSetup.dates,
    ganttEvent: ganttEvent,
    selectedTask: selectedTask,
    rowHeight: rowHeight,
    taskHeight: taskHeight,
    columnWidth: effectiveColumnWidth,
    arrowColor: arrowColor,
    timeStep: timeStep,
    fontFamily: fontFamily,
    fontSize: fontSize,
    arrowIndent: arrowIndent,
    svgWidth: svgWidth,
    rtl: rtl,
    setGanttEvent: setGanttEvent,
    setFailedTask: setFailedTask,
    setSelectedTask: handleSelectedTask,
    onBarTasksUpdate: handleBarTasksUpdate,
    onDateChange: onDateChange,
    onProgressChange: onProgressChange,
    onDoubleClick: onDoubleClick,
    onClick: onClick,
    onDelete: onDelete,
    onCalendarError: onCalendarError,
    projectCalendar: projectCalendar,
    visibleStartY: visibleStartY,
    visibleEndY: visibleEndY,
    sliderTime: sliderTime
  };
  var tableTasks = useMemo(function () {
    return ganttEvent.changedTask ? barTasks.map(function (t) {
      return t.id === ganttEvent.changedTask.id ? ganttEvent.changedTask : t;
    }) : barTasks;
  }, [barTasks, ganttEvent.changedTask]);
  var tableProps = {
    rowHeight: rowHeight,
    rowWidth: listCellWidth,
    fontFamily: fontFamily,
    fontSize: fontSize,
    tasks: tableTasks,
    leafTasks: leafTasks,
    scheduleType: scheduleType,
    locale: locale,
    headerHeight: headerHeight,
    scrollY: scrollY,
    ganttHeight: ganttHeight,
    horizontalContainerClass: styles$a.horizontalContainer,
    selectedTask: selectedTask,
    taskListRef: taskListRef,
    setSelectedTask: handleSelectedTask,
    onExpanderClick: handleExpanderClick,
    onDoubleClick: onDoubleClick,
    TaskListHeader: TaskListHeader,
    TaskListTable: TaskListTable,
    taskLabelRenderer: taskLabelRenderer,
    onMultiSelect: onMultiSelect,
    containerWidth: userResizedRef.current && tableContainerWidth != null ? Math.min(tableContainerWidth, tableCap) : undefined,
    containerMaxWidth: tableCap === Infinity ? undefined : tableCap,
    onContentWidthChange: setTableContentWidth,
    innerScrollRef: tableInnerScrollRef,
    horizontalContainerRef: tableHorizontalContainerRef
  };
  return React.createElement("div", {
    style: {
      position: "relative"
    }
  }, React.createElement("div", {
    className: styles$a.wrapper,
    onKeyDown: handleKeyDown,
    tabIndex: 0,
    ref: wrapperRef
  }, listCellWidth && React.createElement(TaskList, Object.assign({}, tableProps)), listCellWidth && scheduleType === "main" && React.createElement("div", {
    style: {
      width: "20px",
      cursor: "col-resize",
      backgroundColor: "#e0e0e0",
      flexShrink: 0,
      zIndex: 1,
      alignSelf: "stretch",
      display: "flex",
      alignItems: "center",
      justifyContent: "center",
      userSelect: "none",
      fontSize: "10px",
      color: "#666",
      letterSpacing: "-1px"
    },
    onMouseDown: handleTableResizeMouseDown
  }, "\u25C4|\u25BA"), React.createElement(TaskGantt, {
    gridProps: gridProps,
    calendarProps: calendarProps,
    barProps: barProps,
    ganttHeight: ganttHeight,
    scrollY: scrollY,
    scrollX: scrollX
  }), ganttEvent.changedTask && React.createElement(Tooltip, {
    arrowIndent: arrowIndent,
    rowHeight: rowHeight,
    svgContainerHeight: svgContainerHeight,
    svgContainerWidth: svgContainerWidth,
    fontFamily: fontFamily,
    fontSize: fontSize,
    scrollX: scrollX,
    scrollY: scrollY,
    task: ganttEvent.changedTask,
    type: ganttEvent.type,
    headerHeight: headerHeight,
    taskListWidth: taskListWidth,
    TooltipContent: TooltipContent,
    rtl: rtl,
    svgWidth: svgWidth,
    isDragging: ganttEvent.action === "move" || ganttEvent.action === "start" || ganttEvent.action === "end" || ganttEvent.action === "progress"
  }), React.createElement(VerticalScroll, {
    ganttFullHeight: ganttFullHeight,
    ganttHeight: ganttHeight,
    headerHeight: headerHeight,
    scroll: scrollY,
    onScroll: handleScrollY,
    rtl: rtl
  })), isProcessing && React.createElement("div", {
    style: {
      position: "absolute",
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
      backgroundColor: "rgba(255, 255, 255, 0.95)",
      display: "flex",
      justifyContent: "center",
      alignItems: "center",
      gap: "20px",
      zIndex: 9999,
      pointerEvents: "none",
      borderRadius: "8px"
    }
  }, React.createElement("span", {
    style: {
      fontSize: "24px",
      fontWeight: "600",
      color: "#cc0404",
      fontFamily: "Arial, sans-serif"
    }
  }, "Loading..."), React.createElement("div", {
    className: styles$a.spinner
  })), React.createElement("div", {
    style: {
      display: "flex"
    }
  }, listCellWidth && React.createElement("div", {
    ref: tableHScrollRef,
    className: hScrollStyles.scrollWrapper,
    style: {
      width: taskListWidth + 4,
      flexShrink: 0
    },
    onScroll: function onScroll(e) {
      if (tableHorizontalContainerRef.current) {
        tableHorizontalContainerRef.current.scrollLeft = e.currentTarget.scrollLeft;
      }
    }
  }, React.createElement("div", {
    style: {
      width: tableContentWidth
    }
  })), React.createElement("div", {
    style: {
      flex: 1,
      minWidth: 0
    }
  }, React.createElement(HorizontalScroll, {
    svgWidth: svgWidth,
    taskListWidth: 0,
    scroll: scrollX,
    rtl: rtl,
    onScroll: handleScrollX
  }))));
};
function topologicalOrderingHelper(taskID, taskMap, sortedTaskList) {
  if (!taskMap[taskID]) return true;
  if (taskMap[taskID].finished) return true;

  if (taskMap[taskID].started) {
    console.log("Cycle involving " + taskID);
    return false;
  }

  taskMap[taskID].started = true;
  var task = taskMap[taskID].task;
  if (task.dependencies) for (var i = 0; i < task.dependencies.length; i++) {
    var successVal = topologicalOrderingHelper(task.dependencies[i].id, taskMap, sortedTaskList);
    if (!successVal) return false;
  }
  taskMap[taskID].finished = true;
  sortedTaskList.push(taskID);
  return true;
}
function getCriticalPaths(leafTasks) {
  leafTasks = leafTasks.filter(function (t) {
    return t.type !== "milestone" && (t.start.getTime() !== 0 || t.end.getTime() !== 0);
  });
  var taskMap = {};

  for (var i = 0; i < leafTasks.length; i++) {
    taskMap[leafTasks[i].id] = {
      task: leafTasks[i]
    };
  }

  var sortedTaskList = [];

  for (var _i = 0; _i < leafTasks.length; _i++) {
    var successVal = topologicalOrderingHelper(leafTasks[_i].id, taskMap, sortedTaskList);
    if (!successVal) return [[], []];
  }

  for (var _i2 = 0; _i2 < leafTasks.length; _i2++) {
    taskMap[leafTasks[_i2].id].dependents = [];
  }

  for (var _i3 = 0; _i3 < leafTasks.length; _i3++) {
    var task = leafTasks[_i3];
    if (task.dependencies) for (var j = 0; j < task.dependencies.length; j++) {
      var _taskMap$task$depende;

      (_taskMap$task$depende = taskMap[task.dependencies[j].id]) === null || _taskMap$task$depende === void 0 ? void 0 : _taskMap$task$depende.dependents.push(task.id);
    }
  }

  for (var _i4 = (sortedTaskList === null || sortedTaskList === void 0 ? void 0 : sortedTaskList.length) - 1; _i4 >= 0; _i4--) {
    computeCriticalPath(sortedTaskList[_i4], taskMap);
  }

  var taskChainList = [];

  for (var _i5 = 0; _i5 < (sortedTaskList === null || sortedTaskList === void 0 ? void 0 : sortedTaskList.length); _i5++) {
    for (var _j = 0; _j < taskMap[sortedTaskList[_i5]].paths.length; _j++) {
      taskChainList.push(taskMap[sortedTaskList[_i5]].paths[_j]);
    }
  }

  if (taskChainList.length > 0) {
    taskChainList.sort(function (a, b) {
      return b.duration - a.duration;
    });
    var primaryLeaf = taskChainList[0].parent;
    var primaryPath = [];

    while (primaryLeaf !== undefined) {
      primaryPath.push(taskMap[primaryLeaf].task);

      if (taskMap[primaryLeaf].paths.length === 0) {
        primaryLeaf = undefined;
        break;
      }

      var primaryDuration = taskMap[primaryLeaf].paths[0].duration;
      var nextPath = taskMap[primaryLeaf].paths[0];

      for (var _i6 = 1; _i6 < taskMap[primaryLeaf].paths.length; _i6++) {
        var newDuration = taskMap[primaryLeaf].paths[_i6].duration;

        if (newDuration > primaryDuration) {
          nextPath = taskMap[primaryLeaf].paths[_i6];
          primaryDuration = newDuration;
        }
      }

      nextPath.visited = true;
      primaryLeaf = nextPath.task;
    }

    var secondaryLeaf = taskChainList[0].parent;

    for (var _i7 = 0; _i7 < taskChainList.length; _i7++) {
      if (!taskChainList[_i7].visited) {
        secondaryLeaf = taskChainList[_i7].parent;
        break;
      }
    }

    var secondaryPath = [];

    while (secondaryLeaf !== undefined) {
      secondaryPath.push(taskMap[secondaryLeaf].task);

      if (taskMap[secondaryLeaf].paths.length === 0) {
        secondaryLeaf = undefined;
        break;
      }

      var secondaryDuration = taskMap[secondaryLeaf].paths[0].duration;
      var _nextPath = taskMap[secondaryLeaf].paths[0];
      if (_nextPath.visited) secondaryDuration = 0;

      for (var _i8 = 1; _i8 < taskMap[secondaryLeaf].paths.length; _i8++) {
        var _newDuration = taskMap[secondaryLeaf].paths[_i8].duration;

        if (_newDuration > secondaryDuration && !taskMap[secondaryLeaf].paths[_i8].visited) {
          _nextPath = taskMap[secondaryLeaf].paths[_i8];
          secondaryDuration = _newDuration;
        }
      }

      if (_nextPath.visited) {
        break;
      }

      _nextPath.visited = true;
      secondaryLeaf = _nextPath.task;
    }

    console.debug("Primary", primaryPath);
    console.debug("Secondary", secondaryPath);
    return [primaryPath, secondaryPath];
  }

  return [[], []];
}
function computeCriticalPath(taskID, taskMap) {
  var task = taskMap[taskID].task;
  var dependents = taskMap[taskID].dependents;
  taskMap[taskID].start = task.start.getTime();
  taskMap[taskID].end = task.end.getTime();
  taskMap[taskID].paths = [];

  for (var j = 0; j < dependents.length; j++) {
    var depStart = taskMap[dependents[j]].task.start.getTime();
    var depEnd = taskMap[dependents[j]].task.end.getTime();
    var depDuration = depEnd - depStart;
    var startWeek = Math.floor((depStart / 86400000 + 4) / 7);
    var endWeek = Math.floor((depEnd / 86400000 + 4) / 7);
    var offTime = 0;

    if (taskMap[dependents[j]].task.calendar) {
      if (taskMap[dependents[j]].task.calendar.off_days && taskMap[dependents[j]].task.calendar.off_days.length) {
        for (var d = 0; d < taskMap[dependents[j]].task.calendar.off_days.length || 0; d++) {
          for (var w = startWeek; w <= endWeek; w++) {
            var dayOfTheWeek = taskMap[dependents[j]].task.calendar.off_days[d];
            var offDay = 86400000 * (7 * w - 4 + dayOfTheWeek);

            if (offDay >= depStart && offDay <= depEnd && (offDay > taskMap[taskID].end || taskMap[taskID].task.calendar.off_days.includes(dayOfTheWeek))) {
              offTime += 86400000;
            }
          }
        }
      }

      if (taskMap[dependents[j]].task.calendar.holidays && taskMap[dependents[j]].task.calendar.holidays.length) {
        for (var h = 0; h < taskMap[dependents[j]].task.calendar.holidays.length || 0; h++) {
          var holiday = taskMap[dependents[j]].task.calendar.holidays[h];

          if (holiday >= depStart && holiday <= depEnd) {
            offTime += 86400000;
          }
        }
      }
    }

    var overlap = Math.max(taskMap[taskID].end - depStart, 0);
    var paths = taskMap[dependents[j]].paths;

    if (paths && paths.length) {
      for (var k = 0; k < paths.length; k++) {
        var totalDuration = taskMap[taskID].end - taskMap[taskID].start - overlap - offTime + paths[k].duration;

        if (taskMap[taskID].paths.length < 2) {
          taskMap[taskID].paths.push({
            duration: totalDuration,
            task: dependents[j],
            parent: taskID,
            visited: false
          });
        } else if (totalDuration > taskMap[taskID].paths[0].duration) {
          taskMap[taskID].paths[0].duration = totalDuration;
          taskMap[taskID].paths[0].task = dependents[j];
          taskMap[taskID].paths[0].parent = taskID;
          taskMap[taskID].paths[0].visited = false;
        } else if (totalDuration > taskMap[taskID].paths[1].duration) {
          taskMap[taskID].paths[1].duration = totalDuration;
          taskMap[taskID].paths[1].task = dependents[j];
          taskMap[taskID].paths[1].parent = taskID;
          taskMap[taskID].paths[1].visited = false;
        }
      }
    } else {
      var immediateChildDuration = taskMap[taskID].end - taskMap[taskID].start + depDuration - overlap - offTime;

      if (taskMap[taskID].paths.length < 2) {
        taskMap[taskID].paths.push({
          duration: immediateChildDuration,
          task: dependents[j],
          parent: taskID,
          visited: false
        });
      } else if (immediateChildDuration > taskMap[taskID].paths[0].duration) {
        taskMap[taskID].paths[0].duration = immediateChildDuration;
        taskMap[taskID].paths[0].task = dependents[j];
        taskMap[taskID].paths[0].parent = taskID;
        taskMap[taskID].paths[0].visited = false;
      } else if (immediateChildDuration > taskMap[taskID].paths[1].duration) {
        taskMap[taskID].paths[1].duration = immediateChildDuration;
        taskMap[taskID].paths[1].task = dependents[j];
        taskMap[taskID].paths[1].parent = taskID;
        taskMap[taskID].paths[1].visited = false;
      }
    }
  }
}
function uncolorAll(tasks) {
  tasks.forEach(function (task) {
    if (task.styles) delete task.styles.criticalPathColor;
    delete task.criticalPathArrows;
  });
}
function colorPath(path, color, tasks, criticalPathType) {
  for (var i = 0; i < path.length; i++) {
    var longestIDLength = 0;
    var longestTask = void 0;

    for (var j = 0; j < tasks.length; j++) {
      if (path[i].id === tasks[j].id) {
        longestTask = tasks[j];
        break;
      }

      if (path[i].id.startsWith(tasks[j].id + ".") && tasks[j].id.length > longestIDLength) {
        longestIDLength = tasks[j].id.length;
        longestTask = tasks[j];
      }
    }

    if (longestTask) {
      var _longestTask$styles;

      var _styles = (_longestTask$styles = longestTask.styles) != null ? _longestTask$styles : {};

      _styles.criticalPathColor = color;
      longestTask.styles = _styles;
    }
  }

  var _loop = function _loop(_i9) {
    var taskFromTasks = void 0;

    for (var _j2 = 0; _j2 < tasks.length; _j2++) {
      if (path[_i9].id === tasks[_j2].id) {
        taskFromTasks = tasks[_j2];
        break;
      }
    }

    if (taskFromTasks) {
      var arrows = taskFromTasks.criticalPathArrows;
      if (!arrows) arrows = [];
      var arrow = arrows.find(function (arrow) {
        return arrow.taskId === path[_i9 + 1].id;
      });

      if (arrow) {
        arrow.arrowColor = color;
        arrow.criticalPathType = criticalPathType;
      } else arrows.push({
        taskId: path[_i9 + 1].id,
        arrowColor: color,
        criticalPathType: criticalPathType
      });

      taskFromTasks.criticalPathArrows = arrows;
    }
  };

  for (var _i9 = 0; _i9 + 1 < path.length; _i9++) {
    _loop(_i9);
  }
}
var getParentWbs = function getParentWbs(wbs) {
  var segments = wbs.split('.');
  if (segments.length <= 1) return undefined;
  return segments.slice(0, -1).join('.');
};

export { Gantt, ViewMode, getCriticalPaths };
//# sourceMappingURL=index.modern.js.map