UNPKG

hy-vue-gantt

Version:

Evolution of vue-ganttastic package

6,866 lines 275 kB
import dayjs from "dayjs";
import isoWeek from "dayjs/plugin/isoWeek";
import isSameOrBefore from "dayjs/plugin/isSameOrBefore.js";
import isSameOrAfter from "dayjs/plugin/isSameOrAfter.js";
import isBetween from "dayjs/plugin/isBetween.js";
import weekOfYear from "dayjs/plugin/weekOfYear";
import advancedFormat from "dayjs/plugin/advancedFormat";
import customParseFormat from "dayjs/plugin/customParseFormat.js";
import dayOfYear from "dayjs/plugin/dayOfYear.js";
import localizedFormat from "dayjs/plugin/localizedFormat";
import utc from "dayjs/plugin/utc";
import { inject, computed, defineComponent, openBlock, createElementBlock, unref, Fragment, renderList, normalizeStyle, normalizeClass, ref, reactive, onMounted, createElementVNode, renderSlot, createTextVNode, toDisplayString, createVNode, createCommentVNode, watch, toRefs, createBlock, Teleport, Transition, withCtx, nextTick, withDirectives, vModelText, provide, resolveComponent, withModifiers, mergeProps, TransitionGroup, createSlots, useTemplateRef, normalizeProps, guardReactiveProps, useCssVars, useSlots, toRef, onUnmounted, resolveDynamicComponent, isRef, createStaticVNode, vModelSelect, h } from "vue";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { faChevronDown, faChevronRight, faSort, faArrowDownAZ, faArrowDownZA, faAngleUp, faAngleDown, faExpandAlt, faCompressAlt, faAnglesLeft, faAngleLeft, faAngleRight, faAnglesRight, faMagnifyingGlassMinus, faMagnifyingGlassPlus, faUndo, faRedo, faFileExport, faSpinner } from "@fortawesome/free-solid-svg-icons";
import { useIntervalFn, useMouseInElement, useElementBounding, computedWithControl, watchThrottled, useElementSize } from "@vueuse/core";
import { v4 } from "uuid";
import Holidays from "date-holidays";
import { cloneDeep } from "lodash-es";
import html2canvas from "html2canvas";
import jsPDF from "jspdf";
import * as XLSX from "xlsx";
import "dayjs/locale/it";
import "dayjs/locale/en";
import "dayjs/locale/fr";
import "dayjs/locale/de";
import "dayjs/locale/es";
import "dayjs/locale/pt";
import "dayjs/locale/ru";
import "dayjs/locale/zh-cn";
import "dayjs/locale/zh-tw";
import "dayjs/locale/ja";
import "dayjs/locale/ko";
import "dayjs/locale/ar";
import "dayjs/locale/hi";
import "dayjs/locale/tr";
import "dayjs/locale/nl";
import "dayjs/locale/pl";
import "dayjs/locale/cs";
import "dayjs/locale/hu";
import "dayjs/locale/ro";
import "dayjs/locale/bg";
import "dayjs/locale/sr";
import "dayjs/locale/sr-cyrl";
import "dayjs/locale/af";
import "dayjs/locale/az";
import "dayjs/locale/be";
import "dayjs/locale/bs";
import "dayjs/locale/ca";
import "dayjs/locale/da";
import "dayjs/locale/el";
import "dayjs/locale/et";
import "dayjs/locale/fi";
import "dayjs/locale/gl";
import "dayjs/locale/he";
import "dayjs/locale/hr";
import "dayjs/locale/is";
import "dayjs/locale/ka";
import "dayjs/locale/kk";
import "dayjs/locale/ky";
import "dayjs/locale/lt";
import "dayjs/locale/lv";
import "dayjs/locale/mk";
import "dayjs/locale/mn";
import "dayjs/locale/mt";
import "dayjs/locale/nb";
import "dayjs/locale/nn";
import "dayjs/locale/pt-br";
import "dayjs/locale/sk";
import "dayjs/locale/sl";
import "dayjs/locale/sq";
import "dayjs/locale/sv";
import "dayjs/locale/ta";
import "dayjs/locale/th";
import "dayjs/locale/uk";
import "dayjs/locale/uz";
import "dayjs/locale/vi";
import "dayjs/locale/zh-hk";
const CONFIG_KEY = Symbol("CONFIG_KEY");
const BOOLEAN_KEY = Symbol("BOOLEAN_KEY");
const EMIT_BAR_EVENT_KEY = Symbol("EMIT_BAR_EVENT_KEY");
const BAR_CONTAINER_KEY = Symbol("BAR_CONTAINER_KEY");
const CHART_AREA_KEY = Symbol("CHART_AREA_KEY");
const CHART_WRAPPER_KEY = Symbol("CHART_WRAPPER_KEY");
const GANTT_ID_KEY = Symbol("GANTT_ID_KEY");
function provideConfig() {
  const config = inject(CONFIG_KEY);
  if (!config) {
    throw Error("Failed to inject config!");
  }
  return config;
}
const DEFAULT_DATE_FORMAT = "YYYY-MM-DD HH:mm";
function useDayjsHelper(config = provideConfig()) {
  const { chartStart, chartEnd, barStart, barEnd, dateFormat, locale } = config;
  const chartStartDayjs = computed(() => toDayjs(chartStart.value));
  const chartEndDayjs = computed(() => toDayjs(chartEnd.value));
  dayjs.locale(locale.value);
  const toDayjs = (input, startOrEnd) => {
    let value;
    if (startOrEnd !== void 0 && typeof input !== "string" && !(input instanceof Date)) {
      value = startOrEnd === "start" ? input[barStart.value] : input[barEnd.value];
    }
    if (typeof input === "string") {
      value = input;
    } else if (input instanceof Date) {
      return dayjs(input);
    }
    const format2 = dateFormat.value || DEFAULT_DATE_FORMAT;
    return dayjs(value, format2, true);
  };
  const format = (input, pattern) => {
    if (pattern === false) {
      return input instanceof Date ? input : dayjs(input).toDate();
    }
    const inputDayjs = typeof input === "string" || input instanceof Date ? toDayjs(input) : input;
    return inputDayjs.format(pattern);
  };
  const diffDates = () => {
    return chartEndDayjs.value.diff(chartStartDayjs.value, "day");
  };
  return {
    chartStartDayjs,
    chartEndDayjs,
    toDayjs,
    format,
    diffDates
  };
}
const _hoisted_1$a = {
  class: "g-grid-container",
  ref: "time"
};
const _sfc_main$c = /* @__PURE__ */ defineComponent({
  __name: "GGanttGrid",
  props: {
    timeaxisUnits: {},
    internalPrecision: {}
  },
  setup(__props) {
    const props = __props;
    const { toDayjs } = useDayjsHelper();
    const {
      colors,
      highlightedHours,
      highlightedDaysInWeek,
      highlightedDaysInMonth,
      highlightedMonths,
      highlightedWeek,
      enableMinutes
    } = provideConfig();
    const highlightLine = (date) => {
      if (props.internalPrecision === "hour") {
        return isHighlightedHour(date) || isHighlightedDay(date) || isHighlightedMonth(date) || isHighlightedWeek(date);
      }
      if (props.internalPrecision === "day" || props.internalPrecision === "date") {
        return isHighlightedDay(date) || isHighlightedMonth(date) || isHighlightedWeek(date);
      }
      if (props.internalPrecision === "week") {
        return isHighlightedWeek(date) || isHighlightedMonth(date);
      }
      if (props.internalPrecision === "month") {
        return isHighlightedMonth(date);
      }
      return false;
    };
    const isHighlightedHour = (date) => highlightedHours == null ? void 0 : highlightedHours.value.includes(date.getHours());
    const isHighlightedDay = (date) => {
      return (highlightedDaysInWeek == null ? void 0 : highlightedDaysInWeek.value.includes(date.getDay())) || (highlightedDaysInMonth == null ? void 0 : highlightedDaysInMonth.value.includes(date.getDate()));
    };
    const isHighlightedWeek = (date) => highlightedWeek == null ? void 0 : highlightedWeek.value.includes(toDayjs(date).week());
    const isHighlightedMonth = (date) => highlightedMonths == null ? void 0 : highlightedMonths.value.includes(date.getMonth());
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", _hoisted_1$a, [
        !unref(enableMinutes) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(_ctx.timeaxisUnits.result.lowerUnits, ({ label, date, width }, index) => {
          return openBlock(), createElementBlock("div", {
            key: `${label}_${index}`,
            class: "g-grid-line",
            style: normalizeStyle({
              width,
              borderLeft: `1px solid ${unref(colors).gridAndBorder}`,
              background: highlightLine(date) ? unref(colors).hoverHighlight : void 0
            })
          }, null, 4);
        }), 128)) : (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(_ctx.timeaxisUnits.result.lowerUnits, ({ label, date, width }, index) => {
          return openBlock(), createElementBlock(Fragment, {
            key: `${label}_${index}`
          }, [
            (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.timeaxisUnits.globalMinuteStep, (step) => {
              return openBlock(), createElementBlock("div", {
                key: `${date}-${step}`,
                class: normalizeClass([step, "g-grid-line step"]),
                style: normalizeStyle({
                  width,
                  borderLeft: `1px solid ${unref(colors).gridAndBorder}`,
                  background: highlightLine(date) ? unref(colors).hoverHighlight : void 0
                })
              }, null, 6);
            }), 128))
          ], 64);
        }), 128))
      ], 512);
    };
  }
});
function useRowDragAndDrop(rows, isSorted, updateRows, emit) {
  const dragState = ref({
    isDragging: false,
    draggedRow: null,
    dropTarget: {
      row: null,
      position: "before"
    }
  });
  const originalOrder = ref(/* @__PURE__ */ new Map());
  const isValidDrop = (source, target) => {
    const isParentOfTarget = (row) => {
      var _a;
      if (!((_a = row.children) == null ? void 0 : _a.length)) return false;
      return row.children.some((child) => child === target || isParentOfTarget(child));
    };
    return !isParentOfTarget(source);
  };
  const handleDragStart = (row, event) => {
    if (isSorted.value) return;
    dragState.value.isDragging = true;
    dragState.value.draggedRow = row;
    if (event.dataTransfer) {
      event.dataTransfer.effectAllowed = "move";
      event.dataTransfer.setData("text/plain", "");
    }
    if (originalOrder.value.size === 0) {
      rows.value.forEach((row2, index) => {
        if (row2.id) {
          originalOrder.value.set(row2.id, index);
        }
      });
    }
  };
  const handleDragOver = (row, event) => {
    var _a;
    if (!dragState.value.draggedRow || !isValidDrop(dragState.value.draggedRow, row)) {
      return;
    }
    event.preventDefault();
    const rect = event.currentTarget.getBoundingClientRect();
    const mouseY = event.clientY - rect.top;
    if ((_a = row.children) == null ? void 0 : _a.length) {
      if (mouseY < rect.height * 0.25) {
        dragState.value.dropTarget = { row, position: "before" };
      } else if (mouseY > rect.height * 0.75) {
        dragState.value.dropTarget = { row, position: "after" };
      } else {
        dragState.value.dropTarget = { row, position: "child" };
      }
    } else {
      dragState.value.dropTarget = {
        row,
        position: mouseY < rect.height / 2 ? "before" : "after"
      };
    }
  };
  const isDescendant = (parent, potentialChild) => {
    if (!parent.children) {
      return false;
    }
    return parent.children.some(
      (child) => child.id === potentialChild.id || isDescendant(child, potentialChild)
    );
  };
  const findRowIndexById = (rows2, id) => {
    var _a;
    for (let i = 0; i < rows2.length; i++) {
      if (rows2[i].id === id) {
        return [i, rows2];
      }
      if ((_a = rows2[i].children) == null ? void 0 : _a.length) {
        const [index, parentRows] = findRowIndexById(rows2[i].children, id);
        if (index !== -1) {
          return [index, parentRows];
        }
      }
    }
    return [-1, rows2];
  };
  const handleDrop = () => {
    const { draggedRow, dropTarget } = dragState.value;
    if (!draggedRow || !dropTarget.row || isSorted.value || draggedRow === dropTarget.row) {
      return;
    }
    if (isDescendant(draggedRow, dropTarget.row)) {
      return;
    }
    const [sourceIndex, sourceParentRows] = findRowIndexById(rows.value, draggedRow.id);
    const [targetIndex, targetParentRows] = findRowIndexById(rows.value, dropTarget.row.id);
    if (sourceIndex === -1 || targetIndex === -1) {
      return;
    }
    const [removed] = sourceParentRows.splice(sourceIndex, 1);
    const insertIndex = dropTarget.position === "after" ? targetIndex + 1 : targetIndex;
    targetParentRows.splice(insertIndex, 0, removed);
    updateRows([...rows.value]);
    emit("row-drop", {
      sourceRow: draggedRow,
      targetRow: dropTarget.row,
      newIndex: insertIndex,
      parentId: targetParentRows === rows.value ? void 0 : dropTarget.row.id
    });
    dragState.value = {
      isDragging: false,
      draggedRow: null,
      dropTarget: { row: null, position: "before" }
    };
  };
  const resetOrder = () => {
    if (originalOrder.value.size === 0) return;
    rows.value.sort((a, b) => {
      const aIndex = a.id ? originalOrder.value.get(a.id) ?? 0 : 0;
      const bIndex = b.id ? originalOrder.value.get(b.id) ?? 0 : 0;
      return aIndex - bIndex;
    });
  };
  return {
    dragState,
    handleDragStart,
    handleDragOver,
    handleDrop,
    resetOrder,
    isDescendant,
    findRowIndexById
  };
}
function useColumnTouchResize() {
  const touchState = ref({
    isResizing: false,
    startX: 0,
    currentColumn: null,
    initialWidth: 0
  });
  const resetTouchState = () => {
    touchState.value = {
      isResizing: false,
      startX: 0,
      currentColumn: null,
      initialWidth: 0
    };
  };
  const handleTouchStart = (e, column, currentWidth) => {
    const touch = e.touches[0];
    if (!touch) return;
    e.preventDefault();
    touchState.value = {
      isResizing: true,
      startX: touch.clientX,
      currentColumn: column,
      initialWidth: currentWidth
    };
  };
  const handleTouchMove = (e, onResize) => {
    const touch = e.touches[0];
    if (!touch || !touchState.value.isResizing) return;
    e.preventDefault();
    const deltaX = touch.clientX - touchState.value.startX;
    const newWidth = Math.max(50, touchState.value.initialWidth + deltaX);
    if (touchState.value.currentColumn) {
      onResize(touchState.value.currentColumn, newWidth);
    }
  };
  const handleTouchEnd = () => {
    if (touchState.value.isResizing) {
      resetTouchState();
    }
  };
  const handleTouchCancel = handleTouchEnd;
  return {
    touchState,
    handleTouchStart,
    handleTouchMove,
    handleTouchEnd,
    handleTouchCancel
  };
}
function useRowTouchDrag() {
  const touchState = ref({
    isDragging: false,
    startY: 0,
    currentY: 0,
    draggedRow: null,
    dropTarget: {
      row: null,
      position: "before"
    },
    dragElement: null,
    initialTransform: ""
  });
  const resetTouchState = () => {
    if (touchState.value.dragElement) {
      touchState.value.dragElement.style.transform = touchState.value.initialTransform;
    }
    touchState.value = {
      isDragging: false,
      startY: 0,
      currentY: 0,
      draggedRow: null,
      dropTarget: {
        row: null,
        position: "before"
      },
      dragElement: null,
      initialTransform: ""
    };
  };
  const handleTouchStart = (event, row, element) => {
    const touch = event.touches[0];
    if (!touch) return;
    setTimeout(() => {
      if (touchState.value.isDragging) {
        event.preventDefault();
      }
    }, 100);
    touchState.value = {
      isDragging: true,
      startY: touch.clientY,
      currentY: touch.clientY,
      draggedRow: row,
      dropTarget: {
        row: null,
        position: "before"
      },
      dragElement: element,
      initialTransform: element.style.transform || ""
    };
  };
  const handleTouchMove = (event, targetRow, rowElement) => {
    var _a;
    const touch = event.touches[0];
    if (!touch || !touchState.value.isDragging || !touchState.value.dragElement) return;
    event.preventDefault();
    touchState.value.currentY = touch.clientY;
    const deltaY = touch.clientY - touchState.value.startY;
    touchState.value.dragElement.style.transform = `translateY(${deltaY}px)`;
    const rect = rowElement.getBoundingClientRect();
    const relativeY = touch.clientY - rect.top;
    const position = relativeY / rect.height;
    if (touchState.value.draggedRow !== targetRow) {
      if ((_a = targetRow.children) == null ? void 0 : _a.length) {
        if (position < 0.25) {
          touchState.value.dropTarget = { row: targetRow, position: "before" };
        } else if (position > 0.75) {
          touchState.value.dropTarget = { row: targetRow, position: "after" };
        } else {
          touchState.value.dropTarget = { row: targetRow, position: "child" };
        }
      } else {
        touchState.value.dropTarget = {
          row: targetRow,
          position: position < 0.5 ? "before" : "after"
        };
      }
    }
  };
  const handleTouchEnd = (event) => {
    if (!touchState.value.isDragging) return null;
    const touch = event.changedTouches[0];
    if (!touch) return null;
    const result = {
      sourceRow: touchState.value.draggedRow,
      dropTarget: touchState.value.dropTarget,
      dropPosition: touchState.value.dropTarget.position
    };
    resetTouchState();
    return result;
  };
  return {
    touchState,
    handleTouchStart,
    handleTouchMove,
    handleTouchEnd,
    resetTouchState
  };
}
const _hoisted_1$9 = ["onClick"];
const _hoisted_2$6 = { class: "text-ellipsis" };
const _hoisted_3$6 = {
  key: 0,
  class: "sort-icon"
};
const _hoisted_4$5 = ["onMousedown", "onTouchstart"];
const _hoisted_5$4 = ["data-row-id", "draggable", "onDragstart", "onDragover", "onTouchstart", "onTouchmove"];
const _hoisted_6$4 = { class: "g-label-column-row-inner" };
const _hoisted_7$4 = ["onClick"];
const _hoisted_8$4 = { class: "text-ellipsis-value" };
const LONG_PRESS_DURATION = 500;
const INDENT_WIDTH = 24;
const _sfc_main$b = /* @__PURE__ */ defineComponent({
  __name: "GGanttLabelColumn",
  emits: ["scroll", "row-drop"],
  setup(__props, { expose: __expose, emit: __emit }) {
    const emit = __emit;
    const rowManager = inject("useRows");
    if (!rowManager) {
      throw new Error("useRows does not provide ");
    }
    const { rows, sortState, toggleSort } = rowManager;
    const {
      font,
      colors,
      labelColumnTitle,
      labelColumnWidth,
      rowHeight,
      maxRows,
      multiColumnLabel,
      precision,
      barStart,
      barEnd,
      dateFormat,
      rowLabelClass,
      labelResizable,
      enableRowDragAndDrop,
      hideTimeaxis,
      sortable,
      showEventsAxis,
      eventsAxisHeight
    } = provideConfig();
    const { toDayjs, format } = useDayjsHelper();
    const columnWidths = reactive(/* @__PURE__ */ new Map());
    const isDragging = ref(false);
    const dragStartX = ref(0);
    const draggedColumn = ref(null);
    const labelContainer = ref(null);
    const {
      dragState,
      handleDragStart: handleRowDragStart,
      handleDragOver,
      handleDrop
    } = useRowDragAndDrop(
      rows,
      computed(() => sortState.value.direction !== "none"),
      rowManager.updateRows,
      (_event, payload) => emit("row-drop", payload)
    );
    const { touchState, handleTouchStart, handleTouchMove, handleTouchEnd, handleTouchCancel } = useColumnTouchResize();
    const {
      touchState: rowTouchState,
      handleTouchStart: handleRowTouchStart,
      handleTouchMove: handleRowTouchMove,
      handleTouchEnd: handleRowTouchEnd,
      resetTouchState: resetRowTouchState
    } = useRowTouchDrag();
    const columns = computed(() => {
      var _a;
      if (!((_a = multiColumnLabel.value) == null ? void 0 : _a.length) || !labelColumnTitle.value) {
        return [{ field: "Label", sortable: sortable.value }];
      }
      const filteredColumns = multiColumnLabel.value.filter((col) => col.field !== "Label");
      const labelColumn = { field: "Label", sortable: sortable.value };
      return [labelColumn, ...filteredColumns];
    });
    const totalWidth = computed(() => {
      let total = 0;
      columnWidths.forEach((width) => total += width);
      return total;
    });
    const getProcessedRows = computed(() => {
      const processRows = (rows2, level = 0) => {
        return rows2.flatMap((row) => {
          var _a;
          const processedRow = {
            ...row,
            indentLevel: level
          };
          const isExpanded = row.id ? rowManager.isGroupExpanded(row.id) : false;
          if (((_a = row.children) == null ? void 0 : _a.length) && isExpanded) {
            return [processedRow, ...processRows(row.children, level + 1)];
          }
          return [processedRow];
        });
      };
      return processRows(rows.value);
    });
    const labelContainerStyle = computed(() => {
      if (maxRows.value === 0) return {};
      const minRows = Math.min(maxRows.value, getProcessedRows.value.length);
      return {
        height: `${minRows * rowHeight.value}px`,
        "overflow-y": "auto"
      };
    });
    const columnSortableStates = computed(
      () => columns.value.reduce(
        (acc, column) => {
          acc[column.field] = !!(column.sortable !== false && (sortable.value || !sortable.value && column.sortable) && (isValidColumn(column.field) || column.sortFn));
          return acc;
        },
        {}
      )
    );
    const headerHeight = computed(() => {
      if (hideTimeaxis.value) return 0;
      return showEventsAxis.value ? 80 + (eventsAxisHeight.value || 25) : 80;
    });
    let touchStartTime = 0;
    const onRowTouchStart = (e, row) => {
      if (!enableRowDragAndDrop.value || sortState.value.direction !== "none") return;
      touchStartTime = Date.now();
      const element = e.currentTarget;
      handleRowTouchStart(e, row, element);
    };
    const onRowTouchMove = (e, targetRow) => {
      if (!enableRowDragAndDrop.value || sortState.value.direction !== "none") return;
      if (Date.now() - touchStartTime < LONG_PRESS_DURATION) {
        resetRowTouchState();
        return;
      }
      const rowElement = e.currentTarget;
      handleRowTouchMove(e, targetRow, rowElement);
    };
    const onRowTouchEnd = (e) => {
      if (!enableRowDragAndDrop.value || sortState.value.direction !== "none") return;
      if (Date.now() - touchStartTime < LONG_PRESS_DURATION) {
        const target = e.target;
        const button = target.closest(".group-toggle-button");
        if (button) {
          const rowElement = target.closest("[data-row-id]");
          if (rowElement) {
            const rowId = rowElement.dataset.rowId;
            if (rowId) {
              rowManager.toggleGroupExpansion(rowId);
            }
          }
        }
        resetRowTouchState();
        return;
      }
      const result = handleRowTouchEnd(e);
      if (result && result.sourceRow && result.dropTarget.row) {
        let newIndex = getProcessedRows.value.findIndex((r) => r === result.dropTarget.row);
        if (result.dropTarget.position === "after") {
          newIndex += 1;
        }
        const sourceIndex = getProcessedRows.value.findIndex((r) => r === result.sourceRow);
        if (sourceIndex < newIndex) {
          newIndex -= 1;
        }
        const payload = {
          sourceRow: result.sourceRow,
          targetRow: result.dropTarget.row,
          newIndex,
          parentId: result.dropTarget.position === "child" ? result.dropTarget.row.id : void 0
        };
        const newRows = [...getProcessedRows.value];
        newRows.splice(sourceIndex, 1);
        newRows.splice(newIndex, 0, result.sourceRow);
        rowManager.updateRows(newRows);
        emit("row-drop", payload);
      }
    };
    const handleColumnTouchStart = (e, column) => {
      if (!labelResizable) return;
      const currentWidth = columnWidths.get(column) || labelColumnWidth.value;
      handleTouchStart(e, column, currentWidth);
    };
    const handleColumnTouchMove = (e) => {
      if (!labelResizable) return;
      handleTouchMove(e, (column, newWidth) => {
        columnWidths.set(column, newWidth);
      });
    };
    const initializeColumnWidths = () => {
      columns.value.forEach((column) => {
        if (!columnWidths.has(column.field)) {
          columnWidths.set(column.field, labelColumnWidth.value);
        }
      });
    };
    const isValidColumn = (field) => {
      return ["Id", "Label", "StartDate", "EndDate", "Duration", "Progress"].includes(field);
    };
    const getSortIcon = (field) => {
      if (field !== sortState.value.column || sortState.value.direction === "none") {
        return faSort;
      }
      return sortState.value.direction === "asc" ? faArrowDownAZ : faArrowDownZA;
    };
    const getVisibleColumns = (row) => {
      if (row.children && row.children.length > 0) {
        return [{ field: "Label", sortable: sortable.value }];
      }
      return columns.value;
    };
    const rowClasses = (row) => {
      var _a;
      const classes = ["g-label-column-row"];
      if (rowLabelClass.value) {
        classes.push(rowLabelClass.value(row));
      }
      if ((_a = row.children) == null ? void 0 : _a.length) {
        classes.push("g-label-column-group");
      }
      return classes;
    };
    const getDragClasses = (row) => {
      if (!enableRowDragAndDrop.value) return {};
      const isTarget = dragState.value.dropTarget.row === row;
      const isDragged = dragState.value.draggedRow === row;
      return {
        "g-label-column-row-draggable": true,
        "g-label-column-row-dragging": isDragged,
        "g-label-column-row-drop-target": isTarget,
        [`g-label-column-row-drop-${dragState.value.dropTarget.position}`]: isTarget
      };
    };
    const getRowStyle = (row, isLabelColumn) => {
      var _a;
      if (!isLabelColumn) {
        return {
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          width: "100%"
        };
      }
      const style = {
        display: "flex",
        alignItems: "center",
        width: "100%",
        position: "relative"
      };
      if (!((_a = row.children) == null ? void 0 : _a.length) && !row.indentLevel) {
        style.paddingLeft = `${INDENT_WIDTH}px`;
      } else if (row.indentLevel) {
        style.paddingLeft = `${row.indentLevel * INDENT_WIDTH}px`;
      }
      return style;
    };
    const getCellStyle = (isLabelColumn) => {
      const style = {
        display: "flex",
        alignItems: "center",
        width: "100%"
      };
      if (!isLabelColumn) {
        style.justifyContent = "center";
        style.paddingLeft = "0";
      }
      return style;
    };
    const getColumnStyle = (column, isGroup) => {
      if (isGroup && column === "Label") {
        return {
          width: "100%",
          minWidth: "100%",
          maxWidth: "100%",
          position: "relative",
          flexShrink: 0,
          flexGrow: 0
        };
      }
      return {
        width: `${columnWidths.get(column) || labelColumnWidth.value}px`,
        minWidth: `${columnWidths.get(column) || labelColumnWidth.value}px`,
        maxWidth: `${columnWidths.get(column) || labelColumnWidth.value}px`,
        position: "relative",
        flexShrink: 0,
        flexGrow: 0
      };
    };
    const getRowValue = (row, column, index) => {
      if (column.valueGetter) {
        return column.valueGetter(row);
      }
      switch (column.field) {
        case "Id":
          return row.id ?? index + 1;
        case "Label":
          return row.label;
        case "StartDate": {
          if (!row.bars.length) return "-";
          const minDate = row.bars.reduce((min, bar) => {
            const currentStart = bar[barStart.value];
            return !min || toDayjs(currentStart).isBefore(toDayjs(min)) ? currentStart : min;
          }, "");
          return format(minDate, dateFormat.value);
        }
        case "EndDate": {
          if (!row.bars.length) return "-";
          const maxDate = row.bars.reduce((max, bar) => {
            const currentEnd = bar[barEnd.value];
            return !max || toDayjs(currentEnd).isAfter(toDayjs(max)) ? currentEnd : max;
          }, "");
          return format(maxDate, dateFormat.value);
        }
        case "Duration": {
          if (!row.bars.length) return "-";
          const minStart = row.bars.reduce((min, bar) => {
            const currentStart = bar[barStart.value];
            return !min || toDayjs(currentStart).isBefore(toDayjs(min)) ? currentStart : min;
          }, "");
          const maxEnd = row.bars.reduce((max, bar) => {
            const currentEnd = bar[barEnd.value];
            return !max || toDayjs(currentEnd).isAfter(toDayjs(max)) ? currentEnd : max;
          }, "");
          return calculateDuration(minStart, maxEnd);
        }
        case "Progress": {
          if (!row.bars.length) return "-";
          const progressValues = row.bars.map((bar) => bar.ganttBarConfig.progress).filter((progress) => progress !== void 0);
          if (progressValues.length === 0) return "-";
          const averageProgress = progressValues.reduce((sum, curr) => sum + curr, 0) / progressValues.length;
          return `${Math.round(averageProgress)}%`;
        }
        default:
          return "";
      }
    };
    const calculateDuration = (startDate, endDate) => {
      const start = toDayjs(startDate);
      const end = toDayjs(endDate);
      switch (precision.value) {
        case "hour":
          return `${end.diff(start, "hour")}h`;
        case "day":
        case "date":
          return `${end.diff(start, "day")}d`;
        case "week":
          return `${end.diff(start, "week")}w`;
        case "month":
          return `${end.diff(start, "month")}m`;
        default:
          return `${end.diff(start, "day")}d`;
      }
    };
    const handleLabelScroll = (e) => {
      const target = e.target;
      emit("scroll", target.scrollTop);
    };
    const handleGroupToggle = (row, event) => {
      event.stopPropagation();
      if (row.id) {
        rowManager.toggleGroupExpansion(row.id);
      }
    };
    const handleDragStart = (e, column) => {
      isDragging.value = true;
      dragStartX.value = e.clientX;
      draggedColumn.value = column;
      document.addEventListener("mousemove", handleDrag);
      document.addEventListener("mouseup", handleDragEnd);
    };
    const handleDrag = (e) => {
      if (!isDragging.value || !draggedColumn.value) return;
      const deltaX = e.clientX - dragStartX.value;
      const currentWidth = columnWidths.get(draggedColumn.value) || labelColumnWidth.value;
      const newWidth = Math.max(50, currentWidth + deltaX);
      columnWidths.set(draggedColumn.value, newWidth);
      dragStartX.value = e.clientX;
    };
    const handleDragEnd = () => {
      isDragging.value = false;
      draggedColumn.value = null;
      document.removeEventListener("mousemove", handleDrag);
      document.removeEventListener("mouseup", handleDragEnd);
    };
    onMounted(() => {
      initializeColumnWidths();
    });
    __expose({
      setScroll: (value) => {
        if (labelContainer.value) {
          labelContainer.value.scrollTop = value;
        }
      }
    });
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", {
        class: "g-label-column",
        style: normalizeStyle({
          fontFamily: unref(font),
          color: unref(colors).text,
          minWidth: `100%`,
          flex: `0 0 ${totalWidth.value}px`,
          borderRight: `1px solid ${unref(colors).gridAndBorder}`
        })
      }, [
        !unref(hideTimeaxis) ? (openBlock(), createElementBlock("div", {
          key: 0,
          class: "g-label-column-header",
          style: normalizeStyle({
            background: unref(colors).primary,
            borderBottom: `1px solid ${unref(colors).gridAndBorder}`,
            height: `${headerHeight.value}px`,
            minHeight: `${headerHeight.value}px`
          })
        }, [
          (openBlock(true), createElementBlock(Fragment, null, renderList(columns.value, (column) => {
            return openBlock(), createElementBlock(Fragment, { key: column }, [
              isValidColumn(column.field) || column.valueGetter ? (openBlock(), createElementBlock("div", {
                key: 0,
                class: normalizeClass(["g-label-column-header-cell", { sortable: columnSortableStates.value[column.field] }]),
                role: "columnheader",
                style: normalizeStyle(getColumnStyle(column.field, false))
              }, [
                createElementVNode("div", {
                  class: "header-content",
                  onClick: ($event) => columnSortableStates.value[column.field] ? unref(toggleSort)(column.field) : void 0
                }, [
                  createElementVNode("span", _hoisted_2$6, [
                    renderSlot(_ctx.$slots, `label-column-title-${column.field.toLowerCase()}`, {}, () => [
                      createTextVNode(toDisplayString(column.field), 1)
                    ])
                  ]),
                  columnSortableStates.value[column.field] ? (openBlock(), createElementBlock("span", _hoisted_3$6, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: getSortIcon(column.field)
                    }, null, 8, ["icon"])
                  ])) : createCommentVNode("", true)
                ], 8, _hoisted_1$9),
                unref(labelResizable) ? (openBlock(), createElementBlock("div", {
                  key: 0,
                  class: normalizeClass(["column-resizer", {
                    "is-dragging": isDragging.value && draggedColumn.value === column.field,
                    "is-touch-resizing": unref(touchState).isResizing && unref(touchState).currentColumn === column.field
                  }]),
                  onMousedown: (e) => handleDragStart(e, column.field),
                  onTouchstart: (e) => handleColumnTouchStart(e, column.field),
                  onTouchmove: handleColumnTouchMove,
                  onTouchend: _cache[0] || (_cache[0] = //@ts-ignore
                  (...args) => unref(handleTouchEnd) && unref(handleTouchEnd)(...args)),
                  onTouchcancel: _cache[1] || (_cache[1] = //@ts-ignore
                  (...args) => unref(handleTouchCancel) && unref(handleTouchCancel)(...args))
                }, null, 42, _hoisted_4$5)) : createCommentVNode("", true)
              ], 6)) : createCommentVNode("", true)
            ], 64);
          }), 128))
        ], 4)) : createCommentVNode("", true),
        createElementVNode("div", {
          class: "g-label-column-rows",
          style: normalizeStyle(labelContainerStyle.value),
          ref_key: "labelContainer",
          ref: labelContainer,
          onScroll: handleLabelScroll
        }, [
          (openBlock(true), createElementBlock(Fragment, null, renderList(getProcessedRows.value, (row, index) => {
            var _a;
            return openBlock(), createElementBlock("div", {
              key: `${row.id || row.label}_${index}`,
              "data-row-id": row.id,
              style: normalizeStyle({
                background: ((_a = row.children) == null ? void 0 : _a.length) ? unref(colors).rowContainer : index % 2 === 0 ? unref(colors).ternary : unref(colors).quartenary,
                height: `${unref(rowHeight)}px`,
                borderBottom: `1px solid ${unref(colors).gridAndBorder}`,
                transform: unref(rowTouchState).draggedRow === row ? `translateY(${unref(rowTouchState).currentY - unref(rowTouchState).startY}px)` : void 0,
                zIndex: unref(rowTouchState).draggedRow === row ? 1e3 : void 0
              }),
              class: normalizeClass([
                rowClasses(row),
                getDragClasses(row),
                {
                  "is-touch-dragging": unref(rowTouchState).draggedRow === row,
                  "is-touch-drop-target": unref(rowTouchState).dropTarget.row === row,
                  [`is-touch-drop-${unref(rowTouchState).dropTarget.position}`]: unref(rowTouchState).dropTarget.row === row
                }
              ]),
              draggable: unref(enableRowDragAndDrop),
              onDragstart: ($event) => unref(handleRowDragStart)(row, $event),
              onDragover: ($event) => unref(handleDragOver)(row, $event),
              onDrop: _cache[2] || (_cache[2] = ($event) => unref(handleDrop)()),
              onTouchstart: (e) => onRowTouchStart(e, row),
              onTouchmove: (e) => onRowTouchMove(e, row),
              onTouchend: onRowTouchEnd,
              onTouchcancel: _cache[3] || (_cache[3] = //@ts-ignore
              (...args) => unref(resetRowTouchState) && unref(resetRowTouchState)(...args))
            }, [
              createElementVNode("div", _hoisted_6$4, [
                (openBlock(true), createElementBlock(Fragment, null, renderList(getVisibleColumns(row), (column) => {
                  var _a2;
                  return openBlock(), createElementBlock(Fragment, {
                    key: column.field
                  }, [
                    isValidColumn(column.field) || column.valueGetter ? (openBlock(), createElementBlock("div", {
                      key: 0,
                      class: "g-label-column-cell",
                      style: normalizeStyle(getColumnStyle(column.field, Boolean((_a2 = row.children) == null ? void 0 : _a2.length)))
                    }, [
                      createElementVNode("div", {
                        style: normalizeStyle(getCellStyle(column.field === "Label"))
                      }, [
                        createElementVNode("div", {
                          style: normalizeStyle(getRowStyle(row, column.field === "Label")),
                          class: "cell-content"
                        }, [
                          column.field === "Label" && row.children && row.children.length > 0 ? (openBlock(), createElementBlock("button", {
                            key: 0,
                            class: "group-toggle-button",
                            onClick: ($event) => handleGroupToggle(row, $event)
                          }, [
                            createVNode(unref(FontAwesomeIcon), {
                              icon: row.id && unref(rowManager).isGroupExpanded(row.id) ? unref(faChevronDown) : unref(faChevronRight),
                              class: "group-icon"
                            }, null, 8, ["icon"])
                          ], 8, _hoisted_7$4)) : createCommentVNode("", true),
                          createElementVNode("span", _hoisted_8$4, [
                            renderSlot(_ctx.$slots, `label-column-${column.field.toLowerCase()}`, {
                              row,
                              value: getRowValue(row, column, index)
                            }, () => [
                              createTextVNode(toDisplayString(getRowValue(row, column, index)), 1)
                            ])
                          ])
                        ], 4)
                      ], 4)
                    ], 4)) : createCommentVNode("", true)
                  ], 64);
                }), 128))
              ])
            ], 46, _hoisted_5$4);
          }), 128))
        ], 36)
      ], 4);
    };
  }
});
function useHolidays(config) {
  const { chartStartDayjs, chartEndDayjs } = useDayjsHelper(config);
  const holidays = ref([]);
  const hd = new Holidays();
  const loadHolidays = (country) => {
    hd.init(country);
    const start = chartStartDayjs.value.toDate();
    const end = chartEndDayjs.value.toDate();
    const holidaysListStart = hd.getHolidays(start);
    const holidaysListEnd = hd.getHolidays(end);
    const startHolidays = holidaysListStart.map((h2) => ({
      date: new Date(h2.date),
      name: h2.name,
      type: h2.type
    }));
    const endHolidays = holidaysListEnd.map((h2) => ({
      date: new Date(h2.date),
      name: h2.name,
      type: h2.type
    }));
    holidays.value = [...startHolidays, ...endHolidays];
  };
  const getHolidayInfo = (date) => {
    const holiday = holidays.value.find((h2) => h2.date.toDateString() === date.toDateString());
    if (!holiday) return null;
    return {
      isHoliday: true,
      holidayName: holiday.name,
      holidayType: holiday.type
    };
  };
  watch(
    () => {
      var _a;
      return (_a = config.holidayHighlight.value) == null ? void 0 : _a.toUpperCase();
    },
    (newCountry) => {
      if (newCountry) {
        loadHolidays(newCountry);
      } else {
        holidays.value = [];
      }
    },
    { immediate: true }
  );
  return {
    holidays,
    getHolidayInfo
  };
}
const ganttWidth = ref();
const BASE_UNIT_WIDTH = 24;
const MAX_ZOOM = 10;
const MIN_ZOOM = 1;
const DEFAULT_ZOOM = 3;
const CACHE_TTL = 5 * 60 * 1e3;
const capitalizeString = (str) => {
  if (!str) return str;
  return str.normalize("NFD").replace(new RegExp("^\\p{L}", "u"), (letter) => letter.toLocaleUpperCase());
};
const capitalizeWords = (str) => {
  return str.split(/(\s+|\.|\,)/).map((word) => {
    if (new RegExp("^\\p{L}", "u").test(word)) {
      return capitalizeString(word);
    }
    return word;
  }).join("");
};
function useTimeaxisUnits(config = provideConfig()) {
  const { getHolidayInfo } = useHolidays(config);
  const { precision: configPrecision, holidayHighlight, locale, timeaxisEvents } = config;
  const internalPrecision = ref(configPrecision.value);
  const zoomLevel = ref(DEFAULT_ZOOM);
  const processedTimeaxisEvents = ref([]);
  const cache = {
    lower: /* @__PURE__ */ new Map(),
    upper: /* @__PURE__ */ new Map(),
    events: /* @__PURE__ */ new Map()
  };
  const displayFormats = {
    hour: "HH",
    date: "DD.MMM",
    day: "DD.MMM",
    week: "WW",
    month: "MMMM YYYY",
    year: "YYYY"
  };
  const getDisplayFormat = (unit) => {
    if (unit === "isoWeek") return displayFormats.week;
    return displayFormats[unit] || displayFormats.day;
  };
  const precisionHierarchy = ["hour", "day", "week", "month"];
  const unitWidth = computed(() => BASE_UNIT_WIDTH * zoomLevel.value);
  const getNextPrecision = (currentPrecision) => {
    const currentIndex = precisionHierarchy.indexOf(currentPrecision);
    if (currentIndex < precisionHierarchy.length - 1) {
      return precisionHierarchy[currentIndex + 1];
    }
    return currentPrecision;
  };
  const getPreviousPrecision = (currentPrecision) => {
    const currentIndex = precisionHierarchy.indexOf(currentPrecision);
    const configIndex = precisionHierarchy.indexOf(configPrecision.value);
    if (currentIndex > 0 && currentIndex > configIndex) {
      return precisionHierarchy[currentIndex - 1];
    }
    return currentPrecision;
  };
  const upperPrecision = computed(() => {
    const precisionMap = {
      hour: "day",
      day: "month",
      date: "month",
      week: "month",
      month: "year"
    };
    return precisionMap[internalPrecision.value] || "month";
  });
  const getCacheKey = (startDate, endDate, precision, zoom) => {
    return `${startDate.valueOf()}-${endDate.valueOf()}-${precision}-${zoom}`;
  };
  const getEventsCacheKey = (startDate, endDate, zoom) => {
    return `${startDate.valueOf()}-${endDate.valueOf()}-${zoom}`;
  };
  const getFromCache = (cacheMap, key) => {
    const entry = cacheMap.get(key);
    if (!entry) return null;
    if (Date.now() - entry.timestamp > CACHE_TTL) {
      cacheMap.delete(key);
      return null;
    }
    return entry.units;
  };
  const getEventsFromCache = (key) => {
    const entry = cache.events.get(key);
    if (!entry) return null;
    if (Date.now() - entry.timestamp > CACHE_TTL) {
      cache.events.delete(key);
      return null;
    }
    return entry.events;
  };
  const setInCache = (cacheMap, key, units) => {
    cacheMap.set(key, {
      timestamp: Date.now(),
      units
    });
  };
  const setEventsInCache = (key, events) => {
    cache.events.set(key, {
      timestamp: Date.now(),
      events
    });
  };
  const getDayjsUnit = (unit) => {
    const unitMap = {
      hour: "hour",
      day: "day",
      date: "day",
      week: "week",
      month: "month",
      year: "year",
      isoWeek: "week"
    };
    return unitMap[unit];
  };
  const createTimeaxisUnit = (moment, format, width) => {
    const date = moment.toDate();
    const holidayInfo = holidayHighlight.value ? getHolidayInfo(date) : null;
    const formattedLabel = moment.format(format);
    const capitalizedLabel = capitalizeWords(formattedLabel);
    return {
      label: capitalizedLabel,
      value: String(moment),
      date,
      width,
      isHoliday: (holidayInfo == null ? void 0 : holidayInfo.isHoliday) || false,
      holidayName: holidayInfo == null ? void 0 : holidayInfo.holidayName,
      holidayType: holidayInfo == null ? void 0 : holidayInfo.holidayType
    };
  };
  const updateEventPositions = () => {
    var _a;
    if (!((_a = timeaxisEvents.value) == null ? void 0 : _a.length)) {
      processedTimeaxisEvents.value = [];
      return;
    }
    const { chartStartDayjs, chartEndDayjs } = useDayjsHelper(config);
    const totalMinutes = chartEndDayjs.value.diff(chartStartDayjs.value, "minutes");
    const eventsCacheKey = getEventsCacheKey(
      chartStartDayjs.value,
      chartEndDayjs.value,
      zoomLevel.value
    );
    const cachedEvents = getEventsFromCache(eventsCacheKey);
    if (cachedEvents) {
      processedTimeaxisEvents.value = cachedEvents;
      return;
    }
    const processedEvents = timeaxisEvents.value.map((event) => {
      const eventStartDayjs = dayjs(event.startDate);
      const eventEndDayjs = dayjs(event.endDate);
      if (eventEndDayjs.isBefore(chartStartDayjs.value) || eventStartDayjs.isAfter(chartEndDayjs.value)) {
        return {
          ...event,
          width: "0px",
          xPosition: 0
        };
      }
      const startTime = eventStartDayjs.isBefore(chartStartDayjs.value) ? chartStartDayjs.value : eventStartDayjs;
      const endTime = eventEndDayjs.isAfter(chartEndDayjs.value) ? chartEndDayjs.value : eventEndDayjs;
      const startMinutes = startTime.diff(chartStartDayjs.value, "minutes");
      const endMinutes = endTime.diff(chartStartDayjs.value, "minutes");
      const startPosition = startMinutes / totalMinutes * ganttWidth.value;
      const endPosition = endMinutes / totalMinutes * ganttWidth.value;
      const width = Math.max(endPosition - startPosition, 2);
      return {
        ...event,
        width: `${width}px`,
        xPosition: startPosition
      };
    });
    processedTimeaxisEvents.value = processedEvents;
    setEventsInCache(eventsCacheKey, processedEvents);
  };
  watch(
    () => configPrecision.value,
    () => {
      internalPrecision.value = configPrecision.value;
      zoomLevel.value = DEFAULT_ZOOM;
    }
  );
  watch([() => holidayHighlight.value, () => locale.value], () => {
    dayjs.locale(locale.value);
    cache.lower.clear();
    cache.upper.clear();
  });
  watch(ganttWidth, () => {
    updateEventPositions();
  });
  watch(
    [() => timeaxisEvents.value, () => config.chartStart.value, () => config.chartEnd.value],
    () => {
      updateEventPositions();
    },
    { deep: true }
  );
  const timeaxisUnits = computed(() => {
    var _a;
    const { chartStartDayjs, chartEndDayjs } = useDayjsHelper(config);
    const lowerCacheKey = getCacheKey(
      chartStartDayjs.value,
      chartEndDayjs.value,
      internalPrecision.value,
      zoomLevel.value
    );
    let lowerUnits = getFromCache(cache.lower, lowerCacheKey);
    const lowerUnitsByStartTime = /* @__PURE__ */ new Map();
    if (!lowerUnits) {
      lowerUnits = [];
      let currentLower = chartStartDayjs.value.clone();
      while (currentLower.isBefore(chartEndDayjs.value)) {
        const unit = createTimeaxisUnit(
          currentLower,
          getDisplayFormat(internalPrecision.value),
          `${unitWidth.value}px`
        );
        lowerUnits.push(unit);
        lowerUnitsByStartTime.set(currentLower.valueOf(), unit);
        currentLower = currentLower.add(1, getDayjsUnit(internalPrecision.value));
      }
      setInCache(cache.lower, lowerCacheKey, lowerUnits);
    }
    const upperCacheKey = getCacheKey(
      chartStartDayjs.value,
      chartEndDayjs.value,
      upperPrecision.value,
      zoomLevel.value
    );
    let upperUnits = getFromCache(cache.upper, upperCacheKey);
    if (!upperUnits) {
      upperUnits = [];
      let currentUpper = chartStartDayjs.value.startOf(getDayjsUnit(upperPrecision.value));
      while (currentUpper.isBefore(chartEndDayjs.value)) {
        const nextUpper = currentUpper.add(1, getDayjsUnit(upperPrecision.value));
        const effectiveStart = currentUpper.isBefore(chartStartDayjs.value) ? chartStartDayjs.value : currentUpper;
        const effectiveEnd = nextUpper.isAfter(chartEndDayjs.value) ? chartEndDayjs.value : nextUpper;
        let unitsInPeriod = 0;
        if (internalPrecision.value === "day") {
          unitsInPeriod = Math.ceil(effectiveEnd.diff(effectiveStart, "day", true));
        } else if (internalPrecision.value === "month") {
          unitsInPeriod = Math.ceil(effectiveEnd.diff(effectiveStart, "month", true));
        } else if (internalPrecision.value === "week") {
          unitsInPeriod = Math.ceil(effectiveEnd.diff(effectiveStart, "week", true));
        } else {
          unitsInPeriod = Math.ceil(effectiveEnd.diff(effectiveStart, "hour", true));
        }
        const totalWidth = unitsInPeriod * unitWidth.value;
        if (totalWidth > 0) {
          upperUnits.push(
            createTimeaxisUnit(
              currentUpper,
              getDisplayFormat(upperPrecision.value),
              `${totalWidth}px`
            )
          );
        }
        currentUpper = nextUpper;
      }
      setInCache(cache.upper, upperCacheKey, upperUnits);
    }
    if (((_a = timeaxisEvents.value) == null ? void 0 : _a.length) && processedTimeaxisEvents.value.length === 0) {
      updateEventPositions();
    }
    const minuteSteps = calculateMinuteSteps();
    cleanExpiredCache();
    return {
      result: {
        upperUnits,
        lowerUnits,
        events: processedTimeaxisEvents.value
      },
      globalMinuteStep: minuteSteps
    };
  });
  const calculateMinuteSteps = () => {
    if (!config.enableMinutes.value || internalPrecision.value !== "hour") {
      return [];
    }
    const cellWidth = unitWidth.value;
    const minCellWidth = 16;
    const possibleDivisions = Math.floor(cellWidth / minCellWidth);
    let step;
    if (possibleDivisions >= 60) step = 1;
    else if (possibleDivisions >= 12) step = 5;
    else if (possibleDivisions >= 6) step = 10;
    else if (possibleDivisions >= 4) step = 15;
    else if (possibleDivisions >= 2) step = 30;
    else return ["00"];
    return Array.from({ length: 60 / step }, (_, i) => (i * step).toString().padStart(2, "0"));
  };
  const cleanExpiredCache = () => {
    const now = Date.now();
    for (const [key, entry] of cache.lower.entries()) {
      if (now - entry.timestamp > CACHE_TTL) {
        cache.lower.delete(key);
      }
    }
    for (const [key, entry] of cache.upper.entries()) {
      if (now - entry.timestamp > CACHE_TTL) {
        cache.upper.delete(key);
      }
    }
    for (const [key, entry] of cache.events.entries()) {
      if (now - entry.timestamp > CACHE_TTL) {
        cache.events.delete(key);
      }
    }
  };
  const adjustZoomAndPrecision = (increase) => {
    if (increase) {
      if (zoomLevel.value === MAX_ZOOM) {
        const previousPrecision = getPreviousPrecision(internalPrecision.value);
        if (previousPrecision !== internalPrecision.value) {
          internalPrecision.value = previousPrecision;
          zoomLevel.value = MIN_ZOOM;
        }
      } else {
        zoomLevel.value += 1;
      }
    } else {
      if (zoomLevel.value === MIN_ZOOM) {
        const nextPrecision = getNextPrecision(internalPrecision.value);
        if (nextPrecision !== internalPrecision.value) {
          internalPrecision.value = nextPrecision;
          zoomLevel.value = MAX_ZOOM;
        }
      } else {
        zoomLevel.value -= 1;
      }
    }
  };
  watch(
    [
      () => config.chartStart.value,
      () => config.chartEnd.value,
      internalPrecision,
      zoomLevel,
      () => config.timeaxisEvents.value
    ],
    () => {
      cache.lower.clear();
      cache.upper.clear();
      cache.events.clear();
      updateEventPositions();
    }
  );
  updateEventPositions();
  return {
    timeaxisUnits,
    internalPrecision,
    zoomLevel,
    adjustZoomAndPrecision
  };
}
const _hoisted_1$8 = { class: "g-gantt-holiday-tooltip-content" };
const _sfc_main$a = /* @__PURE__ */ defineComponent({
  __name: "GGanttHolidayTooltip",
  props: {
    unit: {},
    modelValue: { type: Boolean },
    targetElement: {}
  },
  setup(__props) {
    const props = __props;
    const { unit, targetElement } = toRefs(props);
    const { font } = provideConfig();
    const tooltipTop = ref("0px");
    const tooltipLeft = ref("0px");
    watch(
      [() => props.unit, () => props.targetElement],
      async () => {
        var _a;
        if (!((_a = unit.value) == null ? void 0 : _a.holidayName) || !targetElement.value) {
          return;
        }
        const rect = targetElement.value.getBoundingClientRect();
        tooltipTop.value = `${rect.top - 30}px`;
        tooltipLeft.value = `${rect.left + rect.width / 2}px`;
      },
      { immediate: true }
    );
    return (_ctx, _cache) => {
      return openBlock(), createBlock(Teleport, { to: "body" }, [
        createVNode(Transition, {
          name: "g-fade",
          mode: "out-in"
        }, {
          default: withCtx(() => {
            var _a;
            return [
              _ctx.modelValue && ((_a = unref(unit)) == null ? void 0 : _a.holidayName) ? (openBlock(), createElementBlock("div", {
                key: 0,
                class: "g-gantt-holiday-tooltip",
                style: normalizeStyle({
                  top: tooltipTop.value,
                  left: tooltipLeft.value,
                  fontFamily: unref(font)
                })
              }, [
                createElementVNode("div", _hoisted_1$8, toDisplayString(unref(unit).holidayName), 1)
              ], 4)) : createCommentVNode("", true)
            ];
          }),
          _: 1
        })
      ]);
    };
  }
});
const _hoisted_1$7 = { class: "g-gantt-event-tooltip-content" };
const _hoisted_2$5 = { class: "g-gantt-event-tooltip-title" };
const _hoisted_3$5 = { class: "g-gantt-event-tooltip-time" };
const _hoisted_4$4 = {
  key: 0,
  class: "g-gantt-event-tooltip-description"
};
const _sfc_main$9 = /* @__PURE__ */ defineComponent({
  __name: "GGanttEventTooltip",
  props: {
    event: {},
    modelValue: { type: Boolean },
    targetElement: {}
  },
  setup(__props) {
    const props = __props;
    const { event, targetElement } = toRefs(props);
    const { font, colors, dateFormat } = provideConfig();
    const { format } = useDayjsHelper();
    const tooltipTop = ref("0px");
    const tooltipLeft = ref("0px");
    watch(
      [() => props.event, () => props.targetElement],
      async () => {
        if (!event.value || !targetElement.value) {
          return;
        }
        await nextTick();
        const rect = targetElement.value.getBoundingClientRect();
        tooltipTop.value = `${rect.top - 95}px`;
        tooltipLeft.value = `${rect.left + rect.width / 2}px`;
      },
      { immediate: true }
    );
    const formatDate = (date) => {
      return format(date, dateFormat.value);
    };
    return (_ctx, _cache) => {
      return openBlock(), createBlock(Teleport, { to: "body" }, [
        createVNode(Transition, {
          name: "g-fade",
          mode: "out-in"
        }, {
          default: withCtx(() => [
            _ctx.modelValue && unref(event) ? (openBlock(), createElementBlock("div", {
              key: 0,
              class: "g-gantt-event-tooltip",
              style: normalizeStyle({
                top: tooltipTop.value,
                left: tooltipLeft.value,
                fontFamily: unref(font),
                background: unref(colors).primary,
                color: unref(colors).text
              })
            }, [
              createElementVNode("div", _hoisted_1$7, [
                createElementVNode("div", _hoisted_2$5, toDisplayString(unref(event).label), 1),
                createElementVNode("div", _hoisted_3$5, toDisplayString(formatDate(unref(event).startDate)) + " - " + toDisplayString(formatDate(unref(event).endDate)), 1),
                unref(event).description ? (openBlock(), createElementBlock("div", _hoisted_4$4, toDisplayString(unref(event).description), 1)) : createCommentVNode("", true)
              ])
            ], 4)) : createCommentVNode("", true)
          ]),
          _: 1
        })
      ]);
    };
  }
});
const _hoisted_1$6 = { class: "g-timeunits-container" };
const _hoisted_2$4 = ["onMouseenter"];
const _hoisted_3$4 = { class: "g-timeunits-container" };
const _hoisted_4$3 = ["onMouseenter"];
const _hoisted_5$3 = { class: "g-timeunit-min" };
const _hoisted_6$3 = { class: "label-unit" };
const _hoisted_7$3 = {
  key: 0,
  class: "g-timeunit-step"
};
const _hoisted_8$3 = { class: "label-unit" };
const _hoisted_9$3 = ["onMouseenter"];
const _hoisted_10$2 = { class: "g-timeaxis-event-label" };
const _sfc_main$8 = /* @__PURE__ */ defineComponent({
  __name: "GGanttTimeaxis",
  props: {
    timeaxisUnits: {},
    internalPrecision: {}
  },
  emits: ["dragStart", "drag", "dragEnd"],
  setup(__props, { expose: __expose, emit: __emit }) {
    const props = __props;
    const { timeaxisUnits, internalPrecision } = toRefs(props);
    const emit = __emit;
    const timeaxisElement = ref(null);
    const hoveredUnit = ref();
    const showTooltip = ref(false);
    const hoveredElement = ref(null);
    const hoveredEvent = ref();
    const showEventTooltip = ref(false);
    const hoveredEventElement = ref(null);
    const {
      precision,
      colors,
      holidayHighlight,
      dayOptionLabel,
      enableMinutes,
      showEventsAxis,
      eventsAxisHeight
    } = provideConfig();
    const { toDayjs } = useDayjsHelper();
    const handleMouseDown = (e) => {
      emit("dragStart", e);
    };
    const dayUnitLevel = computed(() => {
      if (internalPrecision.value === "hour") {
        return "upper";
      } else if (internalPrecision.value === "day") {
        return "lower";
      }
      return null;
    });
    const getHolidayStyle = (unit, unitType) => {
      if (!holidayHighlight.value || dayUnitLevel.value !== unitType || !unit.isHoliday) {
        return {};
      }
      return {
        background: colors.value.holidayHighlight || "#ffebee"
      };
    };
    const handleUnitMouseEnter = (unit, unitType, event) => {
      if (!holidayHighlight.value || dayUnitLevel.value === unitType || !unit.isHoliday) {
        hoveredUnit.value = unit;
        hoveredElement.value = event.currentTarget;
        showTooltip.value = true;
      }
    };
    const handleUnitMouseLeave = () => {
      showTooltip.value = false;
      hoveredUnit.value = void 0;
      hoveredElement.value = null;
    };
    const handleEventMouseEnter = (event, mouseEvent) => {
      hoveredEvent.value = event;
      hoveredEventElement.value = mouseEvent.currentTarget;
      showEventTooltip.value = true;
    };
    const handleEventMouseLeave = () => {
      showEventTooltip.value = false;
      hoveredEvent.value = void 0;
      hoveredEventElement.value = null;
    };
    const formatTimeUnitLabel = (unit, unitType) => {
      if (dayUnitLevel.value !== unitType || !dayOptionLabel.value) {
        return unit.label;
      }
      let result = "";
      for (const option of dayOptionLabel.value) {
        if (result) result += " ";
        switch (option) {
          case "day":
            result += unit.label;
            break;
          case "doy":
            result += `(${toDayjs(unit.date).dayOfYear()})`;
            break;
          case "name":
            result += capitalizeWords(toDayjs(unit.date).format("dd")[0]);
            break;
          case "number":
            result += toDayjs(unit.date).date();
            break;
        }
      }
      return result;
    };
    const eventsAxisHeightValue = computed(() => {
      return eventsAxisHeight.value || 25;
    });
    const shouldShowEventsAxis = computed(() => {
      return showEventsAxis.value && timeaxisUnits.value.result.events.length > 0;
    });
    const eventPositions = computed(() => {
      if (!timeaxisUnits.value.result.events.length) return [];
      const { chartStartDayjs, chartEndDayjs } = useDayjsHelper();
      const totalMinutes = chartEndDayjs.value.diff(chartStartDayjs.value, "minutes");
      return timeaxisUnits.value.result.events.map((event) => {
        const eventStartDayjs = dayjs(event.startDate);
        const eventEndDayjs = dayjs(event.endDate);
        const startTime = eventStartDayjs.isBefore(chartStartDayjs.value) ? chartStartDayjs.value : eventStartDayjs;
        const endTime = eventEndDayjs.isAfter(chartEndDayjs.value) ? chartEndDayjs.value : eventEndDayjs;
        const startMinutes = startTime.diff(chartStartDayjs.value, "minutes");
        const endMinutes = endTime.diff(chartStartDayjs.value, "minutes");
        const xPosition = startMinutes / totalMinutes * ganttWidth.value;
        const width = Math.max((endMinutes - startMinutes) / totalMinutes * ganttWidth.value, 2);
        return {
          ...event,
          calculatedWidth: `${width}px`,
          calculatedX: xPosition
        };
      });
    });
    __expose({ timeaxisElement });
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", {
        ref_key: "timeaxisElement",
        ref: timeaxisElement,
        class: "g-timeaxis",
        onMousedown: handleMouseDown,
        role: "tablist",
        "aria-label": "Time Axis",
        style: normalizeStyle({
          borderBottom: `1px solid ${unref(colors).gridAndBorder}`,
          height: shouldShowEventsAxis.value ? `${80 + eventsAxisHeightValue.value}px` : "80px"
        })
      }, [
        createElementVNode("div", _hoisted_1$6, [
          (openBlock(true), createElementBlock(Fragment, null, renderList(unref(timeaxisUnits).result.upperUnits, (unit, index) => {
            return openBlock(), createElementBlock("div", {
              key: unit.date.toISOString(),
              class: "g-upper-timeunit",
              style: normalizeStyle({
                background: index % 2 === 0 ? unref(colors).primary : unref(colors).secondary,
                ...getHolidayStyle(unit, "upper"),
                color: unref(colors).text,
                width: unit.width
              }),
              onMouseenter: (e) => handleUnitMouseEnter(unit, "upper", e),
              onMouseleave: handleUnitMouseLeave
            }, [
              renderSlot(_ctx.$slots, "upper-timeunit", {
                label: formatTimeUnitLabel(unit, "upper"),
                value: unit.value,
                date: unit.date
              }, () => [
                createTextVNode(toDisplayString(formatTimeUnitLabel(unit, "upper")), 1)
              ])
            ], 44, _hoisted_2$4);
          }), 128))
        ]),
        createElementVNode("div", _hoisted_3$4, [
          (openBlock(true), createElementBlock(Fragment, null, renderList(unref(timeaxisUnits).result.lowerUnits, (unit, index) => {
            return openBlock(), createElementBlock("div", {
              key: unit.date.toISOString(),
              class: "g-timeunit",
              style: normalizeStyle({
                background: index % 2 === 0 ? unref(colors).ternary : unref(colors).quartenary,
                ...getHolidayStyle(unit, "lower"),
                color: unref(colors).text,
                flexDirection: unref(precision) === "hour" ? unref(enableMinutes) ? "column" : "row-reverse" : "row",
                alignItems: "center",
                width: unit.width
              }),
              onMouseenter: (e) => handleUnitMouseEnter(unit, "lower", e),
              onMouseleave: handleUnitMouseLeave
            }, [
              createElementVNode("div", _hoisted_5$3, [
                renderSlot(_ctx.$slots, "timeunit", {
                  label: formatTimeUnitLabel(unit, "lower"),
                  value: unit.value,
                  date: unit.date
                }, () => [
                  createElementVNode("div", _hoisted_6$3, toDisplayString(formatTimeUnitLabel(unit, "lower")), 1)
                ]),
                unref(precision) === "hour" ? (openBlock(), createElementBlock("div", {
                  key: 0,
                  class: "g-timeaxis-hour-pin",
                  style: normalizeStyle({ background: unref(colors).text })
                }, null, 4)) : createCommentVNode("", true)
              ]),
              unref(precision) === "hour" && unref(enableMinutes) ? (openBlock(), createElementBlock("div", _hoisted_7$3, [
                (openBlock(true), createElementBlock(Fragment, null, renderList(unref(timeaxisUnits).globalMinuteStep, (step) => {
                  return openBlock(), createElementBlock("div", {
                    key: `${unit.label}-${step}`,
                    style: normalizeStyle({
                      background: index % 2 === 0 ? unref(colors).ternary : unref(colors).quartenary,
                      color: unref(colors).text,
                      display: "flex",
                      flexGrow: 1,
                      flexDirection: "row-reverse",
                      alignItems: "center"
                    })
                  }, [
                    createElementVNode("div", _hoisted_8$3, toDisplayString(step), 1),
                    createElementVNode("div", {
                      class: "g-timeaxis-hour-pin",
                      style: normalizeStyle({ background: unref(colors).text })
                    }, null, 4)
                  ], 4);
                }), 128))
              ])) : createCommentVNode("", true)
            ], 44, _hoisted_4$3);
          }), 128))
        ]),
        shouldShowEventsAxis.value ? (openBlock(), createElementBlock("div", {
          key: 0,
          class: "g-events-container",
          style: normalizeStyle({
            height: `${eventsAxisHeightValue.value}px`,
            background: unref(colors).background
          })
        }, [
          (openBlock(true), createElementBlock(Fragment, null, renderList(eventPositions.value, (event) => {
            return openBlock(), createElementBlock("div", {
              key: event.id,
              class: "g-timeaxis-event",
              style: normalizeStyle({
                left: `${event.calculatedX}px`,
                width: event.calculatedWidth,
                backgroundColor: event.backgroundColor || unref(colors).primary,
                color: event.color || unref(colors).text,
                borderColor: event.color || unref(colors).primary
              }),
              onMouseenter: (e) => handleEventMouseEnter(event, e),
              onMouseleave: handleEventMouseLeave
            }, [
              createElementVNode("div", _hoisted_10$2, [
                renderSlot(_ctx.$slots, "timeaxis-event", { event }, () => [
                  createTextVNode(toDisplayString(event.label), 1)
                ])
              ])
            ], 44, _hoisted_9$3);
          }), 128))
        ], 4)) : createCommentVNode("", true),
        createVNode(_sfc_main$a, {
          "model-value": showTooltip.value,
          unit: hoveredUnit.value,
          "target-element": hoveredElement.value
        }, null, 8, ["model-value", "unit", "target-element"]),
        createVNode(_sfc_main$9, {
          "model-value": showEventTooltip.value,
          event: hoveredEvent.value,
          "target-element": hoveredEventElement.value
        }, null, 8, ["model-value", "event", "target-element"])
      ], 36);
    };
  }
});
const DEFAULT_DOT_COLOR = "cadetblue";
const _sfc_main$7 = /* @__PURE__ */ defineComponent({
  __name: "GGanttBarTooltip",
  props: {
    bar: {},
    modelValue: { type: Boolean }
  },
  setup(__props) {
    const TOOLTIP_FORMATS = {
      hour: "HH:mm",
      day: "DD. MMM HH:mm",
      date: "DD. MMMM YYYY",
      month: "DD. MMMM YYYY",
      week: "DD. MMMM YYYY (WW)"
    };
    const props = __props;
    const { bar } = toRefs(props);
    const { precision, font, barStart, barEnd, rowHeight, milestones } = provideConfig();
    const tooltipTop = ref("0px");
    const tooltipLeft = ref("0px");
    watch(
      () => props.bar,
      async () => {
        var _a;
        await nextTick();
        const barId = ((_a = bar == null ? void 0 : bar.value) == null ? void 0 : _a.ganttBarConfig.id) || "";
        if (!barId) {
          return;
        }
        const barElement = document.getElementById(barId);
        const { top, left } = (barElement == null ? void 0 : barElement.getBoundingClientRect()) || {
          top: 0,
          left: 0
        };
        const leftValue = Math.max(left, 10);
        tooltipTop.value = `${top + rowHeight.value - 10}px`;
        tooltipLeft.value = `${leftValue}px`;
      },
      { deep: true, immediate: true }
    );
    const dotColor = computed(() => {
      var _a, _b;
      return ((_b = (_a = bar == null ? void 0 : bar.value) == null ? void 0 : _a.ganttBarConfig.style) == null ? void 0 : _b.background) || DEFAULT_DOT_COLOR;
    });
    const { toDayjs } = useDayjsHelper();
    const barStartRaw = computed(() => {
      var _a;
      return (_a = bar.value) == null ? void 0 : _a[barStart.value];
    });
    const barEndRaw = computed(() => {
      var _a;
      return (_a = bar.value) == null ? void 0 : _a[barEnd.value];
    });
    const tooltipContent = computed(() => {
      if (!(bar == null ? void 0 : bar.value)) {
        return "";
      }
      const milestone = milestones.value.find((m) => {
        var _a;
        return m.id === ((_a = bar.value) == null ? void 0 : _a.ganttBarConfig.milestoneId);
      });
      const format = TOOLTIP_FORMATS[precision.value];
      const barStartFormatted = toDayjs(barStartRaw.value).format(format);
      const barEndFormatted = toDayjs(barEndRaw.value).format(format);
      const milestoneName = milestone ? ` - (${milestone.name})` : "";
      return `${barStartFormatted} – ${barEndFormatted}${milestoneName}`;
    });
    return (_ctx, _cache) => {
      return openBlock(), createBlock(Teleport, { to: "body" }, [
        createVNode(Transition, {
          name: "g-fade",
          mode: "out-in"
        }, {
          default: withCtx(() => [
            _ctx.modelValue ? (openBlock(), createElementBlock("div", {
              key: 0,
              class: "g-gantt-tooltip",
              style: normalizeStyle({
                top: tooltipTop.value,
                left: tooltipLeft.value,
                fontFamily: unref(font)
              })
            }, [
              createElementVNode("div", {
                class: "g-gantt-tooltip-color-dot",
                style: normalizeStyle({ background: dotColor.value })
              }, null, 4),
              renderSlot(_ctx.$slots, "default", {
                bar: unref(bar),
                barStart: barStartRaw.value,
                barEnd: barEndRaw.value
              }, () => [
                createTextVNode(toDisplayString(tooltipContent.value), 1)
              ])
            ], 4)) : createCommentVNode("", true)
          ]),
          _: 3
        })
      ]);
    };
  }
});
function useTimePositionMapping(config = provideConfig()) {
  const { dateFormat } = config;
  const { chartStartDayjs, chartEndDayjs, toDayjs, format } = useDayjsHelper(config);
  const totalNumOfMinutes = computed(() => {
    return chartEndDayjs.value.diff(chartStartDayjs.value, "minutes");
  });
  const mapTimeToPosition = (time) => {
    const width = ganttWidth.value || 0;
    const diffFromStart = toDayjs(time).diff(chartStartDayjs.value, "minutes", true);
    const position = Math.ceil(diffFromStart / totalNumOfMinutes.value * width);
    return position;
  };
  const mapPositionToTime = (xPos) => {
    const width = ganttWidth.value || 0;
    const diffFromStart = xPos / width * totalNumOfMinutes.value;
    return format(chartStartDayjs.value.add(diffFromStart, "minutes"), dateFormat.value);
  };
  return {
    mapTimeToPosition,
    mapPositionToTime
  };
}
const _sfc_main$6 = /* @__PURE__ */ defineComponent({
  __name: "GGanttCurrentTime",
  setup(__props) {
    const { mapTimeToPosition } = useTimePositionMapping();
    const currentMoment = ref(dayjs());
    const { colors, dateFormat, currentTimeLabel, utc: utc2 } = provideConfig();
    const xDist = ref();
    const loopTime = () => {
      const now = utc2.value ? dayjs().utc() : dayjs();
      currentMoment.value = now;
      const format = dateFormat.value || "YYYY-MM-DD HH:mm:ss";
      xDist.value = mapTimeToPosition(dayjs(currentMoment.value, format).format(format));
    };
    useIntervalFn(loopTime, 1e3);
    const currentTimeDisplay = computed(() => {
      if (utc2.value) {
        return `${currentTimeLabel.value} (UTC)`;
      }
      return currentTimeLabel.value;
    });
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", {
        class: "g-grid-current-time",
        style: normalizeStyle({
          left: `${xDist.value}px`
        })
      }, [
        createElementVNode("div", {
          class: "g-grid-current-time-marker",
          style: normalizeStyle({
            border: `1px dashed ${unref(colors).markerCurrentTime}`
          })
        }, null, 4),
        createElementVNode("span", {
          class: "g-grid-current-time-text",
          style: normalizeStyle({ color: unref(colors).markerCurrentTime })
        }, [
          renderSlot(_ctx.$slots, "current-time-label", {}, () => [
            createTextVNode(toDisplayString(currentTimeDisplay.value), 1)
          ])
        ], 4)
      ], 4);
    };
  }
});
const _hoisted_1$5 = {
  class: "gantt-connector",
  style: {
    position: "absolute",
    top: 0,
    left: 0,
    width: "100%",
    height: "100%",
    zIndex: 1001,
    overflow: "visible"
  }
};
const _hoisted_2$3 = ["id"];
const _hoisted_3$3 = ["fill"];
const _hoisted_4$2 = ["id"];
const _hoisted_5$2 = ["stop-color"];
const _hoisted_6$2 = ["stop-color"];
const _hoisted_7$2 = ["stop-color"];
const _hoisted_8$2 = ["stop-color"];
const _hoisted_9$2 = ["dur"];
const _hoisted_10$1 = ["dur"];
const _hoisted_11$1 = ["d", "stroke", "stroke-width", "stroke-dasharray"];
const _hoisted_12$1 = ["cx", "cy"];
const _hoisted_13$1 = ["cx", "cy"];
const _sfc_main$5 = /* @__PURE__ */ defineComponent({
  __name: "GGanttConnector",
  props: {
    sourceBar: {},
    targetBar: {},
    type: { default: "straight" },
    color: { default: "#ff0000" },
    strokeWidth: { default: 2 },
    pattern: { default: "solid" },
    animated: { type: Boolean, default: false },
    animationSpeed: { default: "normal" },
    marker: {},
    isSelected: { type: Boolean, default: false }
  },
  setup(__props) {
    const props = __props;
    const { enableConnectionDeletion } = provideConfig();
    const pathRef = ref(null);
    const animationClass = computed(() => {
      if (!props.animated) return "";
      return `connector-animated-${props.pattern}-${props.animationSpeed}`;
    });
    const markerId = computed(() => `marker-start-${props.sourceBar.id}-${props.targetBar.id}`);
    const hasMarkerEnd = computed(() => props.marker === "bidirectional" || props.marker === "forward");
    const hasMarkerStart = computed(() => props.marker === "bidirectional");
    const markerDeltaEnd = computed(() => hasMarkerEnd.value ? 4 : 0);
    const markerDeltaStart = computed(() => hasMarkerStart.value ? 4 : 0);
    const pathData = computed(() => {
      const sourceX = props.sourceBar.x + props.sourceBar.width;
      const sourceY = props.sourceBar.y + props.sourceBar.height / 2;
      const targetX = props.targetBar.x;
      const targetY = props.targetBar.y + props.targetBar.height / 2;
      const OFFSET = 20;
      const isGoingBack = targetX <= sourceX;
      switch (props.type) {
        case "straight":
          return `M ${sourceX},${sourceY} L ${targetX - markerDeltaEnd.value},${targetY}`;
        case "squared":
          if (isGoingBack) {
            return `M ${sourceX + markerDeltaStart.value},${sourceY}
                h ${OFFSET}
                v ${(targetY - sourceY) / 2}
                h -${Math.abs(targetX - sourceX) + OFFSET * 2}
                v ${(targetY - sourceY) / 2}
                h ${OFFSET - markerDeltaEnd.value * 2}`;
          }
          return `M ${sourceX + markerDeltaStart.value},${sourceY}
              h ${OFFSET}
              v ${targetY - sourceY}
              h ${targetX - sourceX - OFFSET - markerDeltaEnd.value * 2}`;
        case "bezier":
        default:
          const controlPointX = (sourceX + targetX) / 2;
          return `M ${sourceX + markerDeltaStart.value},${sourceY}
              C ${controlPointX},${sourceY}
                ${controlPointX},${targetY}
                ${targetX - markerDeltaEnd.value},${targetY}`;
      }
    });
    const nonAnimatedDashArray = computed(() => {
      if (props.animated) return void 0;
      switch (props.pattern) {
        case "dash":
          return "8,8";
        case "dot":
          return "2,6";
        case "dashdot":
          return "12,6,3,6";
        default:
          return "";
      }
    });
    const getStrokeWidth = computed(() => {
      if (props.isSelected && enableConnectionDeletion.value) {
        return props.strokeWidth * 1.5;
      }
      return props.strokeWidth;
    });
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("svg", _hoisted_1$5, [
        createElementVNode("defs", null, [
          createElementVNode("marker", {
            id: markerId.value,
            viewBox: "0 0 10 10",
            refX: "5",
            refY: "5",
            markerWidth: "6",
            markerHeight: "6",
            orient: "auto-start-reverse"
          }, [
            createElementVNode("path", {
              d: "M 0 0 L 10 5 L 0 10 z",
              fill: _ctx.color
            }, null, 8, _hoisted_3$3)
          ], 8, _hoisted_2$3),
          _ctx.animated && _ctx.pattern === "solid" ? (openBlock(), createElementBlock("linearGradient", {
            key: 0,
            id: `gradient-${_ctx.sourceBar.id}-${_ctx.targetBar.id}`,
            gradientUnits: "userSpaceOnUse",
            x1: "0%",
            y1: "0%",
            x2: "100%",
            y2: "0%"
          }, [
            createElementVNode("stop", {
              offset: "0%",
              "stop-color": _ctx.color,
              "stop-opacity": "0.3"
            }, null, 8, _hoisted_5$2),
            createElementVNode("stop", {
              offset: "45%",
              "stop-color": _ctx.color,
              "stop-opacity": "1"
            }, null, 8, _hoisted_6$2),
            createElementVNode("stop", {
              offset: "55%",
              "stop-color": _ctx.color,
              "stop-opacity": "1"
            }, null, 8, _hoisted_7$2),
            createElementVNode("stop", {
              offset: "100%",
              "stop-color": _ctx.color,
              "stop-opacity": "0.3"
            }, null, 8, _hoisted_8$2),
            createElementVNode("animate", {
              attributeName: "x1",
              from: "-100%",
              to: "100%",
              dur: _ctx.animationSpeed === "slow" ? "4s" : _ctx.animationSpeed === "fast" ? "1s" : "2s",
              repeatCount: "indefinite"
            }, null, 8, _hoisted_9$2),
            createElementVNode("animate", {
              attributeName: "x2",
              from: "0%",
              to: "200%",
              dur: _ctx.animationSpeed === "slow" ? "4s" : _ctx.animationSpeed === "fast" ? "1s" : "2s",
              repeatCount: "indefinite"
            }, null, 8, _hoisted_10$1)
          ], 8, _hoisted_4$2)) : createCommentVNode("", true)
        ]),
        createElementVNode("path", {
          ref_key: "pathRef",
          ref: pathRef,
          d: pathData.value,
          fill: "none",
          stroke: _ctx.animated && _ctx.pattern === "solid" ? `url(#gradient-${_ctx.sourceBar.id}-${_ctx.targetBar.id})` : _ctx.color,
          "stroke-width": getStrokeWidth.value,
          "stroke-dasharray": nonAnimatedDashArray.value,
          class: normalizeClass([
            "connector-path",
            animationClass.value,
            { selected: _ctx.isSelected && unref(enableConnectionDeletion) }
          ]),
          style: normalizeStyle({
            markerStart: hasMarkerStart.value ? `url(#${markerId.value})` : "none",
            markerEnd: hasMarkerEnd.value ? `url(#${markerId.value})` : "none",
            cursor: unref(enableConnectionDeletion) ? "pointer" : "inherit",
            pointerEvents: unref(enableConnectionDeletion) ? "all" : "none"
          })
        }, null, 14, _hoisted_11$1),
        _ctx.isSelected && unref(enableConnectionDeletion) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
          createElementVNode("circle", {
            cx: _ctx.sourceBar.x + _ctx.sourceBar.width,
            cy: _ctx.sourceBar.y + _ctx.sourceBar.height / 2,
            r: "6",
            fill: "white",
            class: "connection-endpoint"
          }, null, 8, _hoisted_12$1),
          createElementVNode("circle", {
            cx: _ctx.targetBar.x,
            cy: _ctx.targetBar.y + _ctx.targetBar.height / 2,
            r: "6",
            fill: "white",
            class: "connection-endpoint"
          }, null, 8, _hoisted_13$1)
        ], 64)) : createCommentVNode("", true)
      ]);
    };
  }
});
const _export_sfc = (sfc, props) => {
  const target = sfc.__vccOpts || sfc;
  for (const [key, val] of props) {
    target[key] = val;
  }
  return target;
};
const GGanttConnector = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-a658cc88"]]);
const _hoisted_1$4 = { class: "g-gantt-milestone-tooltip-title" };
const _hoisted_2$2 = { class: "g-gantt-milestone-tooltip-date" };
const _hoisted_3$2 = { class: "g-gantt-milestone-tooltip-description" };
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
  __name: "GGanttMilestone",
  props: {
    milestone: {}
  },
  setup(__props) {
    const props = __props;
    const { mapTimeToPosition } = useTimePositionMapping();
    const { colors } = provideConfig();
    const showTooltip = ref(false);
    const tooltipPosition = ref({ x: 0, y: 0 });
    const milestoneDate = computed(() => {
      const date = dayjs(props.milestone.date);
      if (!date.hour() && !date.minute()) {
        return date.hour(12).minute(0).format("YYYY-MM-DD HH:mm");
      }
      return props.milestone.date;
    });
    const xPosition = computed(() => {
      return mapTimeToPosition(milestoneDate.value);
    });
    const styleConfig = computed(() => {
      if (props.milestone.color) {
        return {
          label: {
            background: props.milestone.color,
            color: "#000",
            border: `2px solid ${props.milestone.color}`
          },
          marker: {
            borderLeft: `2px solid ${props.milestone.color}`
          }
        };
      }
      return {
        label: {
          background: colors.value.primary,
          color: colors.value.text,
          border: "none"
        },
        marker: {
          borderLeft: `2px solid ${colors.value.markerCurrentTime}`
        }
      };
    });
    const handleMouseEnter = (event) => {
      const element = event.target;
      const rect = element.getBoundingClientRect();
      tooltipPosition.value = {
        x: rect.left,
        y: rect.top + 10
      };
      showTooltip.value = true;
    };
    const handleMouseLeave = () => {
      showTooltip.value = false;
    };
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", {
        class: "g-gantt-milestone",
        style: normalizeStyle({
          left: `${xPosition.value}px`
        }),
        onMouseenter: handleMouseEnter,
        onMouseleave: handleMouseLeave
      }, [
        renderSlot(_ctx.$slots, `milestone-${_ctx.milestone.id}`, {
          milestone: _ctx.milestone,
          styleConfig: styleConfig.value,
          position: xPosition.value
        }, () => [
          renderSlot(_ctx.$slots, "milestone", {
            milestone: _ctx.milestone,
            styleConfig: styleConfig.value,
            position: xPosition.value
          }, () => [
            createElementVNode("div", {
              class: "g-gantt-milestone-label",
              style: normalizeStyle(styleConfig.value.label)
            }, toDisplayString(_ctx.milestone.name), 5)
          ])
        ]),
        createElementVNode("div", {
          class: "g-gantt-milestone-marker",
          style: normalizeStyle(styleConfig.value.marker)
        }, null, 4),
        (openBlock(), createBlock(Teleport, { to: "body" }, [
          createVNode(Transition, {
            name: "g-fade",
            mode: "out-in"
          }, {
            default: withCtx(() => [
              showTooltip.value ? (openBlock(), createElementBlock("div", {
                key: 0,
                class: "g-gantt-milestone-tooltip",
                style: normalizeStyle({
                  top: `${tooltipPosition.value.y}px`,
                  left: `${tooltipPosition.value.x}px`,
                  background: unref(colors).primary,
                  color: unref(colors).text
                })
              }, [
                createElementVNode("div", _hoisted_1$4, toDisplayString(_ctx.milestone.name), 1),
                createElementVNode("div", _hoisted_2$2, toDisplayString(_ctx.milestone.date), 1),
                createElementVNode("div", _hoisted_3$2, toDisplayString(_ctx.milestone.description), 1)
              ], 4)) : createCommentVNode("", true)
            ]),
            _: 1
          })
        ]))
      ], 36);
    };
  }
});
function provideEmitBarEvent() {
  const emitBarEvent = inject(EMIT_BAR_EVENT_KEY);
  if (!emitBarEvent) {
    throw Error("Failed to inject emitBarEvent!");
  }
  return emitBarEvent;
}
function useBarSelector() {
  const findBarElement = (ganttId, barId) => {
    const ganttContainer = document.getElementById(ganttId);
    if (!ganttContainer) return null;
    return ganttContainer.querySelector(`#${CSS.escape(barId)}`);
  };
  const findAllBarElements = (ganttId) => {
    const ganttContainer = document.getElementById(ganttId);
    if (!ganttContainer) return document.querySelectorAll(".non-existent");
    return ganttContainer.querySelectorAll(".g-gantt-bar");
  };
  const barExistsInGantt = (ganttId, barId) => {
    return !!findBarElement(ganttId, barId);
  };
  return {
    findBarElement,
    findAllBarElements,
    barExistsInGantt
  };
}
function createBarDrag(bar, onDrag = () => null, onEndDrag = () => null, config, movementAPI, ganttId) {
  const { findBarElement } = useBarSelector();
  const { barStart, barEnd } = config;
  const isDragging = ref(false);
  let cursorOffsetX = 0;
  let initialBarLeft = 0;
  let dragCallBack;
  const { mapPositionToTime } = useTimePositionMapping(config);
  const { toDayjs } = useDayjsHelper(config);
  const initDrag = (e) => {
    if (bar.ganttBarConfig.immobile) {
      return;
    }
    const barElement = findBarElement(ganttId, bar.ganttBarConfig.id);
    if (!barElement) {
      return;
    }
    const rect = barElement.getBoundingClientRect();
    initialBarLeft = rect.left;
    cursorOffsetX = e.clientX - initialBarLeft;
    const mousedownType = e.target.className;
    switch (mousedownType) {
      case "g-gantt-bar-handle-left":
        document.body.style.cursor = "ew-resize";
        dragCallBack = dragByLeftHandle;
        break;
      case "g-gantt-bar-handle-right":
        document.body.style.cursor = "ew-resize";
        dragCallBack = dragByRightHandle;
        break;
      default:
        dragCallBack = drag;
    }
    isDragging.value = true;
    window.addEventListener("mousemove", dragCallBack);
    window.addEventListener("mouseup", endDrag);
  };
  const getBarElements = () => {
    const barElement = findBarElement(ganttId, bar.ganttBarConfig.id);
    let currentElement = barElement;
    let barContainer = null;
    while (currentElement && !barContainer) {
      const container = currentElement.closest(".g-gantt-row-bars-container");
      if (container) {
        barContainer = container.getBoundingClientRect();
      }
      currentElement = currentElement.parentElement;
    }
    return { barElement, barContainer };
  };
  const drag = (e) => {
    const { barElement, barContainer } = getBarElements();
    if (!barElement || !barContainer) {
      console.warn("Missing elements:", { barElement, barContainer });
      return;
    }
    const barWidth = barElement.getBoundingClientRect().width;
    const relativeX = e.clientX - cursorOffsetX - barContainer.left;
    const xStart = Math.max(0, relativeX);
    const xEnd = xStart + barWidth;
    const newBarStart = mapPositionToTime(xStart);
    const newBarEnd = mapPositionToTime(xEnd);
    const currentStart = bar[barStart.value];
    const currentEnd = bar[barEnd.value];
    const result = movementAPI.moveBar(bar, newBarStart, newBarEnd);
    if (!result.success) {
      bar[barStart.value] = currentStart;
      bar[barEnd.value] = currentEnd;
      endDrag(e);
      return;
    }
    onDrag(e, bar);
  };
  const dragByLeftHandle = (e) => {
    const { barContainer } = getBarElements();
    if (!barContainer) {
      return;
    }
    const xStart = e.clientX - barContainer.left;
    const newBarStart = mapPositionToTime(xStart);
    if (toDayjs(newBarStart).isSameOrAfter(toDayjs(bar[barEnd.value]))) {
      return;
    }
    const result = movementAPI.moveBar(bar, newBarStart, bar[barEnd.value]);
    if (result.success) {
      onDrag(e, bar);
    }
  };
  const dragByRightHandle = (e) => {
    const { barContainer } = getBarElements();
    if (!barContainer) {
      return;
    }
    const xEnd = e.clientX - barContainer.left;
    const newBarEnd = mapPositionToTime(xEnd);
    if (toDayjs(newBarEnd).isSameOrBefore(toDayjs(bar[barStart.value]))) {
      return;
    }
    const result = movementAPI.moveBar(bar, bar[barStart.value], newBarEnd);
    if (result.success) {
      onDrag(e, bar);
    }
  };
  const endDrag = (e) => {
    isDragging.value = false;
    document.body.style.cursor = "";
    window.removeEventListener("mousemove", dragCallBack);
    window.removeEventListener("mouseup", endDrag);
    onEndDrag(e, bar);
  };
  return {
    isDragging,
    initDrag
  };
}
function useBarMovement(config, rowManager, dayjsHelper) {
  const { barStart, barEnd, dateFormat, pushOnOverlap, pushOnConnect } = config;
  const processedBars = /* @__PURE__ */ new Set();
  const formatDate = (date) => {
    const result = dayjsHelper.format(date, dateFormat.value);
    return typeof result === "string" ? result : result.toISOString();
  };
  const checkMilestoneConstraint = (bar, newEnd) => {
    if (!bar.ganttBarConfig.milestoneId || !config.milestones.value) return true;
    const milestone = config.milestones.value.find((m) => m.id === bar.ganttBarConfig.milestoneId);
    if (!milestone) return true;
    const endDate = dayjsHelper.toDayjs(newEnd);
    const date = dayjs(milestone.date);
    let milestoneDate = date;
    if (!date.hour() && !date.minute()) {
      milestoneDate = dayjsHelper.toDayjs(date.hour(23).minute(59).format("YYYY-MM-DD HH:mm"));
    }
    return endDate.isSameOrBefore(milestoneDate);
  };
  const getAllBars = () => {
    const extractBarsFromRow = (row) => {
      var _a;
      let bars = [...row.bars];
      if ((_a = row.children) == null ? void 0 : _a.length) {
        row.children.forEach((child) => {
          bars = [...bars, ...extractBarsFromRow(child)];
        });
      }
      return bars;
    };
    return rowManager.rows.value.flatMap((row) => extractBarsFromRow(row));
  };
  const moveBar = (bar, newStart, newEnd, initialMove = true) => {
    if (processedBars.has(bar.ganttBarConfig.id)) {
      return { success: true, affectedBars: /* @__PURE__ */ new Set() };
    }
    if (!checkMilestoneConstraint(bar, newEnd)) {
      return { success: false, affectedBars: /* @__PURE__ */ new Set() };
    }
    processedBars.add(bar.ganttBarConfig.id);
    const affectedBars = /* @__PURE__ */ new Set();
    const originalStart = bar[barStart.value];
    const originalEnd = bar[barEnd.value];
    bar[barStart.value] = newStart;
    bar[barEnd.value] = newEnd;
    if (bar.ganttBarConfig.bundle && initialMove) {
      const bundleBars = getAllBars().filter(
        (b) => b.ganttBarConfig.bundle === bar.ganttBarConfig.bundle && b !== bar
      );
      const timeDiff = dayjsHelper.toDayjs(newStart).diff(dayjsHelper.toDayjs(originalStart), "minutes");
      for (const bundleBar of bundleBars) {
        const bundleBarNewStart = formatDate(
          dayjsHelper.toDayjs(bundleBar[barStart.value]).add(timeDiff, "minutes")
        );
        const bundleBarNewEnd = formatDate(
          dayjsHelper.toDayjs(bundleBar[barEnd.value]).add(timeDiff, "minutes")
        );
        const bundleResult = moveBar(bundleBar, bundleBarNewStart, bundleBarNewEnd, false);
        if (!bundleResult.success) {
          bar[barStart.value] = originalStart;
          bar[barEnd.value] = originalEnd;
          processedBars.delete(bar.ganttBarConfig.id);
          return { success: false, affectedBars: /* @__PURE__ */ new Set() };
        }
        bundleResult.affectedBars.forEach((b) => affectedBars.add(b));
      }
    }
    const result = handleBarInteractions(bar, affectedBars);
    if (!result.success) {
      bar[barStart.value] = originalStart;
      bar[barEnd.value] = originalEnd;
      processedBars.delete(bar.ganttBarConfig.id);
      return { success: false, affectedBars: /* @__PURE__ */ new Set() };
    }
    if (initialMove) {
      processedBars.clear();
    }
    affectedBars.add(bar);
    return { success: true, affectedBars };
  };
  const handleBarInteractions = (bar, affectedBars) => {
    const overlappingBars = pushOnOverlap.value ? findOverlappingBars(bar) : [];
    const connectedBars = pushOnConnect.value ? findConnectedBars(bar) : [];
    const impactedBars = [.../* @__PURE__ */ new Set([...overlappingBars, ...connectedBars])];
    for (const impactedBar of impactedBars) {
      if (impactedBar.ganttBarConfig.immobile) {
        return { success: false };
      }
      const { shouldMove, minutesToMove, direction } = calculateMovement(bar, impactedBar);
      if (!shouldMove) continue;
      const newStart = formatDate(
        direction === "left" ? dayjsHelper.toDayjs(impactedBar[barStart.value]).subtract(minutesToMove, "minutes") : dayjsHelper.toDayjs(impactedBar[barStart.value]).add(minutesToMove, "minutes")
      );
      const newEnd = formatDate(
        direction === "left" ? dayjsHelper.toDayjs(impactedBar[barEnd.value]).subtract(minutesToMove, "minutes") : dayjsHelper.toDayjs(impactedBar[barEnd.value]).add(minutesToMove, "minutes")
      );
      if (!checkMilestoneConstraint(impactedBar, newEnd)) {
        return { success: false };
      }
      const result = moveBar(impactedBar, newStart, newEnd, false);
      if (!result.success) {
        return { success: false };
      }
      affectedBars.add(impactedBar);
      result.affectedBars.forEach((b) => affectedBars.add(b));
    }
    return { success: true };
  };
  const calculateMovement = (sourceBar, targetBar) => {
    const sourceStart = dayjsHelper.toDayjs(sourceBar[barStart.value]);
    const sourceEnd = dayjsHelper.toDayjs(sourceBar[barEnd.value]);
    const targetStart = dayjsHelper.toDayjs(targetBar[barStart.value]);
    const targetEnd = dayjsHelper.toDayjs(targetBar[barEnd.value]);
    if (targetBar.ganttBarConfig.immobile && (sourceStart.isBefore(targetEnd) && sourceEnd.isAfter(targetStart) || sourceEnd.isAfter(targetStart) && sourceStart.isBefore(targetEnd))) {
      return { shouldMove: false, minutesToMove: 0, direction: "right" };
    }
    if (sourceEnd.isSameOrBefore(targetStart) || sourceStart.isSameOrAfter(targetEnd)) {
      return { shouldMove: false, minutesToMove: 0, direction: "right" };
    }
    const direction = sourceStart.isBefore(targetStart) ? "right" : "left";
    let minutesToMove = 0;
    if (direction === "right") {
      minutesToMove = sourceEnd.diff(targetStart, "minutes", true);
    } else {
      minutesToMove = targetEnd.diff(sourceStart, "minutes", true);
    }
    return {
      shouldMove: true,
      minutesToMove: Math.abs(minutesToMove),
      direction
    };
  };
  const findOverlappingBars = (bar) => {
    const findRowForBar = (searchBar, rows) => {
      var _a;
      for (const row of rows) {
        if (row.bars.includes(searchBar)) return row;
        if ((_a = row.children) == null ? void 0 : _a.length) {
          const foundInChildren = findRowForBar(searchBar, row.children);
          if (foundInChildren) return foundInChildren;
        }
      }
      return null;
    };
    const barRow = findRowForBar(bar, rowManager.rows.value);
    if (!barRow) return [];
    return barRow.bars.filter((otherBar) => {
      if (otherBar === bar || otherBar.ganttBarConfig.pushOnOverlap === false) return false;
      if (otherBar.ganttBarConfig.id.startsWith("group-")) return false;
      const start1 = dayjsHelper.toDayjs(bar[barStart.value]);
      const end1 = dayjsHelper.toDayjs(bar[barEnd.value]);
      const start2 = dayjsHelper.toDayjs(otherBar[barStart.value]);
      const end2 = dayjsHelper.toDayjs(otherBar[barEnd.value]);
      return start1.isBefore(end2) && end1.isAfter(start2) || start2.isBefore(end1) && end2.isAfter(start1);
    });
  };
  const findConnectedBars = (bar) => {
    var _a;
    const allBars = getAllBars();
    const connectedBars = [];
    (_a = bar.ganttBarConfig.connections) == null ? void 0 : _a.forEach((conn) => {
      const targetBar = allBars.find((b) => b.ganttBarConfig.id === conn.targetId);
      if (targetBar && targetBar.ganttBarConfig.pushOnConnect !== false) {
        connectedBars.push(targetBar);
      }
    });
    allBars.forEach((otherBar) => {
      var _a2;
      (_a2 = otherBar.ganttBarConfig.connections) == null ? void 0 : _a2.forEach((conn) => {
        if (conn.targetId === bar.ganttBarConfig.id && otherBar.ganttBarConfig.pushOnConnect !== false) {
          connectedBars.push(otherBar);
        }
      });
    });
    return connectedBars;
  };
  return {
    moveBar,
    findOverlappingBars,
    findConnectedBars,
    getAllBars
  };
}
const useBarDragManagement = () => {
  const config = provideConfig();
  const emitBarEvent = provideEmitBarEvent();
  const dayjs2 = useDayjsHelper(config);
  const { barStart, barEnd } = config;
  const rowManager = inject("useRows");
  const ganttId = inject(GANTT_ID_KEY);
  const movement = useBarMovement(config, rowManager, dayjs2);
  const dragState = {
    movedBars: /* @__PURE__ */ new Map(),
    isDragging: false
  };
  const getBundleBars = (bundle) => {
    const res = [];
    if (bundle != null) {
      const allBars = movement.getAllBars();
      allBars.forEach((bar) => {
        if (bar.ganttBarConfig.bundle === bundle) {
          res.push(bar);
        }
      });
    }
    return res;
  };
  const initDragOfBar = (bar, e) => {
    if (bar.ganttBarConfig.bundle) {
      initDragOfBundle(bar, e);
      return;
    }
    const dragHandler = createDragHandler(bar);
    dragHandler.initiateDrag(e);
    addBarToMovedBars(bar);
    emitBarEvent({ ...e, type: "dragstart" }, bar);
  };
  const initDragOfBundle = (mainBar, e) => {
    const bundle = mainBar.ganttBarConfig.bundle;
    if (!bundle) return;
    const bundleBars = getBundleBars(bundle);
    bundleBars.forEach((bar) => {
      const isMainBar = bar === mainBar;
      const dragHandler = createDragHandler(bar, isMainBar);
      dragHandler.initiateDrag(e);
      addBarToMovedBars(bar);
    });
    emitBarEvent({ ...e, type: "dragstart" }, mainBar);
  };
  const createDragHandler = (bar, isMainBar = true) => ({
    initiateDrag: (e) => {
      const { initDrag } = createBarDrag(
        bar,
        (e2) => handleDrag(e2, bar),
        isMainBar ? handleDragEnd : () => null,
        config,
        movement,
        ganttId
      );
      initDrag(e);
    }
  });
  const handleDrag = (e, bar) => {
    emitBarEvent({ ...e, type: "drag" }, bar);
    const result = movement.moveBar(bar, bar[barStart.value], bar[barEnd.value]);
    if (!result.success) {
      snapBackMovedBars();
    } else {
      result.affectedBars.forEach((affectedBar) => {
        if (!dragState.movedBars.has(affectedBar)) {
          addBarToMovedBars(affectedBar);
        }
      });
    }
  };
  const handleDragEnd = (e, bar) => {
    emitBarEvent({ ...e, type: "dragend" }, bar, void 0, new Map(dragState.movedBars));
    dragState.movedBars.clear();
    dragState.isDragging = false;
  };
  const addBarToMovedBars = (bar) => {
    if (!dragState.movedBars.has(bar)) {
      dragState.movedBars.set(bar, {
        oldStart: bar[barStart.value],
        oldEnd: bar[barEnd.value]
      });
    }
  };
  const snapBackMovedBars = () => {
    dragState.movedBars.forEach(({ oldStart, oldEnd }, bar) => {
      bar[barStart.value] = oldStart;
      bar[barEnd.value] = oldEnd;
    });
  };
  return {
    initDragOfBar,
    initDragOfBundle,
    snapBackMovedBars,
    handleDrag,
    getConnectedBars: movement.findConnectedBars
  };
};
function useBarDragLimit() {
  const { pushOnOverlap, pushOnConnect } = provideConfig();
  const { getConnectedBars } = useBarDragManagement();
  const rowManager = inject("useRows");
  const ganttId = inject(GANTT_ID_KEY);
  const { findBarElement } = useBarSelector();
  const getBarsFromBundle = (bundle) => {
    const res = [];
    if (bundle != null) {
      rowManager.rows.value.forEach((row) => {
        row.bars.forEach((bar) => {
          if (bar.ganttBarConfig.bundle === bundle) {
            res.push(bar);
          }
        });
      });
    }
    return res;
  };
  const setDragLimitsOfGanttBar = (bar) => {
    if (!pushOnOverlap.value || bar.ganttBarConfig.pushOnOverlap === false || !pushOnConnect.value || bar.ganttBarConfig.pushOnConnect === false) {
      return;
    }
    for (const sideValue of ["left", "right"]) {
      const side = sideValue;
      const { gapDistanceSoFar, bundleBarsAndGapDist } = countGapDistanceToNextImmobileBar(
        bar,
        0,
        side
      );
      let totalGapDistance = gapDistanceSoFar;
      const bundleBarsOnPath = bundleBarsAndGapDist;
      if (!bundleBarsOnPath) {
        continue;
      }
      for (let i = 0; i < bundleBarsOnPath.length; i++) {
        const barFromBundle = bundleBarsOnPath[i].bar;
        const gapDist = bundleBarsOnPath[i].gapDistance;
        const otherBarsFromBundle = getBarsFromBundle(barFromBundle.ganttBarConfig.bundle).filter(
          (otherBar) => otherBar !== barFromBundle
        );
        otherBarsFromBundle.forEach((otherBar) => {
          const nextGapDistanceAndBars = countGapDistanceToNextImmobileBar(otherBar, gapDist, side);
          const newGapDistance = nextGapDistanceAndBars.gapDistanceSoFar;
          const newBundleBars = nextGapDistanceAndBars.bundleBarsAndGapDist;
          if (newGapDistance != null && (!totalGapDistance || newGapDistance < totalGapDistance)) {
            totalGapDistance = newGapDistance;
          }
          newBundleBars.forEach((newBundleBar) => {
            if (!bundleBarsOnPath.find((barAndGap) => barAndGap.bar === newBundleBar.bar)) {
              bundleBarsOnPath.push(newBundleBar);
            }
          });
        });
      }
      const barElem = findBarElement(ganttId, bar.ganttBarConfig.id);
      if (totalGapDistance != null && side === "left") {
        bar.ganttBarConfig.dragLimitLeft = barElem.offsetLeft - totalGapDistance;
      } else if (totalGapDistance != null && side === "right") {
        bar.ganttBarConfig.dragLimitRight = barElem.offsetLeft + barElem.offsetWidth + totalGapDistance;
      }
    }
    const barsFromBundleOfClickedBar = getBarsFromBundle(bar.ganttBarConfig.bundle);
    barsFromBundleOfClickedBar.forEach((barFromBundle) => {
      barFromBundle.ganttBarConfig.dragLimitLeft = bar.ganttBarConfig.dragLimitLeft;
      barFromBundle.ganttBarConfig.dragLimitRight = bar.ganttBarConfig.dragLimitRight;
    });
  };
  const countGapDistanceToNextImmobileBar = (bar, gapDistanceSoFar = 0, side) => {
    const bundleBarsAndGapDist = bar.ganttBarConfig.bundle ? [{ bar, gapDistance: gapDistanceSoFar }] : [];
    let currentBar = bar;
    let nextBar = getNextGanttBar(currentBar, side);
    if (side === "left") {
      while (nextBar) {
        const currentBarElem = findBarElement(ganttId, currentBar.ganttBarConfig.id);
        const nextBarElem = findBarElement(ganttId, nextBar.ganttBarConfig.id);
        const nextBarOffsetRight = nextBarElem.offsetLeft + nextBarElem.offsetWidth;
        gapDistanceSoFar += currentBarElem.offsetLeft - nextBarOffsetRight;
        if (nextBar.ganttBarConfig.immobile) {
          return { gapDistanceSoFar, bundleBarsAndGapDist };
        } else if (nextBar.ganttBarConfig.bundle) {
          bundleBarsAndGapDist.push({
            bar: nextBar,
            gapDistance: gapDistanceSoFar
          });
        }
        currentBar = nextBar;
        nextBar = getNextGanttBar(nextBar, "left");
      }
    }
    if (side === "right") {
      while (nextBar) {
        const currentBarElem = findBarElement(ganttId, currentBar.ganttBarConfig.id);
        const nextBarElem = findBarElement(ganttId, nextBar.ganttBarConfig.id);
        const currentBarOffsetRight = currentBarElem.offsetLeft + currentBarElem.offsetWidth;
        gapDistanceSoFar += nextBarElem.offsetLeft - currentBarOffsetRight;
        if (nextBar.ganttBarConfig.immobile) {
          return { gapDistanceSoFar, bundleBarsAndGapDist };
        } else if (nextBar.ganttBarConfig.bundle) {
          bundleBarsAndGapDist.push({
            bar: nextBar,
            gapDistance: gapDistanceSoFar
          });
        }
        currentBar = nextBar;
        nextBar = getNextGanttBar(nextBar, "right");
      }
    }
    return { gapDistanceSoFar: null, bundleBarsAndGapDist };
  };
  const getNextGanttBar = (bar, side) => {
    var _a;
    const barElem = findBarElement(ganttId, bar.ganttBarConfig.id);
    let allBarsInRow = [];
    if (pushOnOverlap.value) {
      allBarsInRow = ((_a = rowManager.rows.value.find((row) => row.bars.includes(bar))) == null ? void 0 : _a.bars) || [];
    }
    if (pushOnConnect.value) {
      allBarsInRow = [...allBarsInRow, ...getConnectedBars(bar)];
    }
    let allBarsLeftOrRight = [];
    if (side === "left") {
      allBarsLeftOrRight = allBarsInRow.filter((otherBar) => {
        const otherBarElem = findBarElement(ganttId, otherBar.ganttBarConfig.id);
        return otherBarElem && otherBarElem.offsetLeft < barElem.offsetLeft && otherBar.ganttBarConfig.pushOnOverlap !== false && otherBar.ganttBarConfig.pushOnConnect !== false;
      });
    } else {
      allBarsLeftOrRight = allBarsInRow.filter((otherBar) => {
        const otherBarElem = findBarElement(ganttId, otherBar.ganttBarConfig.id);
        return otherBarElem && otherBarElem.offsetLeft > barElem.offsetLeft && otherBar.ganttBarConfig.pushOnOverlap !== false && otherBar.ganttBarConfig.pushOnConnect !== false;
      });
    }
    if (allBarsLeftOrRight.length > 0) {
      return allBarsLeftOrRight.reduce((bar1, bar2) => {
        const bar1Elem = findBarElement(ganttId, bar1.ganttBarConfig.id);
        const bar2Elem = findBarElement(ganttId, bar2.ganttBarConfig.id);
        const bar1Dist = Math.abs(bar1Elem.offsetLeft - barElem.offsetLeft);
        const bar2Dist = Math.abs(bar2Elem.offsetLeft - barElem.offsetLeft);
        return bar1Dist < bar2Dist ? bar1 : bar2;
      }, allBarsLeftOrRight[0]);
    } else {
      return null;
    }
  };
  return {
    setDragLimitsOfGanttBar
  };
}
function useBarKeyboardControl(bar, config, emitBarEvent) {
  const dayjs2 = useDayjsHelper(config);
  const { barStart, barEnd, dateFormat, precision } = config;
  const rowManager = inject("useRows");
  const movement = useBarMovement(config, rowManager, dayjs2);
  const TIME_STEP = {
    hour: 5,
    day: 120,
    week: 840,
    month: 3600
  };
  const getTimeStep = (isShiftPressed) => {
    const baseStep = TIME_STEP[precision.value] || TIME_STEP.hour;
    return isShiftPressed ? baseStep * 12 : baseStep;
  };
  const moveBarPosition = (direction, isShiftPressed) => {
    const multiplier = direction === "forward" ? 1 : -1;
    const minutesToMove = getTimeStep(isShiftPressed);
    const currentStart = dayjs2.toDayjs(bar[barStart.value]);
    const currentEnd = dayjs2.toDayjs(bar[barEnd.value]);
    const newStart = currentStart.add(minutesToMove * multiplier, "minutes");
    const newEnd = currentEnd.add(minutesToMove * multiplier, "minutes");
    if (newStart.isBefore(config.chartStart.value) || newEnd.isAfter(config.chartEnd.value)) {
      return;
    }
    const newStartStr = dayjs2.format(newStart, dateFormat.value);
    const newEndStr = dayjs2.format(newEnd, dateFormat.value);
    const result = movement.moveBar(bar, newStartStr, newEndStr);
    if (result.success) {
      emitDragEvents();
    }
  };
  const resizeBar = (type, isShiftPressed) => {
    const currentStart = dayjs2.toDayjs(bar[barStart.value]);
    const currentEnd = dayjs2.toDayjs(bar[barEnd.value]);
    let minutesToMove = getTimeStep(isShiftPressed);
    if (minutesToMove === 5) {
      minutesToMove = 10;
    }
    const timePerSide = minutesToMove / 2;
    let newStart;
    let newEnd;
    if (type === "expand") {
      newStart = dayjs2.format(
        currentStart.subtract(timePerSide, "minutes"),
        dateFormat.value
      );
      newEnd = dayjs2.format(currentEnd.add(timePerSide, "minutes"), dateFormat.value);
    } else {
      const currentDuration = currentEnd.diff(currentStart, "minutes");
      if (currentDuration <= minutesToMove) {
        return;
      }
      newStart = dayjs2.format(currentStart.add(timePerSide, "minutes"), dateFormat.value);
      newEnd = dayjs2.format(currentEnd.subtract(timePerSide, "minutes"), dateFormat.value);
    }
    const startDayjs = dayjs2.toDayjs(newStart);
    const endDayjs = dayjs2.toDayjs(newEnd);
    if (startDayjs.isBefore(config.chartStart.value) || endDayjs.isAfter(config.chartEnd.value)) {
      return;
    }
    const result = movement.moveBar(bar, newStart, newEnd);
    if (result.success) {
      emitDragEvents();
    }
  };
  const emitDragEvents = () => {
    const mockEvent = new MouseEvent("drag", { bubbles: true });
    emitBarEvent(mockEvent, bar);
    const mockEndEvent = new MouseEvent("dragend", { bubbles: true });
    emitBarEvent(mockEndEvent, bar);
  };
  const onBarKeyDown = (event) => {
    const target = event.target;
    if (!target.id || target.id !== bar.ganttBarConfig.id || bar.ganttBarConfig.immobile) {
      return;
    }
    switch (event.key) {
      case "ArrowLeft":
        event.preventDefault();
        moveBarPosition("backward", event.shiftKey);
        break;
      case "ArrowRight":
        event.preventDefault();
        moveBarPosition("forward", event.shiftKey);
        break;
      case "ArrowUp":
        event.preventDefault();
        resizeBar("expand", event.shiftKey);
        break;
      case "ArrowDown":
        event.preventDefault();
        resizeBar("shrink", event.shiftKey);
        break;
    }
  };
  return {
    onBarKeyDown
  };
}
function useTouchEvents(initDragCallback, threshold = 5) {
  const touchState = ref({
    isDragging: false,
    startX: 0,
    startY: 0,
    lastX: 0,
    lastY: 0,
    currentBar: null,
    dragTarget: null
  });
  const resetTouchState = () => {
    touchState.value = {
      isDragging: false,
      startX: 0,
      startY: 0,
      lastX: 0,
      lastY: 0,
      currentBar: null,
      dragTarget: null
    };
  };
  const determineDragTarget = (element) => {
    if (element.classList.contains("g-gantt-bar-handle-left")) {
      return "leftHandle";
    }
    if (element.classList.contains("g-gantt-bar-handle-right")) {
      return "rightHandle";
    }
    if (element.classList.contains("g-gantt-bar")) {
      return "bar";
    }
    const barElement = element.closest(".g-gantt-bar");
    if (barElement) {
      return "bar";
    }
    return null;
  };
  const createMouseEventFromTouch = (touch, eventType, movementX = 0, movementY = 0) => {
    const mouseEvent = new MouseEvent(eventType, {
      bubbles: true,
      cancelable: true,
      clientX: touch.clientX,
      clientY: touch.clientY,
      movementX,
      movementY,
      view: window
    });
    if (touchState.value.currentBar) {
      const targetElement = document.querySelector(
        `#${touchState.value.currentBar.ganttBarConfig.id}`
      );
      if (targetElement) {
        Object.defineProperty(mouseEvent, "target", { value: targetElement });
      }
    }
    return mouseEvent;
  };
  const handleTouchStart = (event, bar) => {
    const touch = event.touches[0];
    if (!touch || !bar) return;
    const targetElement = event.target;
    if (!targetElement) return;
    const dragTarget = determineDragTarget(targetElement);
    if (!dragTarget) return;
    event.preventDefault();
    touchState.value = {
      isDragging: false,
      startX: touch.clientX,
      startY: touch.clientY,
      lastX: touch.clientX,
      lastY: touch.clientY,
      currentBar: bar,
      dragTarget
    };
    const mouseEvent = createMouseEventFromTouch(touch, "mousedown");
    initDragCallback(bar, mouseEvent);
  };
  const handleTouchMove = (event) => {
    const touch = event.touches[0];
    if (!touch || !touchState.value.currentBar) return;
    const deltaX = Math.abs(touch.clientX - touchState.value.startX);
    const deltaY = Math.abs(touch.clientY - touchState.value.startY);
    if (!touchState.value.isDragging && (deltaX > threshold || deltaY > threshold)) {
      touchState.value.isDragging = true;
    }
    if (touchState.value.isDragging) {
      event.preventDefault();
      const movementX = touch.clientX - touchState.value.lastX;
      const movementY = touch.clientY - touchState.value.lastY;
      touchState.value.lastX = touch.clientX;
      touchState.value.lastY = touch.clientY;
      const mouseEvent = createMouseEventFromTouch(touch, "mousemove", movementX, movementY);
      window.dispatchEvent(mouseEvent);
    }
  };
  const handleTouchEnd = (event) => {
    const touch = event.changedTouches[0];
    if (!touch || !touchState.value.currentBar) return;
    if (touchState.value.isDragging) {
      event.preventDefault();
      const mouseEvent = createMouseEventFromTouch(touch, "mouseup");
      window.dispatchEvent(mouseEvent);
    }
    resetTouchState();
  };
  const handleTouchCancel = handleTouchEnd;
  return {
    handleTouchStart,
    handleTouchMove,
    handleTouchEnd,
    handleTouchCancel
  };
}
const _hoisted_1$3 = ["id", "aria-label", "aria-grabbed", "aria-describedby"];
const _hoisted_2$1 = {
  key: 0,
  class: "progress-text"
};
const _hoisted_3$1 = ["width", "height"];
const _hoisted_4$1 = ["d", "fill"];
const _hoisted_5$1 = { class: "g-gantt-bar-label" };
const _hoisted_6$1 = { key: 0 };
const _hoisted_7$1 = {
  key: 0,
  class: "g-gantt-bar-label-edit"
};
const _hoisted_8$1 = { key: 1 };
const _hoisted_9$1 = ["innerHTML"];
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
  __name: "GGanttBar",
  props: {
    bar: {}
  },
  setup(__props) {
    const props = __props;
    const ganttId = inject(GANTT_ID_KEY);
    const connectionCreation = inject("connectionCreation");
    const emitBarEvent = provideEmitBarEvent();
    const config = provideConfig();
    const { rowHeight } = config;
    const { bar } = toRefs(props);
    const { mapTimeToPosition, mapPositionToTime } = useTimePositionMapping();
    const { initDragOfBar, initDragOfBundle } = useBarDragManagement();
    const { setDragLimitsOfGanttBar } = useBarDragLimit();
    const isDragging = ref(false);
    const isEditing = ref(false);
    const editedLabel = ref("");
    const labelInput = ref(null);
    const {
      barStart,
      barEnd,
      width,
      chartStart,
      chartEnd,
      chartSize,
      showLabel,
      showProgress,
      defaultProgressResizable,
      enableConnectionCreation,
      barLabelEditable
    } = config;
    const xStart = ref(0);
    const xEnd = ref(0);
    const barConfig = computed(() => bar.value.ganttBarConfig);
    const isGroupBar = computed(() => {
      return bar.value.ganttBarConfig.id.startsWith("group-");
    });
    const progressStyle = computed(() => {
      var _a;
      const progress = props.bar.ganttBarConfig.progress ?? 0;
      const baseStyle = props.bar.ganttBarConfig.progressStyle || {};
      const barColor = ((_a = props.bar.ganttBarConfig.style) == null ? void 0 : _a.background) || "#5F9EA0";
      return {
        ...baseStyle,
        left: 0,
        width: `${Math.min(Math.max(progress, 0), 100)}%`,
        backgroundColor: baseStyle.backgroundColor || getDarkerColor(barColor),
        transition: "width 0.3s ease",
        borderRadius: "inherit",
        height: "100%"
      };
    });
    const connectionPointStyle = computed(() => ({
      width: "12px",
      height: "12px",
      borderRadius: "50%",
      cursor: "pointer",
      background: canBeTarget.value ? "#00ff00" : "#ff0000",
      transition: "all 0.2s ease",
      opacity: (connectionCreation == null ? void 0 : connectionCreation.connectionState.value.isCreating) || isBarHovered.value || startPointHover.value || endPointHover.value ? 1 : 0,
      zIndex: 1e3
    }));
    const startPointStyle = computed(() => ({
      ...connectionPointStyle.value,
      left: 0,
      top: "50%",
      transform: "translate(-50%, -50%)"
    }));
    const endPointStyle = computed(() => ({
      ...connectionPointStyle.value,
      right: 0,
      top: "50%",
      transform: "translate(50%, -50%)"
    }));
    const canBeTarget = computed(() => {
      if (!(connectionCreation == null ? void 0 : connectionCreation.connectionState.value.isCreating)) return false;
      return connectionCreation.canBeConnectionTarget.value(props.bar);
    });
    const firstMousemoveCallback = (e) => {
      if (barConfig.value.bundle != null) {
        initDragOfBundle(bar.value, e);
      } else {
        initDragOfBar(bar.value, e);
      }
      isDragging.value = true;
    };
    const prepareForDrag = () => {
      setDragLimitsOfGanttBar(bar.value);
      if (barConfig.value.immobile) {
        return;
      }
      window.addEventListener("mousemove", firstMousemoveCallback, {
        once: true
      });
      window.addEventListener(
        "mouseup",
        () => {
          window.removeEventListener("mousemove", firstMousemoveCallback);
          isDragging.value = false;
        },
        { once: true }
      );
    };
    const onMouseEvent = (e) => {
      var _a;
      e.preventDefault();
      if (e.type === "mousedown") {
        prepareForDrag();
      }
      const barContainer = (_a = barContainerEl == null ? void 0 : barContainerEl.value) == null ? void 0 : _a.getBoundingClientRect();
      if (!barContainer) {
        return;
      }
      const datetime = mapPositionToTime(e.clientX - barContainer.left);
      emitBarEvent(e, bar.value, datetime);
    };
    const barContainerEl = inject(BAR_CONTAINER_KEY);
    const { handleTouchStart, handleTouchMove, handleTouchEnd, handleTouchCancel } = useTouchEvents(
      (_draggedBar, e) => {
        firstMousemoveCallback(e);
        isDragging.value = true;
      }
    );
    const onTouchEvent = (e) => {
      if (bar.value.ganttBarConfig.immobile) return;
      let mouseEvent;
      switch (e.type) {
        case "touchstart":
          mouseEvent = handleTouchStart(e, bar.value);
          break;
        case "touchmove":
          mouseEvent = handleTouchMove(e);
          break;
        case "touchend":
          mouseEvent = handleTouchEnd(e);
          break;
        case "touchcancel":
          mouseEvent = handleTouchCancel(e);
          break;
      }
      if (mouseEvent) {
        onMouseEvent(mouseEvent);
      }
    };
    const isProgressDragging = ref(false);
    const progressDragStart = ref(0);
    const initialProgress = ref(0);
    const handleProgressDragStart = (e) => {
      if (!props.bar.ganttBarConfig.progressResizable && !defaultProgressResizable.value) return;
      e.stopPropagation();
      isProgressDragging.value = true;
      progressDragStart.value = e.clientX;
      initialProgress.value = props.bar.ganttBarConfig.progress ?? 0;
      window.addEventListener("mousemove", handleProgressDrag);
      window.addEventListener("mouseup", handleProgressDragEnd);
      emitBarEvent(
        {
          ...e,
          type: "progress-drag-start"
        },
        props.bar
      );
    };
    const { findBarElement } = useBarSelector();
    const handleProgressDrag = (e) => {
      if (!isProgressDragging.value) return;
      const barElement = findBarElement(ganttId, props.bar.ganttBarConfig.id);
      if (!barElement) return;
      const rect = barElement.getBoundingClientRect();
      const deltaX = e.clientX - progressDragStart.value;
      const percentageDelta = deltaX / rect.width * 100;
      const newProgress = Math.min(Math.max(initialProgress.value + percentageDelta, 0), 100);
      bar.value.ganttBarConfig.progress = Math.round(newProgress);
      emitBarEvent(
        {
          ...e,
          type: "progress-change"
        },
        props.bar
      );
    };
    const handleProgressDragEnd = (e) => {
      if (!isProgressDragging.value) return;
      isProgressDragging.value = false;
      window.removeEventListener("mousemove", handleProgressDrag);
      window.removeEventListener("mouseup", handleProgressDragEnd);
      emitBarEvent(
        {
          ...e,
          type: "progress-drag-end"
        },
        props.bar
      );
    };
    const startPointHover = ref(false);
    const endPointHover = ref(false);
    const isBarHovered = ref(false);
    const handleConnectionPointMouseEnter = (point) => {
      if (!enableConnectionCreation.value) return;
      if (point === "start") {
        startPointHover.value = true;
      } else {
        endPointHover.value = true;
      }
      connectionCreation == null ? void 0 : connectionCreation.handleConnectionPointHover(props.bar.ganttBarConfig.id, point, true);
    };
    const handleConnectionPointMouseLeave = (point) => {
      if (!enableConnectionCreation.value) return;
      if (point === "start") {
        startPointHover.value = false;
      } else {
        endPointHover.value = false;
      }
      connectionCreation == null ? void 0 : connectionCreation.handleConnectionPointHover(props.bar.ganttBarConfig.id, point, false);
    };
    const handleConnectionPointMouseDown = (e, point) => {
      if (!enableConnectionCreation.value) return;
      e.stopPropagation();
      connectionCreation == null ? void 0 : connectionCreation.startConnectionCreation(props.bar, point, e);
    };
    const handleConnectionDrop = (e, point) => {
      if (!enableConnectionCreation.value) return;
      e.stopPropagation();
      connectionCreation == null ? void 0 : connectionCreation.completeConnection(props.bar, point, e);
    };
    const handleBarMouseEnter = (e) => {
      isBarHovered.value = true;
      onMouseEvent(e);
    };
    const handleBarMouseLeave = (e) => {
      isBarHovered.value = false;
      onMouseEvent(e);
    };
    const startEditing = (e) => {
      if (!barLabelEditable.value || isGroupBar.value) return;
      e.stopPropagation();
      bar.value.ganttBarConfig._previousLabel = barConfig.value.label || "";
      isEditing.value = true;
      editedLabel.value = barConfig.value.label || "";
      setTimeout(() => {
        if (labelInput.value) {
          labelInput.value.focus();
          labelInput.value.select();
        }
      }, 0);
    };
    const saveLabel = () => {
      if (!isEditing.value) return;
      bar.value.ganttBarConfig.label = editedLabel.value;
      emitBarEvent(
        {
          type: "label-edit",
          preventDefault: () => {
          },
          stopPropagation: () => {
          }
        },
        bar.value
      );
      isEditing.value = false;
    };
    const cancelEditing = () => {
      isEditing.value = false;
    };
    const handleLabelKeydown = (e) => {
      if (e.key === "Enter") {
        saveLabel();
      } else if (e.key === "Escape") {
        cancelEditing();
      }
    };
    const handleInputBlur = () => {
      saveLabel();
    };
    const getDarkerColor = (color) => {
      const rgb = color.startsWith("#") ? hexToRgb(color) : parseRgb(color);
      return `rgba(${Math.max(0, rgb.r - 40)}, ${Math.max(0, rgb.g - 40)}, ${Math.max(0, rgb.b - 40)}, ${rgb.a})`;
    };
    const hexToRgb = (hex) => {
      const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
      return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16),
        a: 1
      } : { r: 0, g: 0, b: 0, a: 1 };
    };
    const parseRgb = (color) => {
      const matches = color.match(/(\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?/);
      if (matches) {
        return {
          r: parseInt(matches[1]),
          g: parseInt(matches[2]),
          b: parseInt(matches[3]),
          a: matches[4] ? parseFloat(matches[4]) : 1
        };
      }
      return { r: 0, g: 0, b: 0, a: 1 };
    };
    const getGroupBarPath = (width2, height) => {
      const mainBarHeight = height * 0.5;
      return `
    M 0 0
    L 0 ${height}
    L ${15} ${mainBarHeight}
    L ${width2 - 15} ${mainBarHeight}
    L ${width2} ${height}
    L ${width2} 0
    L 0 0
  `;
    };
    const { onBarKeyDown } = useBarKeyboardControl(bar.value, config, emitBarEvent);
    onMounted(() => {
      xStart.value = mapTimeToPosition(bar.value[barStart.value]);
      xEnd.value = mapTimeToPosition(bar.value[barEnd.value]);
      watch(
        [() => bar.value, width, chartStart, chartEnd, chartSize.width],
        () => {
          const newXStart = mapTimeToPosition(bar.value[barStart.value]);
          const newXEnd = mapTimeToPosition(bar.value[barEnd.value]);
          xStart.value = newXStart;
          xEnd.value = newXEnd;
        },
        { deep: true, immediate: true }
      );
    });
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", {
        id: barConfig.value.id,
        class: normalizeClass(["g-gantt-bar", barConfig.value.class || ""]),
        style: normalizeStyle({
          ...barConfig.value.style,
          position: "absolute",
          top: `${unref(rowHeight) * 0.15}px`,
          left: `${xStart.value}px`,
          width: `${xEnd.value - xStart.value}px`,
          height: `${unref(rowHeight) * 0.7}px`,
          zIndex: isDragging.value ? 3 : 2,
          cursor: unref(bar).ganttBarConfig.immobile ? "" : "grab"
        }),
        onMousedown: onMouseEvent,
        onClick: onMouseEvent,
        onMouseenter: handleBarMouseEnter,
        onMouseleave: handleBarMouseLeave,
        onContextmenu: onMouseEvent,
        onTouchstart: onTouchEvent,
        onTouchmove: onTouchEvent,
        onTouchend: onTouchEvent,
        onTouchcancel: onTouchEvent,
        onKeydown: _cache[9] || (_cache[9] = //@ts-ignore
        (...args) => unref(onBarKeyDown) && unref(onBarKeyDown)(...args)),
        onDblclick: startEditing,
        role: "listitem",
        "aria-label": `Activity ${barConfig.value.label}`,
        "aria-grabbed": isDragging.value,
        tabindex: "0",
        "aria-describedby": `tooltip-${barConfig.value.id}`
      }, [
        unref(enableConnectionCreation) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
          createElementVNode("div", {
            class: "connection-point start",
            style: normalizeStyle([startPointStyle.value, { position: "absolute" }]),
            onMouseenter: _cache[0] || (_cache[0] = ($event) => handleConnectionPointMouseEnter("start")),
            onMouseleave: _cache[1] || (_cache[1] = ($event) => handleConnectionPointMouseLeave("start")),
            onMousedown: _cache[2] || (_cache[2] = ($event) => handleConnectionPointMouseDown($event, "start")),
            onMouseup: _cache[3] || (_cache[3] = ($event) => handleConnectionDrop($event, "start"))
          }, null, 36),
          createElementVNode("div", {
            class: "connection-point end",
            style: normalizeStyle([endPointStyle.value, { position: "absolute" }]),
            onMouseenter: _cache[4] || (_cache[4] = ($event) => handleConnectionPointMouseEnter("end")),
            onMouseleave: _cache[5] || (_cache[5] = ($event) => handleConnectionPointMouseLeave("end")),
            onMousedown: _cache[6] || (_cache[6] = ($event) => handleConnectionPointMouseDown($event, "end")),
            onMouseup: _cache[7] || (_cache[7] = ($event) => handleConnectionDrop($event, "end"))
          }, null, 36)
        ], 64)) : createCommentVNode("", true),
        barConfig.value.progress !== void 0 ? (openBlock(), createElementBlock("div", {
          key: 1,
          class: "g-gantt-progress-bar",
          style: normalizeStyle(progressStyle.value)
        }, [
          unref(showProgress) ? (openBlock(), createElementBlock("span", _hoisted_2$1, toDisplayString(Math.round(barConfig.value.progress)) + "%", 1)) : createCommentVNode("", true),
          barConfig.value.progressResizable || unref(defaultProgressResizable) ? (openBlock(), createElementBlock("div", {
            key: 1,
            class: "g-gantt-progress-handle",
            style: normalizeStyle({ right: unref(bar).ganttBarConfig.progress === 0 ? 0 : "-4px" }),
            onMousedown: handleProgressDragStart
          }, null, 36)) : createCommentVNode("", true)
        ], 4)) : createCommentVNode("", true),
        isGroupBar.value ? (openBlock(), createElementBlock("svg", {
          key: 2,
          class: "group-bar-decoration",
          width: xEnd.value - xStart.value,
          height: unref(rowHeight) * 0.7
        }, [
          createElementVNode("path", {
            d: getGroupBarPath(xEnd.value - xStart.value, unref(rowHeight) * 0.65),
            fill: unref(config).colors.value.barContainer
          }, null, 8, _hoisted_4$1)
        ], 8, _hoisted_3$1)) : createCommentVNode("", true),
        createElementVNode("div", _hoisted_5$1, [
          renderSlot(_ctx.$slots, "default", { bar: unref(bar) }, () => [
            !isGroupBar.value && unref(showLabel) ? (openBlock(), createElementBlock("div", _hoisted_6$1, [
              isEditing.value && unref(barLabelEditable) ? (openBlock(), createElementBlock("div", _hoisted_7$1, [
                withDirectives(createElementVNode("input", {
                  ref_key: "labelInput",
                  ref: labelInput,
                  "onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => editedLabel.value = $event),
                  onKeydown: handleLabelKeydown,
                  onBlur: handleInputBlur,
                  class: "g-gantt-bar-label-input"
                }, null, 544), [
                  [vModelText, editedLabel.value]
                ])
              ])) : (openBlock(), createElementBlock("div", _hoisted_8$1, toDisplayString(barConfig.value.label || ""), 1))
            ])) : createCommentVNode("", true),
            barConfig.value.html ? (openBlock(), createElementBlock("div", {
              key: 1,
              innerHTML: barConfig.value.html
            }, null, 8, _hoisted_9$1)) : createCommentVNode("", true)
          ])
        ]),
        barConfig.value.hasHandles ? (openBlock(), createElementBlock(Fragment, { key: 3 }, [
          _cache[10] || (_cache[10] = createElementVNode("div", { class: "g-gantt-bar-handle-left" }, null, -1)),
          _cache[11] || (_cache[11] = createElementVNode("div", { class: "g-gantt-bar-handle-right" }, null, -1))
        ], 64)) : createCommentVNode("", true)
      ], 46, _hoisted_1$3);
    };
  }
});
const _hoisted_1$2 = {
  key: 0,
  class: "g-gantt-row-children"
};
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
  __name: "GGanttRow",
  props: {
    label: {},
    bars: {},
    highlightOnHover: { type: Boolean },
    id: {},
    children: {},
    connections: {}
  },
  emits: ["drop"],
  setup(__props, { emit: __emit }) {
    const props = __props;
    const emit = __emit;
    const rowManager = inject("useRows");
    const { rowHeight, colors, labelColumnTitle, rowClass } = provideConfig();
    const { highlightOnHover } = toRefs(props);
    const barContainer = ref(null);
    const isHovering = ref(false);
    const isGroup = computed(() => {
      var _a;
      return Boolean((_a = props.children) == null ? void 0 : _a.length);
    });
    const isExpanded = computed(() => {
      if (!isGroup.value || !props.id) return false;
      return rowManager.isGroupExpanded(props.id);
    });
    const rowStyle = computed(() => {
      const baseStyle = {
        height: `${rowHeight.value}px`,
        borderBottom: `1px solid ${colors.value.gridAndBorder}`,
        background: (highlightOnHover == null ? void 0 : highlightOnHover.value) && isHovering.value ? colors.value.hoverHighlight : void 0
      };
      if (isGroup.value) {
        return {
          ...baseStyle,
          background: (highlightOnHover == null ? void 0 : highlightOnHover.value) && isHovering.value ? colors.value.hoverHighlight : void 0
        };
      }
      return baseStyle;
    });
    const rowClasses = computed(() => {
      const classes = ["g-gantt-row"];
      if (rowClass.value && props) {
        classes.push(rowClass.value(props));
      }
      if (isGroup.value) {
        classes.push("g-gantt-row-group");
      }
      return classes;
    });
    const visibleChildRows = computed(() => {
      if (!isGroup.value || !isExpanded.value) return [];
      return props.children || [];
    });
    const { mapPositionToTime } = useTimePositionMapping();
    const isBlank = (str) => {
      return !str || /^\s*$/.test(str);
    };
    const onDrop = (e) => {
      var _a;
      if (isGroup.value) return;
      const container = (_a = barContainer.value) == null ? void 0 : _a.getBoundingClientRect();
      if (!container) {
        console.error("Hyper Vue Gantt: failed to find bar container element for row.");
        return;
      }
      const xPos = e.clientX - container.left;
      const datetime = mapPositionToTime(xPos);
      emit("drop", { e, datetime });
    };
    const handleGroupToggle = (event) => {
      event.stopPropagation();
      if (props.id) {
        rowManager.toggleGroupExpansion(props.id);
      }
    };
    provide(BAR_CONTAINER_KEY, barContainer);
    return (_ctx, _cache) => {
      const _component_g_gantt_row = resolveComponent("g-gantt-row", true);
      return openBlock(), createElementBlock(Fragment, null, [
        createElementVNode("div", {
          class: normalizeClass(rowClasses.value),
          style: normalizeStyle(rowStyle.value),
          onDragover: _cache[2] || (_cache[2] = withModifiers(($event) => isHovering.value = true, ["prevent"])),
          onDragleave: _cache[3] || (_cache[3] = ($event) => isHovering.value = false),
          onDrop: _cache[4] || (_cache[4] = ($event) => onDrop($event)),
          onMouseover: _cache[5] || (_cache[5] = ($event) => isHovering.value = true),
          onMouseleave: _cache[6] || (_cache[6] = ($event) => isHovering.value = false),
          role: "list"
        }, [
          !isBlank(_ctx.label) && !unref(labelColumnTitle) ? (openBlock(), createElementBlock("div", {
            key: 0,
            class: normalizeClass(["g-gantt-row-label", { "g-gantt-row-group-label": isGroup.value }]),
            style: normalizeStyle({ background: unref(colors).primary, color: unref(colors).text }),
            onClick: _cache[1] || (_cache[1] = ($event) => isGroup.value ? handleGroupToggle($event) : void 0)
          }, [
            isGroup.value ? (openBlock(), createElementBlock("button", {
              key: 0,
              class: "group-toggle-button",
              onClick: _cache[0] || (_cache[0] = ($event) => handleGroupToggle($event))
            }, [
              createVNode(unref(FontAwesomeIcon), {
                icon: isExpanded.value ? unref(faChevronDown) : unref(faChevronRight),
                class: "group-icon"
              }, null, 8, ["icon"])
            ])) : createCommentVNode("", true),
            renderSlot(_ctx.$slots, "label", {}, () => [
              createTextVNode(toDisplayString(_ctx.label), 1)
            ])
          ], 6)) : createCommentVNode("", true),
          createElementVNode("div", mergeProps({
            ref_key: "barContainer",
            ref: barContainer,
            class: "g-gantt-row-bars-container"
          }, _ctx.$attrs), [
            createVNode(TransitionGroup, {
              name: "bar-transition",
              tag: "div"
            }, {
              default: withCtx(() => [
                (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.bars, (bar) => {
                  return openBlock(), createBlock(_sfc_main$3, {
                    key: bar.ganttBarConfig.id,
                    bar,
                    class: normalizeClass({ "g-gantt-group-bar": isGroup.value })
                  }, {
                    default: withCtx(() => [
                      !isGroup.value ? renderSlot(_ctx.$slots, "bar-label", {
                        key: 0,
                        bar
                      }) : createCommentVNode("", true)
                    ]),
                    _: 2
                  }, 1032, ["bar", "class"]);
                }), 128))
              ]),
              _: 3
            })
          ], 16)
        ], 38),
        isGroup.value && isExpanded.value ? (openBlock(), createElementBlock("div", _hoisted_1$2, [
          (openBlock(true), createElementBlock(Fragment, null, renderList(visibleChildRows.value, (child) => {
            return openBlock(), createBlock(_component_g_gantt_row, mergeProps({
              key: child.id || child.label,
              ref_for: true
            }, child, { highlightOnHover: unref(highlightOnHover) }), createSlots({ _: 2 }, [
              renderList(_ctx.$slots, (_, name) => {
                return {
                  name,
                  fn: withCtx((slotProps) => [
                    renderSlot(_ctx.$slots, name, mergeProps({ ref_for: true }, slotProps))
                  ])
                };
              })
            ]), 1040, ["highlightOnHover"]);
          }), 128))
        ])) : createCommentVNode("", true)
      ], 64);
    };
  }
});
const _hoisted_1$1 = { style: { "font-weight": "bold" } };
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
  __name: "GGanttPointerMarker",
  setup(__props) {
    const chartAreaEl = inject(CHART_AREA_KEY);
    const chartWrapperEl = inject(CHART_WRAPPER_KEY);
    const hitBars = ref([]);
    const tooltipContainer = useTemplateRef("tooltip");
    const { colors, barStart, barEnd } = provideConfig();
    const { mapPositionToTime } = useTimePositionMapping();
    const rowManager = inject("useRows");
    const { toDayjs } = useDayjsHelper();
    const { elementX } = useMouseInElement(chartAreaEl);
    const { isOutside, x } = useMouseInElement(chartWrapperEl);
    const { width, height } = useElementBounding(tooltipContainer);
    const { top, bottom } = useElementBounding(chartWrapperEl);
    const leftOffset = computed((prev) => isOutside.value ? prev ?? 0 : elementX.value);
    const datetime = computed(() => mapPositionToTime(leftOffset.value));
    const bars = computedWithControl(rowManager.getFlattenedRows, () => rowManager.getFlattenedRows().flatMap((row) => row.bars));
    const tooltipStylePosition = computed(() => {
      if (top.value - height.value > 0) {
        return {
          top: `${top.value}px`,
          transform: `translateY(-100%)`,
          left: `${x.value - width.value / 2}px`
        };
      }
      return {
        top: `${bottom.value}px`,
        left: `${x.value - width.value / 2}px`
      };
    });
    watchThrottled(leftOffset, () => {
      const hitBarsElement = [];
      const cursorTime = toDayjs(datetime.value);
      for (let i = 0; i < bars.value.length; i++) {
        const element = bars.value[i];
        const begin = toDayjs(element[barStart.value]);
        const end = toDayjs(element[barEnd.value]);
        if (cursorTime.isBetween(begin, end)) {
          hitBarsElement.push(element);
        }
      }
      hitBars.value = hitBarsElement;
    }, { throttle: 200 });
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", {
        class: "g-grid-pointer-marker-container",
        style: normalizeStyle({
          left: `${leftOffset.value}px`
        })
      }, [
        createElementVNode("div", {
          class: "g-grid-pointer-marker-marker",
          style: normalizeStyle({
            border: `1px dashed ${unref(colors).markerCurrentTime}`
          })
        }, null, 4),
        (openBlock(), createBlock(Teleport, { to: "body" }, [
          createVNode(Transition, {
            name: "g-fade",
            mode: "out-in"
          }, {
            default: withCtx(() => [
              !unref(isOutside) ? (openBlock(), createElementBlock("div", {
                key: 0,
                ref: "tooltip",
                class: "g-grid-pointer-marker-tooltip",
                style: normalizeStyle(tooltipStylePosition.value)
              }, [
                renderSlot(_ctx.$slots, "pointer-marker-tooltips", normalizeProps(guardReactiveProps({ hitBars: hitBars.value, datetime: datetime.value })), () => [
                  createElementVNode("div", {
                    class: "g-grid-pointer-marker-tooltip-content",
                    style: normalizeStyle({ background: unref(colors).primary, color: unref(colors).text })
                  }, [
                    createElementVNode("div", _hoisted_1$1, "Event at " + toDisplayString(datetime.value), 1),
                    createElementVNode("ul", null, [
                      (openBlock(true), createElementBlock(Fragment, null, renderList(hitBars.value, (bar) => {
                        return openBlock(), createElementBlock("li", {
                          key: bar.ganttBarConfig.id
                        }, toDisplayString(bar.ganttBarConfig.label ?? bar.ganttBarConfig.id), 1);
                      }), 128))
                    ])
                  ], 4)
                ])
              ], 4)) : createCommentVNode("", true)
            ]),
            _: 3
          })
        ]))
      ], 4);
    };
  }
});
function useConnections(rowManager, props, id, emit) {
  const connections = ref([]);
  const barPositions = ref(/* @__PURE__ */ new Map());
  const selectedConnection = ref(null);
  const getConnectorProps = computed(() => (conn) => {
    var _a, _b;
    const sourceBar = barPositions.value.get(conn.sourceId);
    const targetBar = barPositions.value.get(conn.targetId);
    if (!sourceBar || !targetBar) {
      return null;
    }
    const connectionProps = {
      type: conn.type ?? props.defaultConnectionType,
      color: conn.color ?? props.defaultConnectionColor,
      pattern: conn.pattern ?? props.defaultConnectionPattern,
      animated: conn.animated ?? props.defaultConnectionAnimated,
      animationSpeed: conn.animationSpeed ?? props.defaultConnectionAnimationSpeed,
      isSelected: ((_a = selectedConnection.value) == null ? void 0 : _a.sourceId) === conn.sourceId && ((_b = selectedConnection.value) == null ? void 0 : _b.targetId) === conn.targetId
    };
    return {
      sourceBar,
      targetBar,
      ...connectionProps
    };
  });
  const handleConnectionClick = (connection) => {
    var _a, _b;
    if (((_a = selectedConnection.value) == null ? void 0 : _a.sourceId) === connection.sourceId && ((_b = selectedConnection.value) == null ? void 0 : _b.targetId) === connection.targetId) {
      selectedConnection.value = null;
    } else {
      selectedConnection.value = connection;
    }
  };
  const deleteSelectedConnection = () => {
    if (!selectedConnection.value) return;
    const allBars = getAllBars(rowManager.rows.value);
    const sourceBar = allBars.find(
      (bar) => {
        var _a;
        return bar.ganttBarConfig.id === ((_a = selectedConnection.value) == null ? void 0 : _a.sourceId);
      }
    );
    if (sourceBar && sourceBar.ganttBarConfig.connections) {
      sourceBar.ganttBarConfig.connections = sourceBar.ganttBarConfig.connections.filter(
        (conn) => {
          var _a;
          return conn.targetId !== ((_a = selectedConnection.value) == null ? void 0 : _a.targetId);
        }
      );
      const targetBar = allBars.find(
        (bar) => {
          var _a;
          return bar.ganttBarConfig.id === ((_a = selectedConnection.value) == null ? void 0 : _a.targetId);
        }
      );
      emit("connection-delete", {
        sourceBar,
        targetBar,
        e: new MouseEvent("mouseup")
      });
      selectedConnection.value = null;
      initializeConnections();
      rowManager.onBarMove();
    }
  };
  const getAllBars = (rows) => {
    return rows.flatMap((row) => {
      var _a;
      const bars = [...row.bars];
      if ((_a = row.children) == null ? void 0 : _a.length) {
        return [...bars, ...getAllBars(row.children)];
      }
      return bars;
    });
  };
  const initializeConnections = () => {
    connections.value = [];
    const allBars = getAllBars(rowManager.rows.value);
    allBars.forEach((el) => {
      var _a;
      if ((_a = el.ganttBarConfig.connections) == null ? void 0 : _a.length) {
        el.ganttBarConfig.connections.forEach((conn) => {
          connections.value.push({
            sourceId: el.ganttBarConfig.id,
            targetId: conn.targetId,
            type: conn.type,
            color: conn.color,
            pattern: conn.pattern,
            animated: conn.animated,
            animationSpeed: conn.animationSpeed
          });
        });
      }
    });
  };
  watch(
    () => rowManager.rows.value,
    () => {
      initializeConnections();
    },
    { deep: true }
  );
  const updateBarPositions = async () => {
    await new Promise((resolve) => requestAnimationFrame(resolve));
    const parentElement = document.getElementById(id.value);
    const rowsContainer = parentElement.querySelector(".g-gantt-rows-container");
    if (!rowsContainer) return;
    const scrollTop = rowsContainer.scrollTop;
    const scrollLeft = rowsContainer.scrollLeft;
    const containerRect = rowsContainer.getBoundingClientRect();
    const bars = parentElement.querySelectorAll(".g-gantt-bar");
    barPositions.value.clear();
    bars.forEach((bar) => {
      const rect = bar.getBoundingClientRect();
      const barId = bar.getAttribute("id");
      if (barId) {
        const position = {
          id: barId,
          x: rect.left - containerRect.left + scrollLeft,
          y: rect.top - containerRect.top + scrollTop,
          width: rect.width,
          height: rect.height
        };
        barPositions.value.set(barId, position);
      }
    });
  };
  return {
    connections,
    barPositions,
    getConnectorProps,
    initializeConnections,
    updateBarPositions,
    handleConnectionClick,
    selectedConnection,
    deleteSelectedConnection
  };
}
function useTooltip() {
  const showTooltip = ref(false);
  const tooltipBar = ref(void 0);
  let tooltipTimeoutId;
  const initTooltip = (bar) => {
    if (tooltipTimeoutId) {
      clearTimeout(tooltipTimeoutId);
    }
    tooltipTimeoutId = setTimeout(() => {
      showTooltip.value = true;
    }, 800);
    tooltipBar.value = bar;
  };
  const clearTooltip = () => {
    clearTimeout(tooltipTimeoutId);
    showTooltip.value = false;
  };
  return {
    showTooltip,
    tooltipBar,
    initTooltip,
    clearTooltip
  };
}
function useChartNavigation(options, maxRows) {
  const { scrollRefs, updateBarPositions, timeaxisUnits } = options;
  const { adjustZoomAndPrecision } = timeaxisUnits;
  const scrollPosition = ref(0);
  const isAtTop = ref(true);
  const isAtBottom = ref(false);
  const totalWidth = computed(() => {
    return timeaxisUnits.timeaxisUnits.value.result.lowerUnits.reduce((total, unit) => {
      return total + parseInt(unit.width);
    }, 0);
  });
  const handleStep = (newPosition, wrapper) => {
    const maxScroll = totalWidth.value - wrapper.clientWidth;
    const targetScroll = maxScroll * newPosition / 100;
    wrapper.scrollLeft = targetScroll;
    scrollPosition.value = newPosition;
  };
  const handleScroll = (wrapper) => {
    const maxScroll = totalWidth.value - wrapper.clientWidth;
    const targetScroll = maxScroll * scrollPosition.value / 100;
    wrapper.scrollLeft = targetScroll;
  };
  const handleWheel = (e, wrapper) => {
    if (maxRows !== 0) {
      if (e.deltaX !== 0) {
        e.preventDefault();
      }
      return;
    }
    wrapper.scrollLeft += e.deltaX || e.deltaY;
    const maxScroll = totalWidth.value - wrapper.clientWidth;
    scrollPosition.value = wrapper.scrollLeft / maxScroll * 100;
  };
  const handleZoomUpdate = async (increase) => {
    adjustZoomAndPrecision(increase);
    await nextTick();
    updateBarPositions();
  };
  const handleContentScroll = (e) => {
    const target = e.target;
    if (scrollRefs.labelColumn.value) {
      scrollRefs.labelColumn.value.setScroll(target.scrollTop);
    }
    updateVerticalScrollState();
  };
  const handleLabelScroll = (scrollTop) => {
    if (scrollRefs.rowsContainer.value) {
      scrollRefs.rowsContainer.value.scrollTop = scrollTop;
      updateVerticalScrollState();
    }
  };
  const updateVerticalScrollState = () => {
    if (!scrollRefs.rowsContainer.value) return;
    const { scrollTop, scrollHeight, clientHeight } = scrollRefs.rowsContainer.value;
    isAtTop.value = scrollTop === 0;
    isAtBottom.value = Math.ceil(scrollTop + clientHeight) >= scrollHeight;
  };
  const scrollRowUp = () => {
    var _a;
    if (!scrollRefs.rowsContainer.value) return;
    const currentScroll = scrollRefs.rowsContainer.value.scrollTop;
    const rowHeight = ((_a = scrollRefs.rowsContainer.value.firstElementChild) == null ? void 0 : _a.clientHeight) || 0;
    scrollRefs.rowsContainer.value.scrollTop = Math.max(0, currentScroll - rowHeight);
    handleContentScroll(createScrollEvent(scrollRefs.rowsContainer.value));
  };
  const scrollRowDown = () => {
    var _a;
    if (!scrollRefs.rowsContainer.value) return;
    const currentScroll = scrollRefs.rowsContainer.value.scrollTop;
    const rowHeight = ((_a = scrollRefs.rowsContainer.value.firstElementChild) == null ? void 0 : _a.clientHeight) || 0;
    const maxScroll = scrollRefs.rowsContainer.value.scrollHeight - scrollRefs.rowsContainer.value.clientHeight;
    scrollRefs.rowsContainer.value.scrollTop = Math.min(maxScroll, currentScroll + rowHeight);
    handleContentScroll(createScrollEvent(scrollRefs.rowsContainer.value));
  };
  const createScrollEvent = (target) => {
    const event = new Event("scroll", {
      bubbles: true,
      cancelable: true
    });
    Object.defineProperty(event, "target", {
      value: target,
      enumerable: true
    });
    return event;
  };
  return {
    scrollPosition,
    isAtTop,
    isAtBottom,
    handleStep,
    handleScroll,
    handleWheel,
    handleContentScroll,
    handleLabelScroll,
    handleZoomUpdate,
    scrollRowUp,
    scrollRowDown
  };
}
function useKeyboardNavigation(chartNavigation, wrapperRef, ganttContainerRef, connectionControls, enableConnectionDeletion) {
  const { handleStep, handleZoomUpdate, scrollPosition } = chartNavigation;
  const { selectedConnection, deleteSelectedConnection } = connectionControls;
  const handleKeyDown = (event) => {
    const target = event.target;
    if (!ganttContainerRef.value || target !== ganttContainerRef.value) {
      return;
    }
    if (selectedConnection.value && enableConnectionDeletion.value) {
      switch (event.key) {
        case "Delete":
          deleteSelectedConnection();
          return;
        case "Escape":
          selectedConnection.value = null;
          return;
      }
    }
    switch (event.key) {
      case "ArrowLeft":
        if (wrapperRef.value && scrollPosition.value > 0) {
          handleStep(Math.max(0, scrollPosition.value - 10), wrapperRef.value);
        }
        break;
      case "ArrowRight":
        if (wrapperRef.value && scrollPosition.value < 100) {
          handleStep(Math.min(100, scrollPosition.value + 10), wrapperRef.value);
        }
        break;
      case "+":
        handleZoomUpdate(true);
        break;
      case "-":
        handleZoomUpdate(false);
        break;
      case "Home":
        if (wrapperRef.value) {
          handleStep(0, wrapperRef.value);
        }
        break;
      case "End":
        if (wrapperRef.value) {
          handleStep(100, wrapperRef.value);
        }
        break;
      case "PageUp":
        if (wrapperRef.value && scrollPosition.value >= 10) {
          handleStep(scrollPosition.value - 10, wrapperRef.value);
        } else if (wrapperRef.value) {
          handleStep(0, wrapperRef.value);
        }
        break;
      case "PageDown":
        if (wrapperRef.value && scrollPosition.value <= 90) {
          handleStep(scrollPosition.value + 10, wrapperRef.value);
        } else if (wrapperRef.value) {
          handleStep(100, wrapperRef.value);
        }
        break;
    }
  };
  return {
    handleKeyDown
  };
}
function createHistoryState(rows, expandedGroups, customOrder) {
  const prepareRowForCloning = (row) => {
    var _a, _b;
    const cleanRow = {
      id: row.id,
      label: row.label,
      bars: ((_a = row.bars) == null ? void 0 : _a.map((bar) => ({
        ...bar,
        ganttBarConfig: {
          id: bar.ganttBarConfig.id,
          label: bar.ganttBarConfig.label,
          html: bar.ganttBarConfig.html,
          hasHandles: bar.ganttBarConfig.hasHandles,
          immobile: bar.ganttBarConfig.immobile,
          bundle: bar.ganttBarConfig.bundle,
          pushOnOverlap: bar.ganttBarConfig.pushOnOverlap,
          pushOnConnect: bar.ganttBarConfig.pushOnConnect,
          style: bar.ganttBarConfig.style,
          class: bar.ganttBarConfig.class,
          connections: bar.ganttBarConfig.connections,
          milestoneId: bar.ganttBarConfig.milestoneId,
          progress: bar.ganttBarConfig.progress,
          progressStyle: bar.ganttBarConfig.progressStyle,
          progressResizable: bar.ganttBarConfig.progressResizable
        }
      }))) || [],
      connections: row.connections,
      children: (_b = row.children) == null ? void 0 : _b.map(prepareRowForCloning)
    };
    return cleanRow;
  };
  const preparedRows = rows.map(prepareRowForCloning);
  return {
    rows: cloneDeep(preparedRows),
    expandedGroups: new Set(expandedGroups),
    customOrder: new Map(customOrder),
    timestamp: Date.now()
  };
}
function restoreState(state, originalRows) {
  const restoreRow = (historyRow, originalRow) => {
    const restored = cloneDeep(historyRow);
    if (originalRow) {
      restored._originalNode = originalRow._originalNode;
    }
    if (restored.children && (originalRow == null ? void 0 : originalRow.children)) {
      restored.children = restored.children.map(
        (child, index) => restoreRow(child, originalRow.children[index])
      );
    }
    return restored;
  };
  return {
    rows: state.rows.map((historyRow) => {
      const originalRow = originalRows.find((r) => r.id === historyRow.id);
      return restoreRow(historyRow, originalRow);
    }),
    expandedGroups: new Set(state.expandedGroups),
    customOrder: new Map(state.customOrder)
  };
}
function findParentId(rows, path) {
  if (path.length <= 1) return void 0;
  let current = rows[path[0]];
  for (let i = 1; i < path.length - 1; i++) {
    if (!(current == null ? void 0 : current.children)) return void 0;
    current = current.children[path[i]];
  }
  return current == null ? void 0 : current.id;
}
function findBarInRows(rows, barId) {
  for (const row of rows) {
    const found = row.bars.find((bar) => bar.ganttBarConfig.id === barId);
    if (found) return found;
    if (row.children) {
      const foundInChildren = findBarInRows(row.children, barId);
      if (foundInChildren) return foundInChildren;
    }
  }
  return null;
}
function findRowById(rows, id) {
  for (const row of rows) {
    if (row.id === id) return row;
    if (row.children) {
      const found = findRowById(row.children, id);
      if (found) return found;
    }
  }
  return null;
}
function findRowPath(rows, id) {
  for (let i = 0; i < rows.length; i++) {
    if (rows[i].id === id) return [i];
    if (rows[i].children) {
      const childPath = findRowPath(rows[i].children, id);
      if (childPath.length) return [i, ...childPath];
    }
  }
  return [];
}
function findRowIdForBar(barId, rows) {
  function searchInRows(rows2) {
    for (const row of rows2) {
      if (row.bars.some((bar) => bar.ganttBarConfig.id === barId)) {
        return row.id;
      }
      if (row.children) {
        const foundId = searchInRows(row.children);
        if (foundId) return foundId;
      }
    }
    return null;
  }
  return searchInRows(rows) || "";
}
function getAllBarsFromState(state) {
  const barsMap = /* @__PURE__ */ new Map();
  function collectBars(rows) {
    rows.forEach((row) => {
      row.bars.forEach((bar) => {
        barsMap.set(bar.ganttBarConfig.id, bar);
      });
      if (row.children) {
        collectBars(row.children);
      }
    });
  }
  collectBars(state.rows);
  return barsMap;
}
function compareBarStates(oldBar, newBar, barStart, barEnd, rows) {
  if (oldBar[barStart.value] === newBar[barStart.value] && oldBar[barEnd.value] === newBar[barEnd.value]) {
    return null;
  }
  return {
    barId: oldBar.ganttBarConfig.id,
    rowId: findRowIdForBar(oldBar.ganttBarConfig.id, rows.value),
    oldStart: oldBar[barStart.value],
    newStart: newBar[barStart.value],
    oldEnd: oldBar[barEnd.value],
    newEnd: newBar[barEnd.value]
  };
}
function compareAllBars(oldState, newState, barStart, barEnd, rows) {
  const changes = [];
  const oldBars = getAllBarsFromState(oldState);
  const newBars = getAllBarsFromState(newState);
  oldBars.forEach((oldBar, barId) => {
    const newBar = newBars.get(barId);
    if (newBar) {
      const change = compareBarStates(oldBar, newBar, barStart, barEnd, rows);
      if (change) {
        changes.push(change);
      }
    }
  });
  return changes;
}
function calculateHistoryChanges(prevState, newState, barStart, barEnd, rows) {
  const rowChanges = [];
  function compareRows(oldRows) {
    for (const oldRow of oldRows) {
      if (!oldRow.id) continue;
      const oldPath = findRowPath(prevState.rows, oldRow.id);
      const newPath = findRowPath(newState.rows, oldRow.id);
      if (oldPath.length !== newPath.length || !oldPath.every((v, i) => v === newPath[i])) {
        const oldParentId = oldPath.length > 1 ? findParentId(prevState.rows, oldPath) : void 0;
        const newParentId = newPath.length > 1 ? findParentId(newState.rows, newPath) : void 0;
        rowChanges.push({
          type: oldParentId !== newParentId ? "group" : "reorder",
          sourceRow: oldRow,
          oldIndex: oldPath[oldPath.length - 1],
          newIndex: newPath[newPath.length - 1],
          oldParentId,
          newParentId
        });
      }
      if (oldRow.children) {
        const newRow = findRowById(newState.rows, oldRow.id);
        if (newRow == null ? void 0 : newRow.children) {
          compareRows(oldRow.children);
        }
      }
    }
  }
  compareRows(prevState.rows);
  const barChanges = compareAllBars(prevState, newState, barStart, barEnd, rows);
  return {
    rowChanges,
    barChanges
  };
}
const MAX_HISTORY_STATES = 50;
function useRows(slots, {
  barStart,
  barEnd,
  dateFormat,
  multiColumnLabel,
  onSort,
  initialSort,
  onGroupExpansion
}, initialRows) {
  const sortState = ref({
    column: initialSort.column,
    direction: initialSort.direction
  });
  const sortChangeCallbacks = ref(/* @__PURE__ */ new Set());
  const expandedGroups = ref(/* @__PURE__ */ new Set());
  const groupExpansionCallbacks = ref(/* @__PURE__ */ new Set());
  const customOrder = ref(/* @__PURE__ */ new Map());
  const reorderedRows = ref([]);
  const historyStates = ref([]);
  const currentHistoryIndex = ref(-1);
  const initializeHistory = () => {
    historyStates.value = [
      createHistoryState(reorderedRows.value, expandedGroups.value, customOrder.value)
    ];
    currentHistoryIndex.value = 0;
  };
  onMounted(() => {
    initializeHistory();
  });
  const canUndo = computed(() => currentHistoryIndex.value > 0 && historyStates.value.length > 1);
  const canRedo = computed(
    () => historyStates.value.length > 1 && currentHistoryIndex.value < historyStates.value.length - 1
  );
  const addHistoryState = () => {
    if (currentHistoryIndex.value < historyStates.value.length - 1) {
      historyStates.value = historyStates.value.slice(0, currentHistoryIndex.value + 1);
    }
    historyStates.value.push(
      createHistoryState(reorderedRows.value, expandedGroups.value, customOrder.value)
    );
    currentHistoryIndex.value++;
    if (historyStates.value.length > MAX_HISTORY_STATES) {
      const excess = historyStates.value.length - MAX_HISTORY_STATES;
      historyStates.value = historyStates.value.slice(excess);
      currentHistoryIndex.value = Math.max(0, currentHistoryIndex.value - excess);
    }
  };
  const undo = () => {
    const currentState = historyStates.value[currentHistoryIndex.value];
    currentHistoryIndex.value--;
    const previousState = historyStates.value[currentHistoryIndex.value];
    const changes = calculateHistoryChanges(currentState, previousState, barStart, barEnd, rows);
    const restored = restoreState(previousState, reorderedRows.value);
    reorderedRows.value = restored.rows;
    customOrder.value = restored.customOrder;
    return changes;
  };
  const redo = () => {
    const currentState = historyStates.value[currentHistoryIndex.value];
    currentHistoryIndex.value++;
    const nextState = historyStates.value[currentHistoryIndex.value];
    const changes = calculateHistoryChanges(currentState, nextState, barStart, barEnd, rows);
    const restored = restoreState(nextState, reorderedRows.value);
    reorderedRows.value = restored.rows;
    customOrder.value = restored.customOrder;
    return changes;
  };
  const onBarMove = () => {
    addHistoryState();
  };
  const clearHistory = () => {
    initializeHistory();
  };
  const extractRowsFromSlots = () => {
    var _a;
    const defaultSlot = (_a = slots.default) == null ? void 0 : _a.call(slots);
    const rows2 = [];
    if (!defaultSlot) return rows2;
    defaultSlot.forEach((child) => {
      var _a2, _b;
      if (((_a2 = child.props) == null ? void 0 : _a2.bars) || ((_b = child.props) == null ? void 0 : _b.children)) {
        const { label, bars = [], children = [], id, connections = [] } = child.props;
        rows2.push({
          id,
          label,
          bars,
          children,
          connections,
          _originalNode: child
        });
      } else if (Array.isArray(child.children)) {
        child.children.forEach((grandchild) => {
          var _a3, _b2;
          const grandchildNode = grandchild;
          if (((_a3 = grandchildNode == null ? void 0 : grandchildNode.props) == null ? void 0 : _a3.bars) || ((_b2 = grandchildNode == null ? void 0 : grandchildNode.props) == null ? void 0 : _b2.children)) {
            const { label, bars = [], children = [], id, connections = [] } = grandchildNode.props;
            rows2.push({
              id,
              label,
              bars,
              children,
              connections,
              _originalNode: grandchildNode
            });
          }
        });
      }
    });
    return rows2;
  };
  const getSourceRows = () => {
    var _a;
    if ((_a = initialRows == null ? void 0 : initialRows.value) == null ? void 0 : _a.length) {
      return initialRows.value;
    }
    return extractRowsFromSlots();
  };
  reorderedRows.value = getSourceRows();
  watch(
    () => getSourceRows(),
    (newRows) => {
      reorderedRows.value = newRows;
    }
  );
  const calculateGroupBars = (row) => {
    var _a;
    if (!((_a = row.children) == null ? void 0 : _a.length)) return row.bars || [];
    const allChildBars = row.children.flatMap((child) => {
      const childGroupBars = calculateGroupBars(child);
      return [...childGroupBars, ...child.bars || []];
    });
    if (!allChildBars.length) return [];
    const minStart = allChildBars.reduce(
      (min, bar) => {
        const currentStart = toDayjs(bar[barStart.value]);
        return !min || currentStart.isBefore(min) ? currentStart : min;
      },
      null
    );
    const maxEnd = allChildBars.reduce(
      (max, bar) => {
        const currentEnd = toDayjs(bar[barEnd.value]);
        return !max || currentEnd.isAfter(max) ? currentEnd : max;
      },
      null
    );
    if (!minStart || !maxEnd) return [];
    const format = typeof dateFormat.value === "string" ? dateFormat.value : "YYYY-MM-DD HH:mm";
    return [
      {
        [barStart.value]: minStart.format(format),
        [barEnd.value]: maxEnd.format(format),
        ganttBarConfig: {
          id: `group-${row.id || row.label}`,
          immobile: true,
          label: row.label,
          style: {
            background: "transparent"
          },
          connections: row.connections || []
        }
      }
    ];
  };
  const toDayjs = (input) => {
    if (typeof input === "string") {
      return dayjs(input);
    } else if (input instanceof Date) {
      return dayjs(input);
    }
    return dayjs();
  };
  const getStartDate = (row) => {
    var _a;
    if ((_a = row.children) == null ? void 0 : _a.length) {
      const childDates = row.children.map((child) => getStartDate(child)).filter((date) => date !== null);
      if (childDates.length === 0) {
        return getBarsStartDate(row.bars);
      }
      return childDates.reduce((min, date) => !min || date.isBefore(min) ? date : min);
    }
    return getBarsStartDate(row.bars);
  };
  const getBarsStartDate = (bars) => {
    if (bars.length === 0) return null;
    return bars.reduce((min, bar) => {
      const currentStart = toDayjs(bar[barStart.value]);
      return !min || currentStart.isBefore(min) ? currentStart : min;
    }, null);
  };
  const getEndDate = (row) => {
    var _a;
    if ((_a = row.children) == null ? void 0 : _a.length) {
      const childDates = row.children.map((child) => getEndDate(child)).filter((date) => date !== null);
      if (childDates.length === 0) {
        return getBarsEndDate(row.bars);
      }
      return childDates.reduce((max, date) => !max || date.isAfter(max) ? date : max);
    }
    return getBarsEndDate(row.bars);
  };
  const getBarsEndDate = (bars) => {
    if (bars.length === 0) return null;
    return bars.reduce((max, bar) => {
      const currentEnd = toDayjs(bar[barEnd.value]);
      return !max || currentEnd.isAfter(max) ? currentEnd : max;
    }, null);
  };
  const calculateDuration = (row) => {
    const startDate = getStartDate(row);
    const endDate = getEndDate(row);
    if (!startDate || !endDate) return 0;
    return endDate.diff(startDate, "minutes");
  };
  const compareValues = (a, b, column) => {
    var _a, _b, _c, _d, _e;
    if ((((_a = a.children) == null ? void 0 : _a.length) || 0) !== (((_b = b.children) == null ? void 0 : _b.length) || 0)) {
      return (((_c = b.children) == null ? void 0 : _c.length) || 0) - (((_d = a.children) == null ? void 0 : _d.length) || 0);
    }
    const columnConfig = (_e = multiColumnLabel.value) == null ? void 0 : _e.find((conf) => conf.field === column);
    if ((columnConfig == null ? void 0 : columnConfig.sortFn) && !isStandardField(column)) {
      return columnConfig.sortFn(a, b);
    }
    switch (column) {
      case "Id":
        const aId = a.id ?? 0;
        const bId = b.id ?? 0;
        return aId < bId ? -1 : aId > bId ? 1 : 0;
      case "Label":
        return a.label.localeCompare(b.label, void 0, {
          numeric: true,
          sensitivity: "base"
        });
      case "StartDate": {
        const aStartDate = getStartDate(a);
        const bStartDate = getStartDate(b);
        if (!aStartDate && !bStartDate) return 0;
        if (!aStartDate) return 1;
        if (!bStartDate) return -1;
        return aStartDate.valueOf() - bStartDate.valueOf();
      }
      case "EndDate": {
        const aEndDate = getEndDate(a);
        const bEndDate = getEndDate(b);
        if (!aEndDate && !bEndDate) return 0;
        if (!aEndDate) return 1;
        if (!bEndDate) return -1;
        return aEndDate.valueOf() - bEndDate.valueOf();
      }
      case "Duration": {
        const aDuration = calculateDuration(a);
        const bDuration = calculateDuration(b);
        return aDuration - bDuration;
      }
      case "Progress": {
        const getAvgProgress = (row) => {
          const progressValues = row.bars.map((bar) => bar.ganttBarConfig.progress).filter((progress) => progress !== void 0);
          if (progressValues.length === 0) return -1;
          return progressValues.reduce((sum, curr) => sum + curr, 0) / progressValues.length;
        };
        const progressA = getAvgProgress(a);
        const progressB = getAvgProgress(b);
        if (progressA === -1 && progressB === -1) return 0;
        if (progressA === -1) return 1;
        if (progressB === -1) return -1;
        return progressA - progressB;
      }
      default:
        if (columnConfig == null ? void 0 : columnConfig.valueGetter) {
          const aValue = columnConfig.valueGetter(a);
          const bValue = columnConfig.valueGetter(b);
          return String(aValue).localeCompare(String(bValue));
        }
        return 0;
    }
  };
  const isStandardField = (field) => {
    return ["Id", "Label", "StartDate", "EndDate", "Duration"].includes(field);
  };
  const applyCustomOrder = (rowsToSort) => {
    if (customOrder.value.size === 0 || sortState.value.direction !== "none") {
      return rowsToSort;
    }
    return [...rowsToSort].sort((a, b) => {
      const orderA = a.id ? customOrder.value.get(a.id) ?? Number.MAX_VALUE : Number.MAX_VALUE;
      const orderB = b.id ? customOrder.value.get(b.id) ?? Number.MAX_VALUE : Number.MAX_VALUE;
      return orderA - orderB;
    });
  };
  const rows = computed(() => {
    let sourceRows = [...reorderedRows.value];
    if (!sourceRows.length) return sourceRows;
    const processRowsWithGroupBars = (rows2) => {
      return rows2.map((row) => {
        var _a;
        if ((_a = row.children) == null ? void 0 : _a.length) {
          const processedChildren = processRowsWithGroupBars(row.children);
          return {
            ...row,
            children: processedChildren,
            bars: calculateGroupBars(row)
          };
        }
        return row;
      });
    };
    sourceRows = processRowsWithGroupBars(sourceRows);
    if (sortState.value.direction !== "none") {
      return sortRows(sourceRows, sortState.value.column, sortState.value.direction);
    }
    if (customOrder.value.size > 0) {
      return sourceRows.sort((a, b) => {
        const orderA = a.id ? customOrder.value.get(a.id) ?? Number.MAX_VALUE : Number.MAX_VALUE;
        const orderB = b.id ? customOrder.value.get(b.id) ?? Number.MAX_VALUE : Number.MAX_VALUE;
        return orderA - orderB;
      });
    }
    return sourceRows;
  });
  const resetCustomOrder = () => {
    customOrder.value.clear();
  };
  const sortRows = (rows2, column, direction) => {
    return rows2.map((row) => {
      var _a;
      if ((_a = row.children) == null ? void 0 : _a.length) {
        return {
          ...row,
          children: sortRows(row.children, column, direction)
        };
      }
      return row;
    }).sort((a, b) => {
      const comparison = compareValues(a, b, column);
      return direction === "asc" ? comparison : -comparison;
    });
  };
  const toggleSort = (column) => {
    const previousDirection = sortState.value.direction;
    if (sortState.value.column !== column) {
      sortState.value = {
        column,
        direction: "asc"
      };
    } else {
      switch (sortState.value.direction) {
        case "none":
          sortState.value.direction = "asc";
          break;
        case "asc":
          sortState.value.direction = "desc";
          break;
        case "desc":
          sortState.value.direction = "none";
          break;
      }
    }
    onSort(sortState.value);
    sortChangeCallbacks.value.forEach((callback) => callback());
    if (previousDirection !== "none" && sortState.value.direction === "none") {
      applyCustomOrder(rows.value);
    }
  };
  const toggleGroupExpansion = (rowId) => {
    if (expandedGroups.value.has(rowId)) {
      expandedGroups.value.delete(rowId);
    } else {
      expandedGroups.value.add(rowId);
    }
    onGroupExpansion(rowId);
    groupExpansionCallbacks.value.forEach((callback) => callback());
  };
  const isGroupExpanded = (rowId) => {
    return expandedGroups.value.has(rowId);
  };
  const getFlattenedRows = () => {
    const flatten = (rows2) => {
      return rows2.flatMap((row) => {
        var _a;
        if (!((_a = row.children) == null ? void 0 : _a.length) || !isGroupExpanded(row.id)) {
          return [row];
        }
        return [row, ...flatten(row.children)];
      });
    };
    return flatten(rows.value);
  };
  const onSortChange = (callback) => {
    sortChangeCallbacks.value.add(callback);
    return () => {
      sortChangeCallbacks.value.delete(callback);
    };
  };
  const onGroupExpansionChange = (callback) => {
    groupExpansionCallbacks.value.add(callback);
    return () => {
      groupExpansionCallbacks.value.delete(callback);
    };
  };
  const expandAllGroups = () => {
    const addGroupsToExpanded = (rows2) => {
      rows2.forEach((row) => {
        var _a;
        if (((_a = row.children) == null ? void 0 : _a.length) && row.id) {
          expandedGroups.value.add(row.id);
          addGroupsToExpanded(row.children);
        }
      });
    };
    addGroupsToExpanded(getSourceRows());
    groupExpansionCallbacks.value.forEach((callback) => callback());
  };
  const collapseAllGroups = () => {
    expandedGroups.value.clear();
    groupExpansionCallbacks.value.forEach((callback) => callback());
  };
  const hasAnyGroup = computed(() => {
    const checkForGroups = (rows2) => {
      return rows2.some(
        (row) => {
          var _a;
          return ((_a = row.children) == null ? void 0 : _a.length) > 0 || row.children && checkForGroups(row.children);
        }
      );
    };
    return checkForGroups(rows.value);
  });
  const areAllGroupsExpanded = computed(() => {
    if (!hasAnyGroup.value) return false;
    const checkAllExpanded = (rows2) => {
      return rows2.every((row) => {
        var _a;
        if ((_a = row.children) == null ? void 0 : _a.length) {
          const isCurrentExpanded = row.id ? expandedGroups.value.has(row.id) : false;
          return isCurrentExpanded && checkAllExpanded(row.children);
        }
        return true;
      });
    };
    return checkAllExpanded(rows.value);
  });
  const areAllGroupsCollapsed = computed(() => {
    if (!hasAnyGroup.value) return false;
    const checkAllCollapsed = (rows2) => {
      return rows2.every((row) => {
        var _a;
        if ((_a = row.children) == null ? void 0 : _a.length) {
          const isCurrentCollapsed = row.id ? !expandedGroups.value.has(row.id) : true;
          return isCurrentCollapsed && checkAllCollapsed(row.children);
        }
        return true;
      });
    };
    return checkAllCollapsed(rows.value);
  });
  const getChartRows = () => rows.value;
  const updateRows = (newRows) => {
    reorderedRows.value = newRows;
    addHistoryState();
  };
  return {
    rows,
    updateRows,
    sortState,
    toggleSort,
    getChartRows,
    onSortChange,
    toggleGroupExpansion,
    isGroupExpanded,
    getFlattenedRows,
    onGroupExpansionChange,
    customOrder,
    resetCustomOrder,
    expandAllGroups,
    collapseAllGroups,
    canUndo,
    canRedo,
    undo,
    redo,
    clearHistory,
    onBarMove,
    areAllGroupsExpanded,
    areAllGroupsCollapsed
  };
}
const useSectionResize = () => {
  const resizeState = ref({
    isResizing: false,
    startX: 0,
    startWidth: 0
  });
  const resetResizeState = () => {
    resizeState.value = {
      isResizing: false,
      startX: 0,
      startWidth: 0
    };
  };
  const handleResizeStart = (e, currentWidth) => {
    e.preventDefault();
    resizeState.value = {
      isResizing: true,
      startX: e.clientX,
      startWidth: currentWidth
    };
    document.body.style.cursor = "col-resize";
  };
  const handleResizeMove = (e, onResize) => {
    if (!resizeState.value.isResizing) return;
    e.preventDefault();
    const deltaX = e.clientX - resizeState.value.startX;
    const newWidth = Math.max(0, resizeState.value.startWidth + deltaX);
    onResize(newWidth);
  };
  const handleResizeEnd = () => {
    if (resizeState.value.isResizing) {
      document.body.style.cursor = "";
      resetResizeState();
    }
  };
  const handleTouchStart = (e, currentWidth) => {
    const touch = e.touches[0];
    if (!touch) return;
    e.preventDefault();
    resizeState.value = {
      isResizing: true,
      startX: touch.clientX,
      startWidth: currentWidth
    };
  };
  const handleTouchMove = (e, onResize) => {
    if (!resizeState.value.isResizing) return;
    const touch = e.touches[0];
    if (!touch) return;
    e.preventDefault();
    const deltaX = touch.clientX - resizeState.value.startX;
    const newWidth = Math.max(0, resizeState.value.startWidth + deltaX);
    onResize(newWidth);
  };
  return {
    resizeState,
    handleResizeStart,
    handleResizeMove,
    handleResizeEnd,
    handleTouchStart,
    handleTouchMove,
    resetResizeState
  };
};
function useConnectionCreation(config, rowManager, emit, reinitializeConnections) {
  const connectionState = ref({
    isCreating: false,
    sourceBar: null,
    sourcePoint: null,
    mouseX: 0,
    mouseY: 0
  });
  const hoverState = ref({
    isVisible: false,
    barId: null,
    point: null
  });
  const validateConnection = (sourceBar, targetBar) => {
    var _a;
    if (sourceBar.ganttBarConfig.id === targetBar.ganttBarConfig.id) {
      return { isValid: false, message: "Cannot connect a bar to itself" };
    }
    const existingConnection = (_a = sourceBar.ganttBarConfig.connections) == null ? void 0 : _a.find(
      (conn) => conn.targetId === targetBar.ganttBarConfig.id
    );
    if (existingConnection) {
      return { isValid: false, message: "Existing connection" };
    }
    return { isValid: true };
  };
  const startConnectionCreation = (bar, point, e) => {
    connectionState.value = {
      isCreating: true,
      sourceBar: bar,
      sourcePoint: point,
      mouseX: e.clientX,
      mouseY: e.clientY
    };
    emit("connection-start", {
      sourceBar: bar,
      connectionPoint: point,
      e
    });
  };
  const updateConnectionDrag = (e) => {
    if (!connectionState.value.isCreating) return;
    connectionState.value.mouseX = e.clientX;
    connectionState.value.mouseY = e.clientY;
    emit("connection-drag", {
      sourceBar: connectionState.value.sourceBar,
      connectionPoint: connectionState.value.sourcePoint,
      currentX: e.clientX,
      currentY: e.clientY,
      e
    });
  };
  const completeConnection = (targetBar, targetPoint, e) => {
    if (!connectionState.value.sourceBar) return;
    const validation = validateConnection(connectionState.value.sourceBar, targetBar);
    if (validation.isValid) {
      const newConnection = {
        targetId: targetBar.ganttBarConfig.id,
        type: config.defaultConnectionType.value,
        color: config.defaultConnectionColor.value,
        pattern: config.defaultConnectionPattern.value,
        animated: config.defaultConnectionAnimated.value,
        animationSpeed: config.defaultConnectionAnimationSpeed.value
      };
      if (!connectionState.value.sourceBar.ganttBarConfig.connections) {
        connectionState.value.sourceBar.ganttBarConfig.connections = [];
      }
      connectionState.value.sourceBar.ganttBarConfig.connections.push(newConnection);
      const updatedRows = [...rowManager.rows.value];
      rowManager.updateRows(updatedRows);
      reinitializeConnections();
      emit("connection-complete", {
        sourceBar: connectionState.value.sourceBar,
        targetBar,
        sourcePoint: connectionState.value.sourcePoint,
        targetPoint,
        e
      });
    }
    resetConnectionState();
  };
  const handleConnectionPointHover = (barId, point, isEnter) => {
    hoverState.value = {
      isVisible: isEnter,
      barId: isEnter ? barId : null,
      point: isEnter ? point : null
    };
  };
  const cancelConnectionCreation = (e) => {
    if (connectionState.value.sourceBar && connectionState.value.sourcePoint) {
      emit("connection-cancel", {
        sourceBar: connectionState.value.sourceBar,
        connectionPoint: connectionState.value.sourcePoint,
        e
      });
    }
    resetConnectionState();
  };
  const resetConnectionState = () => {
    connectionState.value = {
      isCreating: false,
      sourceBar: null,
      sourcePoint: null,
      mouseX: 0,
      mouseY: 0
    };
  };
  const canBeConnectionTarget = computed(() => (bar) => {
    if (!connectionState.value.sourceBar) return false;
    return validateConnection(connectionState.value.sourceBar, bar).isValid;
  });
  return {
    connectionState,
    hoverState,
    startConnectionCreation,
    updateConnectionDrag,
    completeConnection,
    cancelConnectionCreation,
    handleConnectionPointHover,
    canBeConnectionTarget
  };
}
function useExport(getChartElement, getWrapperElement, rowManager, config) {
  const isExporting = ref(false);
  const lastError = ref(null);
  const prepareElementForExport = (element, wrapperELement, options) => {
    const clonedElement = wrapperELement.cloneNode(true);
    clonedElement.style.width = element.offsetWidth + "px";
    clonedElement.style.height = element.offsetHeight + "px";
    const textSelectors = [".g-gantt-bar-label > div", ".g-timeunit-min", ".label-unit"];
    const textElements = clonedElement.querySelectorAll(textSelectors.join(", "));
    const commands = clonedElement.querySelector(".g-gantt-command");
    commands.style.display = "none";
    if (!options.exportColumnLabel) {
      const columnLabels = clonedElement.querySelector(".g-gantt-label-section");
      columnLabels.style.display = "none";
    }
    textElements.forEach((el) => {
      const element2 = el;
      element2.style.display = "flex";
      element2.style.alignItems = "center";
      element2.style.justifyContent = "center";
      element2.style.textAlign = "center";
      element2.style.position = "relative";
      element2.style.fontSize = "10px";
      element2.style.transform = "translateY(-25%)";
    });
    const ellipsisElements = clonedElement.querySelectorAll(
      ".cell-content, .text-ellipsis, .text-ellipsis-value"
    );
    ellipsisElements.forEach((el) => {
      const element2 = el;
      element2.style.overflow = "visible";
      element2.style.alignItems = "center";
      element2.style.whiteSpace = "normal";
      element2.style.textOverflow = "ellipsis";
      element2.style.fontSize = "10px";
      element2.style.transform = "translateY(-1%)";
    });
    const rows = clonedElement.querySelectorAll(".g-label-column-row");
    rows.forEach((row) => {
      const rowElement = row;
      rowElement.style.overflow = "visible";
      rowElement.style.flexWrap = "wrap";
    });
    const barLabels = clonedElement.querySelectorAll(".g-gantt-bar-label");
    barLabels.forEach((el) => {
      const element2 = el;
      element2.style.overflow = "hidden";
      element2.style.textOverflow = "ellipsis";
      element2.style.whiteSpace = "nowrap";
      element2.style.transform = "translateY(-15%)";
    });
    const progressBars = clonedElement.querySelectorAll(".g-gantt-progress-bar");
    progressBars.forEach((el) => {
      const element2 = el;
      element2.style.display = "";
      element2.style.alignItems = "";
      element2.style.justifyContent = "";
      element2.style.transform = "";
      element2.style.position = "";
    });
    const minUnitLabels = clonedElement.querySelectorAll(".g-timeunit-min");
    minUnitLabels.forEach((el) => {
      const element2 = el;
      element2.style.transform = "translateY(-35%)";
    });
    const progressTexts = clonedElement.querySelectorAll(".progress-text");
    progressTexts.forEach((el) => {
      const element2 = el;
      element2.style.transform = "translateY(-40%)";
    });
    const timeAxisEventsLabels = clonedElement.querySelectorAll(".g-timeaxis-event-label");
    timeAxisEventsLabels.forEach((el) => {
      const element2 = el;
      element2.style.fontSize = "8px";
      element2.style.transform = "translateY(-45%)";
    });
    const milestoneLabels = clonedElement.querySelectorAll(".g-gantt-milestone-label");
    milestoneLabels.forEach((el) => {
      const element2 = el;
      element2.style.transform = "translateY(-15%)";
    });
    const milestoneMarkers = clonedElement.querySelectorAll(".g-gantt-milestone-marker");
    milestoneMarkers.forEach((el) => {
      const element2 = el;
      element2.style.transform = "translateY(-0.2%)";
    });
    const rowLabels = clonedElement.querySelectorAll(".g-gantt-row-label");
    rowLabels.forEach((el) => {
      const element2 = el;
      element2.style.transform = "translateY(-15%)";
    });
    return clonedElement;
  };
  const exportChart = async (options) => {
    isExporting.value = true;
    lastError.value = null;
    try {
      const element = getChartElement();
      const wrapper = getWrapperElement();
      if (!element || !wrapper) {
        throw new Error("Gantt chart element not found");
      }
      const filename = options.filename || `gantt-export-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
      switch (options.format) {
        case "pdf":
          return await exportToPdf(element, wrapper, {
            ...options,
            filename: filename + ".pdf"
          });
        case "png":
          return await exportToPng(element, wrapper, {
            ...options,
            filename: filename + ".png"
          });
        case "svg":
          return await exportToSvg(element, wrapper, {
            ...options,
            filename: filename + ".svg"
          });
        case "excel":
          return await exportToExcel({
            ...options,
            filename: filename + ".xlsx"
          });
        default:
          throw new Error(`Format file export not supported: ${options.format}`);
      }
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : "Unknown Error";
      lastError.value = errorMessage;
      return {
        success: false,
        data: null,
        error: errorMessage,
        filename: options.filename || "export-error"
      };
    } finally {
      isExporting.value = false;
    }
  };
  const exportToPdf = async (element, wrapper, options) => {
    try {
      const processedElement = prepareElementForExport(element, wrapper, options);
      const tempContainer = document.createElement("div");
      tempContainer.style.position = "absolute";
      tempContainer.style.left = "-9999px";
      tempContainer.style.width = element.offsetWidth + "px";
      tempContainer.style.height = element.offsetHeight + "px";
      tempContainer.style.overflow = "hidden";
      tempContainer.appendChild(processedElement);
      document.body.appendChild(tempContainer);
      await new Promise((resolve) => setTimeout(resolve, 100));
      const paperSize = options.paperSize || "a4";
      const orientation = options.orientation || "landscape";
      const scale = options.scale || 1;
      const margin = options.margin !== void 0 ? options.margin : 10;
      const pdf = new jsPDF({
        orientation,
        unit: "mm",
        format: paperSize
      });
      const canvas = await html2canvas(processedElement, {
        scale,
        logging: false,
        allowTaint: true,
        useCORS: true,
        backgroundColor: "#ffffff",
        imageTimeout: 0,
        removeContainer: false,
        foreignObjectRendering: false
      });
      document.body.removeChild(tempContainer);
      const pageWidth = orientation === "landscape" ? pdf.internal.pageSize.getHeight() : pdf.internal.pageSize.getWidth();
      const pageHeight = orientation === "landscape" ? pdf.internal.pageSize.getWidth() : pdf.internal.pageSize.getHeight();
      const pdfWidth = pageWidth - margin * 2;
      const imgWidth = canvas.width;
      const imgHeight = canvas.height;
      const ratio = imgWidth / imgHeight;
      let pdfHeight = pdfWidth / ratio;
      if (pdfHeight > pageHeight - margin * 2) {
        let currentHeight = 0;
        while (currentHeight < imgHeight) {
          if (currentHeight > 0) {
            pdf.addPage();
          }
          const canvasSection = Math.min(
            imgHeight - currentHeight,
            imgWidth / pdfWidth * (pageHeight - margin * 2)
          );
          const sectionHeight = canvasSection / imgHeight * imgHeight;
          pdf.addImage(
            canvas.toDataURL("image/jpeg", options.quality || 0.95),
            "JPEG",
            margin,
            margin,
            pdfWidth,
            pdfWidth * (sectionHeight / imgWidth),
            "",
            "FAST",
            currentHeight / imgHeight
          );
          currentHeight += canvasSection;
        }
      } else {
        pdf.addImage(
          canvas.toDataURL("image/jpeg", options.quality || 0.95),
          "JPEG",
          margin,
          margin,
          pdfWidth,
          pdfHeight,
          "",
          "FAST"
        );
      }
      const blob = pdf.output("blob");
      return {
        success: true,
        data: blob,
        filename: options.filename || "gantt-chart.pdf"
      };
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : "Error during PDF export";
      return {
        success: false,
        data: null,
        error: errorMessage,
        filename: options.filename || "gantt-chart.pdf"
      };
    }
  };
  const exportToPng = async (element, wrapper, options) => {
    try {
      const processedElement = prepareElementForExport(element, wrapper, options);
      const tempContainer = document.createElement("div");
      tempContainer.style.position = "absolute";
      tempContainer.style.left = "-9999px";
      tempContainer.style.width = element.offsetWidth + "px";
      tempContainer.style.height = element.offsetHeight + "px";
      tempContainer.style.overflow = "hidden";
      tempContainer.appendChild(processedElement);
      document.body.appendChild(tempContainer);
      await new Promise((resolve) => setTimeout(resolve, 100));
      const scale = options.scale || 2;
      const canvas = await html2canvas(processedElement, {
        scale,
        logging: false,
        allowTaint: true,
        useCORS: true,
        backgroundColor: "#ffffff",
        imageTimeout: 0,
        removeContainer: false,
        foreignObjectRendering: false
      });
      document.body.removeChild(tempContainer);
      const blob = await new Promise((resolve, reject) => {
        canvas.toBlob(
          (blob2) => {
            if (blob2) {
              resolve(blob2);
            } else {
              reject(new Error("Error creating blob PNG"));
            }
          },
          "image/png",
          options.quality || 0.95
        );
      });
      return {
        success: true,
        data: blob,
        filename: options.filename || "gantt-chart.png"
      };
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : "Error exporting PNG";
      return {
        success: false,
        data: null,
        error: errorMessage,
        filename: options.filename || "gantt-chart.png"
      };
    }
  };
  const exportToSvg = async (element, wrapper, options) => {
    try {
      const processedElement = prepareElementForExport(element, wrapper, options);
      const tempContainer = document.createElement("div");
      tempContainer.style.position = "absolute";
      tempContainer.style.left = "-9999px";
      tempContainer.style.width = element.offsetWidth + "px";
      tempContainer.style.height = element.offsetHeight + "px";
      tempContainer.style.overflow = "hidden";
      tempContainer.appendChild(processedElement);
      document.body.appendChild(tempContainer);
      await new Promise((resolve) => setTimeout(resolve, 100));
      const canvas = await html2canvas(processedElement, {
        scale: options.scale || 2,
        logging: false,
        allowTaint: true,
        useCORS: true,
        backgroundColor: "#ffffff",
        imageTimeout: 0,
        removeContainer: false,
        foreignObjectRendering: false
      });
      document.body.removeChild(tempContainer);
      const width = canvas.width;
      const height = canvas.height;
      const svgNS = "http://www.w3.org/2000/svg";
      const svgRoot = document.createElementNS(svgNS, "svg");
      svgRoot.setAttribute("width", width.toString());
      svgRoot.setAttribute("height", height.toString());
      svgRoot.setAttribute("viewBox", `0 0 ${width} ${height}`);
      svgRoot.setAttribute("xmlns", svgNS);
      svgRoot.setAttribute("version", "1.1");
      const img = document.createElementNS(svgNS, "image");
      img.setAttribute("width", width.toString());
      img.setAttribute("height", height.toString());
      img.setAttribute("x", "0");
      img.setAttribute("y", "0");
      img.setAttribute("href", canvas.toDataURL("image/png", options.quality || 0.95));
      svgRoot.appendChild(img);
      const serializer = new XMLSerializer();
      const svgString = serializer.serializeToString(svgRoot);
      const finalSvgString = '<?xml version="1.0" standalone="no"?>\n' + svgString;
      const blob = new Blob([finalSvgString], { type: "image/svg+xml;charset=utf-8" });
      return {
        success: true,
        data: blob,
        filename: options.filename || "gantt-chart.svg"
      };
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : "Error exporting in SVG";
      return {
        success: false,
        data: null,
        error: errorMessage,
        filename: options.filename || "gantt-chart.svg"
      };
    }
  };
  const exportToExcel = async (options) => {
    try {
      const workbook = XLSX.utils.book_new();
      const getAllRows = (rows) => {
        return rows.flatMap((row) => {
          var _a;
          if (!((_a = row.children) == null ? void 0 : _a.length)) {
            return [row];
          }
          return [row, ...getAllRows(row.children)];
        });
      };
      const allRows = getAllRows(rowManager.rows.value);
      const firstSheetData = [];
      firstSheetData.push(["ID", "Task", "Start Date", "End Date", "Duration", "Progress (%)"]);
      allRows.forEach((row, index) => {
        let startDate = "-";
        let endDate = "-";
        let duration = "-";
        let progress = "-";
        if (row.bars && row.bars.length > 0) {
          const minStartDate = row.bars.reduce(
            (min, bar) => {
              const currentStart = dayjs(bar[config.barStart.value]);
              return !min || currentStart.isBefore(min) ? currentStart : min;
            },
            null
          );
          const maxEndDate = row.bars.reduce(
            (max, bar) => {
              const currentEnd = dayjs(bar[config.barEnd.value]);
              return !max || currentEnd.isAfter(max) ? currentEnd : max;
            },
            null
          );
          if (minStartDate) {
            startDate = minStartDate.format(config.dateFormat.value || "YYYY-MM-DD HH:mm");
          }
          if (maxEndDate) {
            endDate = maxEndDate.format(config.dateFormat.value || "YYYY-MM-DD HH:mm");
          }
          if (minStartDate && maxEndDate) {
            const durationValue = maxEndDate.diff(minStartDate, config.precision.value);
            duration = `${durationValue}${config.precision.value.charAt(0)}`;
          }
          const progressValues = row.bars.map((bar) => bar.ganttBarConfig.progress).filter((progress2) => progress2 !== void 0);
          if (progressValues.length > 0) {
            const avgProgress = progressValues.reduce((sum, curr) => sum + curr, 0) / progressValues.length;
            progress = `${Math.round(avgProgress)}%`;
          }
        }
        firstSheetData.push([
          row.id || index + 1,
          row.label,
          startDate,
          endDate,
          duration,
          progress
        ]);
      });
      const worksheet1 = XLSX.utils.aoa_to_sheet(firstSheetData);
      XLSX.utils.book_append_sheet(workbook, worksheet1, "Gantt Rows");
      const secondSheetData = [];
      secondSheetData.push([
        "Bar ID",
        "Label",
        "Parent Row",
        "Row ID",
        "Start Date",
        "End Date",
        "Duration",
        "Progress (%)",
        "Connections",
        "Milestone"
      ]);
      const processedBarIds = /* @__PURE__ */ new Set();
      const allBars = [];
      const collectBars = (rows) => {
        rows.forEach((row) => {
          row.bars.forEach((bar) => {
            if (!processedBarIds.has(bar.ganttBarConfig.id)) {
              processedBarIds.add(bar.ganttBarConfig.id);
              allBars.push({
                bar,
                rowLabel: row.label,
                rowId: row.id || ""
              });
            }
          });
          if (row.children && row.children.length > 0) {
            collectBars(row.children);
          }
        });
      };
      collectBars(rowManager.rows.value);
      allBars.forEach((item) => {
        const { bar, rowLabel, rowId } = item;
        const barConfig = bar.ganttBarConfig;
        const startDate = dayjs(bar[config.barStart.value]).format(
          config.dateFormat.value || "YYYY-MM-DD HH:mm"
        );
        const endDate = dayjs(bar[config.barEnd.value]).format(
          config.dateFormat.value || "YYYY-MM-DD HH:mm"
        );
        const durationValue = dayjs(bar[config.barEnd.value]).diff(
          dayjs(bar[config.barStart.value]),
          config.precision.value
        );
        const duration = `${durationValue}${config.precision.value.charAt(0)}`;
        const progress = barConfig.progress !== void 0 ? `${Math.round(barConfig.progress)}%` : "-";
        const connections = barConfig.connections && barConfig.connections.length > 0 ? barConfig.connections.map((conn) => conn.targetId).join(", ") : "-";
        const milestone = barConfig.milestoneId ? barConfig.milestoneId : "-";
        secondSheetData.push([
          barConfig.id,
          barConfig.label || "",
          rowLabel,
          rowId,
          startDate,
          endDate,
          duration,
          progress,
          connections,
          milestone
        ]);
      });
      const worksheet2 = XLSX.utils.aoa_to_sheet(secondSheetData);
      XLSX.utils.book_append_sheet(workbook, worksheet2, "Bars Detail");
      [worksheet1, worksheet2].forEach((worksheet) => {
        const headerRange = XLSX.utils.decode_range(worksheet["!ref"] || "A1");
        for (let col = headerRange.s.c; col <= headerRange.e.c; col++) {
          const cellRef = XLSX.utils.encode_cell({ r: 0, c: col });
          if (!worksheet[cellRef]) worksheet[cellRef] = {};
          worksheet[cellRef].s = { font: { bold: true } };
        }
      });
      const colWidths1 = [
        { wch: 10 },
        { wch: 40 },
        { wch: 20 },
        { wch: 20 },
        { wch: 10 },
        { wch: 15 }
      ];
      worksheet1["!cols"] = colWidths1;
      const colWidths2 = [
        { wch: 15 },
        { wch: 30 },
        { wch: 30 },
        { wch: 10 },
        { wch: 20 },
        { wch: 20 },
        { wch: 10 },
        { wch: 15 },
        { wch: 30 },
        { wch: 20 }
      ];
      worksheet2["!cols"] = colWidths2;
      const excelBuffer = XLSX.write(workbook, { bookType: "xlsx", type: "array" });
      const blob = new Blob([excelBuffer], {
        type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
      });
      return {
        success: true,
        data: blob,
        filename: options.filename || "gantt-chart.xlsx"
      };
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : "Error exporting to Excel";
      console.error("Error during Excel export:", error);
      return {
        success: false,
        data: null,
        error: errorMessage,
        filename: options.filename || "gantt-chart.xlsx"
      };
    }
  };
  const downloadExport = (result) => {
    if (result.success && result.data) {
      const url = URL.createObjectURL(result.data);
      const link = document.createElement("a");
      link.href = url;
      link.download = result.filename;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(url);
    }
  };
  return {
    exportChart,
    downloadExport,
    isExporting,
    lastError
  };
}
const colorSchemes = {
  default: {
    primary: "#eeeeee",
    secondary: "#E0E0E0",
    ternary: "#F5F5F5",
    quartenary: "#ededed",
    hoverHighlight: "rgba(204, 216, 219, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "#404040",
    background: "white",
    commands: "#eeeeee",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "rgba(0, 0, 0, 0.7)",
    rowContainer: "rgba(255, 255, 255, 1)",
    gridAndBorder: "#eaeaea"
  },
  creamy: {
    primary: "#ffe8d9",
    secondary: "#fcdcc5",
    ternary: "#fff6f0",
    quartenary: "#f7ece6",
    hoverHighlight: "rgba(230, 221, 202, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "#542d05",
    background: "white",
    commands: "white",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "#fcdcc5",
    rowContainer: "rgba(255, 255, 255, 1)",
    gridAndBorder: "#eaeaea"
  },
  crimson: {
    primary: "#a82039",
    secondary: "#c41238",
    ternary: "#db4f56",
    quartenary: "#ce5f64",
    hoverHighlight: "rgba(196, 141, 141, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "black",
    background: "white",
    commands: "white",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "#c41238",
    rowContainer: "rgba(255, 255, 255, 1)",
    gridAndBorder: "#eaeaea"
  },
  dark: {
    primary: "#404040",
    secondary: "#303030",
    ternary: "#353535",
    quartenary: "#383838",
    hoverHighlight: "rgba(159, 160, 161, 0.5)",
    markerCurrentTime: "#fff",
    markerPointer: "#fff",
    text: "white",
    background: "#525252",
    toast: "#1f1f1f",
    commands: "#525252",
    rangeHighlight: "#000",
    holidayHighlight: "#ff9d3b",
    barContainer: "rgba(0, 0, 0, 1)",
    rowContainer: "rgba(0, 0, 0, 1)",
    gridAndBorder: "#eaeaea"
  },
  flare: {
    primary: "#e08a38",
    secondary: "#e67912",
    ternary: "#5e5145",
    quartenary: "#665648",
    hoverHighlight: "rgba(196, 141, 141, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "white",
    background: "white",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "rgba(0, 0, 0, 1)",
    rowContainer: "rgba(0, 0, 0, 1)",
    gridAndBorder: "#eaeaea"
  },
  fuchsia: {
    primary: "#de1d5a",
    secondary: "#b50b41",
    ternary: "#ff7da6",
    quartenary: "#f2799f",
    hoverHighlight: "rgba(196, 141, 141, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "white",
    background: "white",
    commands: "white",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "#de1d5a",
    rowContainer: "rgba(0, 0, 0, 1)",
    gridAndBorder: "#eaeaea"
  },
  grove: {
    primary: "#3d9960",
    secondary: "#288542",
    ternary: "#72b585",
    quartenary: "#65a577",
    hoverHighlight: "rgba(160, 219, 171, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "white",
    background: "white",
    commands: "white",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "#3d9960",
    rowContainer: "rgba(0, 0, 0, 1)",
    gridAndBorder: "#eaeaea"
  },
  "material-blue": {
    primary: "#0D47A1",
    secondary: "#1565C0",
    ternary: "#42a5f5",
    quartenary: "#409fed",
    hoverHighlight: "rgba(110, 165, 196, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "white",
    background: "white",
    commands: "white",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "#0D47A1",
    rowContainer: "rgba(0, 0, 0, 1)",
    gridAndBorder: "#eaeaea"
  },
  sky: {
    primary: "#b5e3ff",
    secondary: "#a1d6f7",
    ternary: "#d6f7ff",
    quartenary: "#d0edf4",
    hoverHighlight: "rgba(193, 202, 214, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "#022c47",
    background: "white",
    commands: "white",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "rgb(20,20,20)",
    rowContainer: "#a1d6f7",
    gridAndBorder: "#eaeaea"
  },
  slumber: {
    primary: "#2a2f42",
    secondary: "#2f3447",
    ternary: "#35394d",
    quartenary: "#2c3044",
    hoverHighlight: "rgba(179, 162, 127, 0.5)",
    markerCurrentTime: "#fff",
    markerPointer: "#fff",
    text: "#ffe0b3",
    background: "#38383b",
    toast: "#1f1f1f",
    commands: "#38383b",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "#2a2f42",
    rowContainer: "rgba(0, 0, 0, 1)",
    gridAndBorder: "#eaeaea"
  },
  vue: {
    primary: "#258a5d",
    secondary: "#41B883",
    ternary: "#35495E",
    quartenary: "#2a3d51",
    hoverHighlight: "rgba(160, 219, 171, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "white",
    background: "white",
    commands: "white",
    rangeHighlight: "#000",
    holidayHighlight: "#f7842d",
    barContainer: "#258a5d",
    rowContainer: "rgba(0, 0, 0, 1)",
    gridAndBorder: "#eaeaea"
  }
};
const _hoisted_1 = ["id"];
const _hoisted_2 = {
  class: "g-gantt-main-layout",
  "aria-controls": "gantt-controls"
};
const _hoisted_3 = {
  key: 0,
  class: "connection-preview",
  style: {
    position: "absolute",
    top: 0,
    left: 0,
    width: "100%",
    height: "100%",
    pointerEvents: "none",
    zIndex: 2e3,
    overflow: "visible"
  }
};
const _hoisted_4 = { class: "g-gantt-command-block" };
const _hoisted_5 = {
  key: 0,
  class: "g-gantt-command-vertical"
};
const _hoisted_6 = ["disabled"];
const _hoisted_7 = ["disabled"];
const _hoisted_8 = {
  key: 1,
  class: "g-gantt-command-groups"
};
const _hoisted_9 = ["disabled"];
const _hoisted_10 = ["disabled"];
const _hoisted_11 = { class: "g-gantt-command-fixed" };
const _hoisted_12 = { class: "g-gantt-command-slider" };
const _hoisted_13 = ["disabled"];
const _hoisted_14 = ["disabled"];
const _hoisted_15 = ["aria-valuenow"];
const _hoisted_16 = ["disabled"];
const _hoisted_17 = ["disabled"];
const _hoisted_18 = { class: "g-gantt-command-block" };
const _hoisted_19 = { class: "g-gantt-command-zoom" };
const _hoisted_20 = ["disabled"];
const _hoisted_21 = ["disabled"];
const _hoisted_22 = { class: "g-gantt-command-history" };
const _hoisted_23 = ["disabled"];
const _hoisted_24 = ["disabled"];
const _hoisted_25 = { class: "g-gantt-command-block" };
const _hoisted_26 = {
  key: 0,
  class: "g-gantt-command-export"
};
const _hoisted_27 = { class: "g-gantt-export-container" };
const _hoisted_28 = ["disabled"];
const _hoisted_29 = ["disabled"];
const _hoisted_30 = {
  key: 0,
  class: "g-gantt-export-loading"
};
const _sfc_main = /* @__PURE__ */ defineComponent({
  __name: "GGanttChart",
  props: {
    chartStart: {},
    chartEnd: {},
    precision: { default: "day" },
    barStart: {},
    barEnd: {},
    currentTime: { type: Boolean },
    currentTimeLabel: { default: "" },
    pointerMarker: { type: Boolean },
    dateFormat: { type: [String, Boolean], default: DEFAULT_DATE_FORMAT },
    width: { default: "100%" },
    hideTimeaxis: { type: Boolean, default: false },
    colorScheme: { default: "default" },
    grid: { type: Boolean, default: false },
    pushOnOverlap: { type: Boolean, default: false },
    pushOnConnect: { type: Boolean, default: false },
    noOverlap: { type: Boolean, default: false },
    rowHeight: { default: 40 },
    font: { default: "inherit" },
    labelColumnTitle: { default: "" },
    labelColumnWidth: { default: 120 },
    multiColumnLabel: { default: () => [] },
    commands: { type: Boolean, default: true },
    enableMinutes: { type: Boolean, default: false },
    enableConnections: { type: Boolean, default: true },
    enableConnectionCreation: { type: Boolean, default: false },
    enableConnectionDeletion: { type: Boolean, default: false },
    defaultConnectionType: { default: "straight" },
    defaultConnectionColor: { default: "#ff0000" },
    defaultConnectionPattern: { default: "solid" },
    defaultConnectionAnimated: { type: Boolean, default: false },
    defaultConnectionAnimationSpeed: { default: "normal" },
    maxRows: { default: 0 },
    initialSort: { default: () => ({
      column: "Label",
      direction: "none"
    }) },
    initialRows: { default: () => [] },
    sortable: { type: Boolean, default: true },
    labelResizable: { type: Boolean, default: true },
    milestones: { default: () => [] },
    timeaxisEvents: { default: () => [] },
    showEventsAxis: { type: Boolean, default: true },
    eventsAxisHeight: { default: 25 },
    holidayHighlight: { default: "" },
    rowClass: { type: Function, default: () => "" },
    rowLabelClass: { type: Function, default: () => "" },
    dayOptionLabel: { default: () => ["day"] },
    highlightedHours: { default: () => [] },
    highlightedDaysInWeek: { default: () => [] },
    highlightedDaysInMonth: { default: () => [] },
    highlightedMonths: { default: () => [] },
    highlightedWeek: { default: () => [] },
    locale: { default: "en" },
    enableRowDragAndDrop: { type: Boolean, default: false },
    markerConnection: { default: "forward" },
    showLabel: { type: Boolean, default: true },
    showProgress: { type: Boolean, default: true },
    defaultProgressResizable: { type: Boolean, default: true },
    utc: { type: Boolean, default: false },
    barLabelEditable: { type: Boolean, default: false },
    exportEnabled: { type: Boolean, default: true },
    exportOptions: { default: () => ({
      format: "pdf",
      quality: 0.95,
      paperSize: "a4",
      orientation: "landscape",
      scale: 1.5,
      margin: 10,
      exportColumnLabel: true
    }) }
  },
  emits: ["click-bar", "mousedown-bar", "mouseup-bar", "dblclick-bar", "mouseenter-bar", "mouseleave-bar", "dragstart-bar", "drag-bar", "dragend-bar", "contextmenu-bar", "sort", "group-expansion", "row-drop", "progress-change", "progress-drag-start", "progress-drag-end", "connection-start", "connection-drag", "connection-complete", "connection-cancel", "connection-delete", "label-edit", "export-start", "export-success", "export-error"],
  setup(__props, { expose: __expose, emit: __emit }) {
    useCssVars((_ctx) => ({
      "170a1ade": colors.value.rangeHighlight,
      "1a0a3e0a": colors.value.primary
    }));
    const props = __props;
    const emit = __emit;
    const id = ref(v4());
    const slots = useSlots();
    const isDragging = ref(false);
    const isDraggingTimeaxis = ref(false);
    const lastMouseX = ref(0);
    const gGantt = ref(null);
    const ganttChart = ref(null);
    const ganttWrapper = ref(null);
    const timeaxisComponent = ref(null);
    const ganttContainer = ref(null);
    const rowsContainer = ref(null);
    const labelColumn = ref(null);
    const setLabelWidth = () => {
      return props.labelColumnWidth * (props.multiColumnLabel.length === 0 ? 1 : props.multiColumnLabel.length + (props.multiColumnLabel.some((el) => el.field === "Label") ? 0 : 1));
    };
    const labelSectionWidth = ref(setLabelWidth());
    watch(
      () => props.multiColumnLabel,
      () => {
        labelSectionWidth.value = setLabelWidth();
      }
    );
    const chartSize = useElementSize(ganttChart);
    const handleTimeaxisTouch = {
      startX: 0,
      isDragging: false
    };
    const rowManager = useRows(
      slots,
      {
        barStart: toRef(props, "barStart"),
        barEnd: toRef(props, "barEnd"),
        dateFormat: toRef(props, "dateFormat"),
        multiColumnLabel: toRef(props, "multiColumnLabel"),
        onSort: (sortState) => emit("sort", { sortState }),
        initialSort: props.initialSort,
        onGroupExpansion: (rowId) => emit("group-expansion", { rowId })
      },
      props.initialRows ? toRef(props, "initialRows") : void 0
    );
    provide("useRows", rowManager);
    const {
      connections,
      barPositions,
      getConnectorProps,
      initializeConnections,
      updateBarPositions,
      handleConnectionClick,
      selectedConnection,
      deleteSelectedConnection
    } = useConnections(rowManager, props, id, emit);
    const { showTooltip, tooltipBar, initTooltip, clearTooltip } = useTooltip();
    const { font, colorScheme } = toRefs(props);
    const colors = computed(() => getColorScheme(colorScheme.value));
    const { timeaxisUnits, internalPrecision, zoomLevel, adjustZoomAndPrecision } = useTimeaxisUnits({
      ...toRefs(props),
      colors,
      chartSize
    });
    const {
      scrollPosition,
      handleStep,
      handleScroll,
      handleWheel,
      handleContentScroll,
      handleLabelScroll,
      handleZoomUpdate,
      scrollRowUp,
      scrollRowDown,
      isAtTop,
      isAtBottom
    } = useChartNavigation(
      {
        scrollRefs: {
          rowsContainer,
          labelColumn
        },
        updateBarPositions,
        timeaxisUnits: { timeaxisUnits, internalPrecision, zoomLevel, adjustZoomAndPrecision }
      },
      props.maxRows
    );
    const { handleKeyDown } = useKeyboardNavigation(
      {
        scrollPosition,
        handleStep,
        handleZoomUpdate
      },
      ganttWrapper,
      ganttContainer,
      {
        selectedConnection,
        deleteSelectedConnection
      },
      toRef(props.enableConnectionDeletion)
    );
    const {
      handleResizeStart,
      handleResizeMove,
      handleResizeEnd,
      handleTouchStart,
      handleTouchMove,
      resetResizeState
    } = useSectionResize();
    const {
      connectionState,
      hoverState,
      startConnectionCreation,
      updateConnectionDrag,
      completeConnection,
      cancelConnectionCreation,
      handleConnectionPointHover,
      canBeConnectionTarget
    } = useConnectionCreation(
      {
        ...toRefs(props),
        colors,
        chartSize
      },
      rowManager,
      emit,
      initializeConnections
    );
    provide("connectionCreation", {
      connectionState,
      hoverState,
      startConnectionCreation,
      updateConnectionDrag,
      completeConnection,
      cancelConnectionCreation,
      handleConnectionPointHover,
      canBeConnectionTarget
    });
    const handleChartMouseMove = (e) => {
      if (connectionState.value.isCreating) {
        updateConnectionDrag(e);
      }
    };
    const handleChartMouseUp = (e) => {
      if (connectionState.value.isCreating) {
        cancelConnectionCreation(e);
      }
    };
    const { findBarElement } = useBarSelector();
    const previewLinePoints = computed(() => {
      if (!connectionState.value.isCreating || !connectionState.value.sourceBar) return null;
      const sourceBarElement = findBarElement(
        id.value,
        connectionState.value.sourceBar.ganttBarConfig.id
      );
      if (!sourceBarElement) return null;
      const sourceRect = sourceBarElement.getBoundingClientRect();
      const containerElement = ganttContainer.value;
      const rowsContainer2 = containerElement == null ? void 0 : containerElement.querySelector(".g-gantt-rows-container");
      if (!rowsContainer2) return null;
      const containerRect = rowsContainer2.getBoundingClientRect();
      const scrollLeft = rowsContainer2.scrollLeft;
      const scrollTop = rowsContainer2.scrollTop;
      const sourceX = connectionState.value.sourcePoint === "start" ? sourceRect.left - containerRect.left + scrollLeft : sourceRect.right - containerRect.left + scrollLeft;
      const sourceY = sourceRect.top - containerRect.top + scrollTop + sourceRect.height / 2;
      const mouseX = connectionState.value.mouseX - containerRect.left + scrollLeft;
      const mouseY = connectionState.value.mouseY - containerRect.top + scrollTop;
      return {
        x1: sourceX,
        y1: sourceY,
        x2: mouseX,
        y2: mouseY
      };
    });
    watch(
      () => scrollPosition.value,
      () => {
        var _a;
        if (connectionState.value.isCreating) {
          const container = (_a = ganttContainer.value) == null ? void 0 : _a.querySelector(".g-gantt-rows-container");
          if (container) {
            connectionState.value.mouseX = connectionState.value.mouseX;
          }
        }
      }
    );
    const { exportChart, downloadExport, isExporting } = useExport(
      () => ganttChart.value,
      () => gGantt.value,
      rowManager,
      {
        barStart: toRef(props, "barStart"),
        barEnd: toRef(props, "barEnd"),
        dateFormat: toRef(props, "dateFormat"),
        precision: toRef(props, "precision")
      }
    );
    const handleExport = async (options) => {
      const mergedOptions = {
        format: props.exportOptions.format || "pdf",
        quality: props.exportOptions.quality,
        filename: props.exportOptions.filename,
        paperSize: props.exportOptions.paperSize,
        orientation: props.exportOptions.orientation,
        scale: props.exportOptions.scale,
        margin: props.exportOptions.margin,
        ...options
      };
      emit("export-start", mergedOptions.format);
      try {
        const result = await exportChart(mergedOptions);
        if (result.success) {
          emit("export-success", result);
        } else {
          emit("export-error", result.error || "Unknown error");
        }
        return result;
      } catch (error) {
        const errorMessage = error instanceof Error ? error.message : "Unknown error";
        emit("export-error", errorMessage);
        return {
          success: false,
          data: null,
          error: errorMessage,
          filename: mergedOptions.filename || "export-error"
        };
      }
    };
    const selectedExportFormat = ref("");
    const triggerExport = async () => {
      if (!selectedExportFormat.value || isExporting.value) return;
      const options = {
        ...props.exportOptions,
        format: selectedExportFormat.value
      };
      try {
        const result = await handleExport(options);
        downloadExport(result);
        selectedExportFormat.value = "";
      } catch (error) {
        console.error("Error during export:", error);
      }
    };
    const rows = computed(() => rowManager.rows.value);
    const rowsContainerStyle = computed(() => {
      if (props.maxRows === 0) return {};
      return {
        "max-height": `${props.maxRows * props.rowHeight}px`,
        "overflow-y": "auto"
      };
    });
    const totalWidth = computed(() => {
      const lowerUnits = timeaxisUnits.value.result.lowerUnits;
      return lowerUnits.reduce((total, unit) => {
        return total + parseInt(unit.width);
      }, 0);
    });
    const hasGroupRows = computed(() => {
      const checkForGroups = (rows2) => {
        return rows2.some(
          (row) => {
            var _a;
            return ((_a = row.children) == null ? void 0 : _a.length) > 0 || row.children && checkForGroups(row.children);
          }
        );
      };
      return checkForGroups(rows.value);
    });
    const labelSectionStyle = computed(() => ({
      width: `${labelSectionWidth.value}px`,
      maxWidth: `${labelSectionWidth.value}px`,
      position: "relative",
      flexShrink: 0,
      flexGrow: 0
    }));
    const handleTimeaxisMouseDown = (e) => {
      isDraggingTimeaxis.value = true;
      lastMouseX.value = e.clientX;
    };
    const handleTimeaxisMouseMove = (e) => {
      if (!isDraggingTimeaxis.value || !ganttWrapper.value) return;
      const deltaX = e.clientX - lastMouseX.value;
      lastMouseX.value = e.clientX;
      ganttWrapper.value.scrollLeft -= deltaX;
      const maxScroll = ganttWrapper.value.scrollWidth - ganttWrapper.value.clientWidth;
      scrollPosition.value = ganttWrapper.value.scrollLeft / maxScroll * 100;
    };
    const handleTimeaxisMouseUp = () => {
      isDraggingTimeaxis.value = false;
    };
    const handleTimeaxisTouchStart = (e) => {
      const touch = e.touches[0];
      if (!touch) return;
      handleTimeaxisTouch.isDragging = true;
      handleTimeaxisTouch.startX = touch.clientX;
      e.preventDefault();
    };
    const handleTimeaxisTouchMove = (e) => {
      if (!handleTimeaxisTouch.isDragging || !ganttWrapper.value) return;
      const touch = e.touches[0];
      if (!touch) return;
      const deltaX = touch.clientX - handleTimeaxisTouch.startX;
      handleTimeaxisTouch.startX = touch.clientX;
      ganttWrapper.value.scrollLeft -= deltaX;
      const maxScroll = ganttWrapper.value.scrollWidth - ganttWrapper.value.clientWidth;
      scrollPosition.value = ganttWrapper.value.scrollLeft / maxScroll * 100;
      e.preventDefault();
    };
    const handleTimeaxisTouchEnd = () => {
      handleTimeaxisTouch.isDragging = false;
    };
    const handleSectionResize = (newWidth) => {
      labelSectionWidth.value = newWidth;
    };
    const emitBarEvent = (e, bar, datetime, movedBars) => {
      switch (e.type) {
        case "click":
          emit("click-bar", { bar, e, datetime });
          break;
        case "mousedown":
          emit("mousedown-bar", { bar, e, datetime });
          break;
        case "mouseup":
          emit("mouseup-bar", { bar, e, datetime });
          break;
        case "dblclick":
          emit("dblclick-bar", { bar, e, datetime });
          break;
        case "mouseenter":
          initTooltip(bar);
          emit("mouseenter-bar", { bar, e });
          break;
        case "mouseleave":
          clearTooltip();
          emit("mouseleave-bar", { bar, e });
          break;
        case "dragstart":
          isDragging.value = true;
          emit("dragstart-bar", { bar, e });
          updateBarPositions();
          break;
        case "drag":
          emit("drag-bar", { bar, e });
          updateBarPositions();
          break;
        case "dragend":
          isDragging.value = false;
          emit("dragend-bar", { bar, e, movedBars });
          updateBarPositions();
          rowManager.onBarMove();
          break;
        case "contextmenu":
          emit("contextmenu-bar", { bar, e, datetime });
          break;
        case "progress-drag-start":
          initTooltip(bar);
          emit("progress-drag-start", { bar, e });
          break;
        case "progress-change":
          initTooltip(bar);
          emit("progress-change", { bar, e });
          break;
        case "progress-drag-end":
          initTooltip(bar);
          emit("progress-drag-end", { bar, e });
          rowManager.onBarMove();
          break;
        case "label-edit":
          emit("label-edit", {
            bar,
            e,
            oldValue: bar.ganttBarConfig._previousLabel || "",
            newValue: bar.ganttBarConfig.label || ""
          });
          rowManager.onBarMove();
          break;
      }
    };
    const dropRow = (event) => {
      emit("row-drop", event);
      updateBarPositions();
    };
    const getColorScheme = (scheme) => typeof scheme !== "string" ? scheme : colorSchemes[scheme] || colorSchemes.default;
    watch(
      () => totalWidth.value,
      () => {
        ganttWidth.value = totalWidth.value;
      },
      { immediate: true }
    );
    const renderRow = (row) => {
      if (row._originalNode) {
        return h(
          _sfc_main$2,
          {
            ...row._originalNode.props,
            label: row.label,
            bars: row.bars,
            children: row.children,
            id: row.id,
            key: row.id || row.label
          },
          row._originalNode.children || {}
        );
      }
      return h(_sfc_main$2, {
        label: row.label,
        bars: row.bars,
        id: row.id,
        key: row.id || row.label
      });
    };
    const updateRangeBackground = () => {
      const parentElement = document.getElementById(id.value);
      const slider = parentElement.querySelector(".g-gantt-scroller");
      if (slider) {
        slider.style.setProperty("--value", `${scrollPosition.value}%`);
      }
    };
    const undo = () => {
      const changes = rowManager.undo();
      if (!changes) return;
      changes.rowChanges.forEach((rowChange) => {
        emit("row-drop", {
          sourceRow: rowChange.sourceRow,
          targetRow: void 0,
          newIndex: rowChange.newIndex,
          parentId: rowChange.newParentId
        });
      });
      changes.barChanges.forEach((barChange) => {
        const bar = findBarInRows(rowManager.rows.value, barChange.barId);
        if (!bar) return;
        emit("dragend-bar", {
          bar,
          e: new MouseEvent("mouseup"),
          movedBars: /* @__PURE__ */ new Map([
            [
              bar,
              {
                oldStart: barChange.newStart,
                oldEnd: barChange.newEnd
              }
            ]
          ])
        });
      });
      updateBarPositions();
    };
    const redo = () => {
      const changes = rowManager.redo();
      if (!changes) return;
      changes.rowChanges.forEach((rowChange) => {
        emit("row-drop", {
          sourceRow: rowChange.sourceRow,
          targetRow: void 0,
          newIndex: rowChange.newIndex,
          parentId: rowChange.newParentId
        });
      });
      changes.barChanges.forEach((barChange) => {
        const bar = findBarInRows(rowManager.rows.value, barChange.barId);
        if (!bar) return;
        emit("dragend-bar", {
          bar,
          e: new MouseEvent("mouseup"),
          movedBars: /* @__PURE__ */ new Map([
            [
              bar,
              {
                oldStart: barChange.oldStart,
                oldEnd: barChange.oldEnd
              }
            ]
          ])
        });
      });
      updateBarPositions();
    };
    const handleKeyboardShortcuts = (e) => {
      const isCtrlPressed = e.ctrlKey || e.metaKey;
      if (isCtrlPressed && e.code === "KeyZ") {
        e.preventDefault();
        if (e.shiftKey) {
          if (rowManager.canRedo.value) {
            redo();
          }
        } else {
          if (rowManager.canUndo.value) {
            undo();
          }
        }
      }
    };
    let resizeObserver;
    onMounted(() => {
      const cleanup = rowManager.onSortChange(updateBarPositions);
      const cleanupGroup = rowManager.onGroupExpansionChange(updateBarPositions);
      onUnmounted(cleanup);
      onUnmounted(cleanupGroup);
      if (ganttWrapper.value) {
        ganttWrapper.value.addEventListener("wheel", (e) => handleWheel(e, ganttWrapper.value));
      }
      window.addEventListener("mousemove", handleTimeaxisMouseMove);
      window.addEventListener("mouseup", handleTimeaxisMouseUp);
      window.addEventListener("mousemove", (e) => handleResizeMove(e, handleSectionResize));
      window.addEventListener("mouseup", handleResizeEnd);
      window.addEventListener("keydown", handleKeyboardShortcuts);
      resizeObserver = new ResizeObserver(updateBarPositions);
      const container = document.querySelector(".g-gantt-chart");
      if (container) {
        resizeObserver.observe(container);
      }
      window.addEventListener("resize", updateBarPositions);
      initializeConnections();
      nextTick(() => {
        updateBarPositions();
      });
      watch(scrollPosition, updateRangeBackground, { immediate: true });
    });
    onUnmounted(() => {
      if (ganttWrapper.value) {
        ganttWrapper.value.removeEventListener("wheel", (e) => handleWheel(e, ganttWrapper.value));
      }
      window.removeEventListener("mousemove", handleTimeaxisMouseMove);
      window.removeEventListener("mouseup", handleTimeaxisMouseUp);
      window.removeEventListener("mousemove", (e) => handleResizeMove(e, handleSectionResize));
      window.removeEventListener("mouseup", handleResizeEnd);
      window.removeEventListener("keydown", handleKeyboardShortcuts);
      if (resizeObserver) {
        resizeObserver.disconnect();
      }
      window.removeEventListener("resize", updateBarPositions);
    });
    watch([() => props.chartStart, () => props.chartEnd], () => {
      updateBarPositions();
    });
    provide(CONFIG_KEY, {
      ...toRefs(props),
      colors,
      chartSize
    });
    provide(EMIT_BAR_EVENT_KEY, emitBarEvent);
    provide(BOOLEAN_KEY, { ...props });
    provide(GANTT_ID_KEY, id.value);
    provide(CHART_AREA_KEY, ganttChart);
    provide(CHART_WRAPPER_KEY, ganttWrapper);
    __expose({
      exportChart,
      isExporting
    });
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", {
        class: "g-gantt-container",
        role: "application",
        "aria-label": "Interactive Gantt",
        tabindex: "0",
        onKeydown: _cache[19] || (_cache[19] = //@ts-ignore
        (...args) => unref(handleKeyDown) && unref(handleKeyDown)(...args)),
        onMousemove: handleChartMouseMove,
        onMouseup: handleChartMouseUp,
        ref_key: "ganttContainer",
        ref: ganttContainer,
        id: id.value
      }, [
        createElementVNode("div", {
          class: "g-gantt-rounded-wrapper",
          ref_key: "gGantt",
          ref: gGantt
        }, [
          createElementVNode("div", _hoisted_2, [
            _ctx.labelColumnTitle ? (openBlock(), createElementBlock("div", {
              key: 0,
              class: "g-gantt-label-section",
              style: normalizeStyle(labelSectionStyle.value)
            }, [
              createVNode(_sfc_main$b, {
                ref_key: "labelColumn",
                ref: labelColumn,
                onScroll: unref(handleLabelScroll),
                onRowDrop: dropRow
              }, createSlots({
                "label-column-title": withCtx(() => [
                  renderSlot(_ctx.$slots, "label-column-title")
                ]),
                "label-column-row": withCtx((slotProps) => [
                  renderSlot(_ctx.$slots, "label-column-row", normalizeProps(guardReactiveProps(slotProps)))
                ]),
                _: 2
              }, [
                renderList(_ctx.$slots, (_, name) => {
                  return {
                    name,
                    fn: withCtx((slotData) => [
                      renderSlot(_ctx.$slots, name, normalizeProps(guardReactiveProps(slotData)))
                    ])
                  };
                })
              ]), 1032, ["onScroll"]),
              createElementVNode("div", {
                class: "g-gantt-section-resizer",
                onMousedown: _cache[0] || (_cache[0] = (e) => unref(handleResizeStart)(e, labelSectionWidth.value)),
                onTouchstart: _cache[1] || (_cache[1] = (e) => unref(handleTouchStart)(e, labelSectionWidth.value)),
                onTouchmove: _cache[2] || (_cache[2] = (e) => unref(handleTouchMove)(e, handleSectionResize)),
                onTouchend: _cache[3] || (_cache[3] = //@ts-ignore
                (...args) => unref(resetResizeState) && unref(resetResizeState)(...args)),
                onTouchcancel: _cache[4] || (_cache[4] = //@ts-ignore
                (...args) => unref(resetResizeState) && unref(resetResizeState)(...args))
              }, null, 32)
            ], 4)) : createCommentVNode("", true),
            createElementVNode("div", {
              ref_key: "ganttWrapper",
              ref: ganttWrapper,
              class: "gantt-wrapper",
              style: normalizeStyle({
                width: "100%",
                "overflow-x": _ctx.commands ? "hidden" : "auto"
              })
            }, [
              createElementVNode("div", {
                ref_key: "ganttChart",
                ref: ganttChart,
                class: "g-gantt-chart",
                style: normalizeStyle({
                  width: `${totalWidth.value}px`,
                  background: colors.value.background,
                  fontFamily: unref(font)
                })
              }, [
                !_ctx.hideTimeaxis ? (openBlock(), createBlock(_sfc_main$8, {
                  key: 0,
                  ref_key: "timeaxisComponent",
                  ref: timeaxisComponent,
                  onDragStart: handleTimeaxisMouseDown,
                  onTouchstart: handleTimeaxisTouchStart,
                  onTouchmove: handleTimeaxisTouchMove,
                  onTouchend: handleTimeaxisTouchEnd,
                  onTouchcancel: handleTimeaxisTouchEnd,
                  timeaxisUnits: unref(timeaxisUnits),
                  internalPrecision: unref(internalPrecision)
                }, {
                  "upper-timeunit": withCtx((slotProps) => [
                    renderSlot(_ctx.$slots, "upper-timeunit", normalizeProps(guardReactiveProps(slotProps)))
                  ]),
                  timeunit: withCtx((slotProps) => [
                    renderSlot(_ctx.$slots, "timeunit", normalizeProps(guardReactiveProps(slotProps)))
                  ]),
                  _: 3
                }, 8, ["timeaxisUnits", "internalPrecision"])) : createCommentVNode("", true),
                _ctx.grid ? (openBlock(), createBlock(_sfc_main$c, {
                  key: 1,
                  timeaxisUnits: unref(timeaxisUnits),
                  internalPrecision: unref(internalPrecision)
                }, null, 8, ["timeaxisUnits", "internalPrecision"])) : createCommentVNode("", true),
                _ctx.currentTime ? (openBlock(), createBlock(_sfc_main$6, { key: 2 }, {
                  "current-time-label": withCtx(() => [
                    renderSlot(_ctx.$slots, "current-time-label")
                  ]),
                  _: 3
                })) : createCommentVNode("", true),
                _ctx.pointerMarker ? (openBlock(), createBlock(_sfc_main$1, { key: 3 }, {
                  "pointer-marker-tooltips": withCtx(({ hitBars, datetime }) => [
                    renderSlot(_ctx.$slots, "pointer-marker-tooltips", normalizeProps(guardReactiveProps({ hitBars, datetime })))
                  ]),
                  _: 3
                })) : createCommentVNode("", true),
                (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.milestones, (milestone) => {
                  return openBlock(), createBlock(_sfc_main$4, {
                    key: milestone.date.toString(),
                    milestone
                  }, createSlots({ _: 2 }, [
                    renderList(_ctx.$slots, (_, name) => {
                      return {
                        name,
                        fn: withCtx((slotData) => [
                          name.startsWith("milestone-") || name === "milestone" ? renderSlot(_ctx.$slots, name, mergeProps({
                            key: 0,
                            ref_for: true
                          }, slotData)) : createCommentVNode("", true)
                        ])
                      };
                    })
                  ]), 1032, ["milestone"]);
                }), 128)),
                createElementVNode("div", {
                  class: "g-gantt-rows-container",
                  style: normalizeStyle(rowsContainerStyle.value),
                  ref_key: "rowsContainer",
                  ref: rowsContainer,
                  onScroll: _cache[5] || (_cache[5] = //@ts-ignore
                  (...args) => unref(handleContentScroll) && unref(handleContentScroll)(...args))
                }, [
                  (openBlock(true), createElementBlock(Fragment, null, renderList(rows.value, (row) => {
                    return openBlock(), createBlock(resolveDynamicComponent(renderRow(row)), {
                      key: row.id || row.label
                    });
                  }), 128)),
                  unref(connectionState).isCreating && previewLinePoints.value ? (openBlock(), createElementBlock("svg", _hoisted_3, [
                    previewLinePoints.value ? (openBlock(), createBlock(GGanttConnector, {
                      key: 0,
                      "source-bar": {
                        id: unref(connectionState).sourceBar.ganttBarConfig.id,
                        x: previewLinePoints.value.x1,
                        y: previewLinePoints.value.y1,
                        width: 0,
                        height: 0
                      },
                      "target-bar": {
                        id: "preview",
                        x: previewLinePoints.value.x2,
                        y: previewLinePoints.value.y2,
                        width: 0,
                        height: 0
                      },
                      type: _ctx.defaultConnectionType,
                      color: _ctx.defaultConnectionColor,
                      pattern: _ctx.defaultConnectionPattern,
                      animated: _ctx.defaultConnectionAnimated,
                      "animation-speed": _ctx.defaultConnectionAnimationSpeed,
                      style: { opacity: 0.6 },
                      marker: _ctx.markerConnection
                    }, null, 8, ["source-bar", "target-bar", "type", "color", "pattern", "animated", "animation-speed", "marker"])) : createCommentVNode("", true)
                  ])) : createCommentVNode("", true),
                  _ctx.enableConnections ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(unref(connections), (conn) => {
                    return openBlock(), createElementBlock(Fragment, {
                      key: `${conn.sourceId}-${conn.targetId}`
                    }, [
                      unref(barPositions).get(conn.sourceId) && unref(barPositions).get(conn.targetId) ? (openBlock(), createBlock(GGanttConnector, mergeProps({
                        key: 0,
                        ref_for: true
                      }, unref(getConnectorProps)(conn), {
                        marker: _ctx.markerConnection,
                        onClick: ($event) => unref(handleConnectionClick)(conn)
                      }), null, 16, ["marker", "onClick"])) : createCommentVNode("", true)
                    ], 64);
                  }), 128)) : createCommentVNode("", true)
                ], 36)
              ], 4)
            ], 4)
          ]),
          _ctx.commands ? (openBlock(), createElementBlock("div", {
            key: 0,
            class: "g-gantt-command",
            style: normalizeStyle({ background: colors.value.commands, fontFamily: unref(font) }),
            "aria-label": "Gantt Commands"
          }, [
            renderSlot(_ctx.$slots, "commands", {
              zoomIn: () => unref(handleZoomUpdate)(true),
              zoomOut: () => unref(handleZoomUpdate)(false),
              scrollRowUp: () => unref(scrollRowUp)(),
              scrollRowDown: () => unref(scrollRowDown)(),
              expandAllGroups: () => unref(rowManager).expandAllGroups(),
              collapseAllGroups: () => unref(rowManager).collapseAllGroups(),
              handleToStart: () => unref(handleStep)(0, ganttWrapper.value),
              handleBack: () => unref(handleStep)(unref(scrollPosition) - 10, ganttWrapper.value),
              handleScroll: () => unref(handleScroll)(ganttWrapper.value),
              handleForward: () => unref(handleStep)(unref(scrollPosition) + 10, ganttWrapper.value),
              handleToEnd: () => unref(handleStep)(100, ganttWrapper.value),
              undo: () => undo(),
              redo: () => redo(),
              canUndo: unref(rowManager).canUndo,
              canRedo: unref(rowManager).canRedo,
              isAtTop: unref(isAtTop),
              isAtBottom: unref(isAtBottom),
              zoomLevel: unref(zoomLevel),
              export: () => triggerExport()
            }, () => [
              createElementVNode("div", _hoisted_4, [
                _ctx.maxRows > 0 ? (openBlock(), createElementBlock("div", _hoisted_5, [
                  createElementVNode("button", {
                    onClick: _cache[6] || (_cache[6] = //@ts-ignore
                    (...args) => unref(scrollRowUp) && unref(scrollRowUp)(...args)),
                    "aria-label": "Scroll row up",
                    disabled: unref(isAtTop)
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faAngleUp),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_6),
                  createElementVNode("button", {
                    onClick: _cache[7] || (_cache[7] = //@ts-ignore
                    (...args) => unref(scrollRowDown) && unref(scrollRowDown)(...args)),
                    "aria-label": "Scroll row down",
                    disabled: unref(isAtBottom)
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faAngleDown),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_7)
                ])) : createCommentVNode("", true),
                hasGroupRows.value ? (openBlock(), createElementBlock("div", _hoisted_8, [
                  createElementVNode("button", {
                    onClick: _cache[8] || (_cache[8] = ($event) => unref(rowManager).expandAllGroups()),
                    "aria-label": "Expand all groups",
                    disabled: unref(rowManager).areAllGroupsExpanded.value
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faExpandAlt),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_9),
                  createElementVNode("button", {
                    onClick: _cache[9] || (_cache[9] = ($event) => unref(rowManager).collapseAllGroups()),
                    "aria-label": "Collapse all groups",
                    disabled: unref(rowManager).areAllGroupsCollapsed.value
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faCompressAlt),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_10)
                ])) : createCommentVNode("", true)
              ]),
              createElementVNode("div", _hoisted_11, [
                createElementVNode("div", _hoisted_12, [
                  createElementVNode("button", {
                    disabled: unref(scrollPosition) === 0,
                    onClick: _cache[10] || (_cache[10] = ($event) => unref(handleStep)(0, ganttWrapper.value)),
                    "aria-label": "Scroll to start"
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faAnglesLeft),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_13),
                  createElementVNode("button", {
                    disabled: unref(scrollPosition) === 0,
                    onClick: _cache[11] || (_cache[11] = ($event) => unref(handleStep)(unref(scrollPosition) - 10, ganttWrapper.value)),
                    "aria-label": "Scroll back"
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faAngleLeft),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_14),
                  withDirectives(createElementVNode("input", {
                    "onUpdate:modelValue": _cache[12] || (_cache[12] = ($event) => isRef(scrollPosition) ? scrollPosition.value = $event : null),
                    type: "range",
                    min: "0",
                    max: "100",
                    class: "g-gantt-scroller",
                    style: normalizeStyle({ "--value": `${unref(scrollPosition)}%` }),
                    onInput: _cache[13] || (_cache[13] = ($event) => unref(handleScroll)(ganttWrapper.value)),
                    "aria-valuemin": 0,
                    "aria-valuemax": 100,
                    "aria-valuenow": unref(scrollPosition),
                    "aria-label": "Gantt scroll position"
                  }, null, 44, _hoisted_15), [
                    [vModelText, unref(scrollPosition)]
                  ]),
                  createElementVNode("button", {
                    disabled: unref(scrollPosition) === 100,
                    onClick: _cache[14] || (_cache[14] = ($event) => unref(handleStep)(unref(scrollPosition) + 10, ganttWrapper.value)),
                    "aria-label": "Scroll up"
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faAngleRight),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_16),
                  createElementVNode("button", {
                    disabled: unref(scrollPosition) === 100,
                    onClick: _cache[15] || (_cache[15] = ($event) => unref(handleStep)(100, ganttWrapper.value)),
                    "aria-label": "Scroll to end"
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faAnglesRight),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_17)
                ])
              ]),
              createElementVNode("div", _hoisted_18, [
                createElementVNode("div", _hoisted_19, [
                  createElementVNode("button", {
                    onClick: _cache[16] || (_cache[16] = () => unref(handleZoomUpdate)(false)),
                    "aria-label": "Zoom-out Gantt",
                    disabled: unref(zoomLevel) === 1 && unref(internalPrecision) === "month"
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faMagnifyingGlassMinus),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_20),
                  createElementVNode("button", {
                    onClick: _cache[17] || (_cache[17] = () => unref(handleZoomUpdate)(true)),
                    "aria-label": "Zoom-out Gantt",
                    disabled: unref(zoomLevel) === 10 && unref(internalPrecision) === _ctx.precision
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faMagnifyingGlassPlus),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_21)
                ]),
                createElementVNode("div", _hoisted_22, [
                  createElementVNode("button", {
                    onClick: undo,
                    disabled: !unref(rowManager).canUndo.value,
                    "aria-label": "Undo last action"
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faUndo),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_23),
                  createElementVNode("button", {
                    onClick: redo,
                    disabled: !unref(rowManager).canRedo.value,
                    "aria-label": "Redo action"
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faRedo),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_24)
                ])
              ]),
              createElementVNode("div", _hoisted_25, [
                _ctx.exportEnabled ? (openBlock(), createElementBlock("div", _hoisted_26, [
                  createElementVNode("div", _hoisted_27, [
                    withDirectives(createElementVNode("select", {
                      "onUpdate:modelValue": _cache[18] || (_cache[18] = ($event) => selectedExportFormat.value = $event),
                      class: "g-gantt-export-select",
                      disabled: unref(isExporting)
                    }, _cache[20] || (_cache[20] = [
                      createStaticVNode('<option value="" disabled>Export</option><option value="pdf">PDF</option><option value="png">PNG</option><option value="svg">SVG</option><option value="excel">Excel</option>', 5)
                    ]), 8, _hoisted_28), [
                      [vModelSelect, selectedExportFormat.value]
                    ]),
                    createElementVNode("button", {
                      onClick: triggerExport,
                      disabled: !selectedExportFormat.value || unref(isExporting)
                    }, [
                      createVNode(unref(FontAwesomeIcon), {
                        icon: unref(faFileExport),
                        class: "command-icon"
                      }, null, 8, ["icon"]),
                      unref(isExporting) ? (openBlock(), createElementBlock("span", _hoisted_30, [
                        createVNode(unref(FontAwesomeIcon), {
                          icon: unref(faSpinner),
                          class: "fa-spin"
                        }, null, 8, ["icon"])
                      ])) : createCommentVNode("", true)
                    ], 8, _hoisted_29)
                  ])
                ])) : createCommentVNode("", true)
              ])
            ])
          ], 4)) : createCommentVNode("", true)
        ], 512),
        createVNode(_sfc_main$7, {
          "model-value": unref(showTooltip) || isDragging.value,
          bar: unref(tooltipBar)
        }, {
          default: withCtx((slotProps) => [
            renderSlot(_ctx.$slots, "bar-tooltip", normalizeProps(guardReactiveProps(slotProps)))
          ]),
          _: 3
        }, 8, ["model-value", "bar"])
      ], 40, _hoisted_1);
    };
  }
});
function extendDayjs() {
  dayjs.extend(isSameOrBefore);
  dayjs.extend(isSameOrAfter);
  dayjs.extend(isBetween);
  dayjs.extend(customParseFormat);
  dayjs.extend(weekOfYear);
  dayjs.extend(isoWeek);
  dayjs.extend(advancedFormat);
  dayjs.extend(dayOfYear);
  dayjs.extend(localizedFormat);
  dayjs.extend(utc);
}
const hyvuegantt = {
  install(app) {
    extendDayjs();
    app.component("GGanttChart", _sfc_main);
    app.component("GGanttRow", _sfc_main$2);
  }
};
function injectStyle(css, insertAt = "top") {
  if (!css || typeof document === "undefined") return;
  const head = document.head || document.querySelector("head");
  const firstChild = head.querySelector(":first-child");
  const style = document.createElement("style");
  style.appendChild(document.createTextNode(css));
  if (insertAt === "top" && firstChild) {
    head.insertBefore(style, firstChild);
  } else {
    head.appendChild(style);
  }
}
injectStyle('\n.g-gantt-container {\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n}\n/* Layout */\n.g-gantt-chart {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  overflow-x: hidden;\n  -webkit-touch-callout: none;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n          user-select: none;\n  font-feature-settings: "tnum";\n  font-variant-numeric: tabular-nums;\n}\n\n/* Container Styles */\n.g-gantt-rows-container {\n  position: relative;\n  width: 100%;\n  height: 100%;\n  overflow: visible;\n  scrollbar-width: none;\n  -ms-overflow-style: none;\n}\n.labels-in-column {\n  display: flex;\n  flex-direction: row;\n}\n\n/* Command Section Styles */\n.g-gantt-command {\n  display: flex;\n  align-items: center;\n  height: 40px;\n  border-top: 1px solid #eaeaea;\n  padding: 0px 6px;\n  gap: 8px;\n}\n.g-gantt-command-block {\n  display: flex;\n  gap: 8px;\n}\n.g-gantt-command-fixed,\n.g-gantt-command-slider,\n.g-gantt-command-vertical,\n.g-gantt-command-zoom,\n.g-gantt-command-history,\n.g-gantt-command-groups,\n.g-gantt-export-container {\n  display: flex;\n  align-items: center;\n  gap: 2px;\n}\n.g-gantt-command-custom {\n  flex-grow: 1;\n}\n.g-gantt-command-vertical button:disabled,\n.g-gantt-command-slider button:disabled,\n.g-gantt-command-zoom button:disabled,\n.g-gantt-command-groups button:disabled,\n.g-gantt-command-history button:disabled,\n.g-gantt-export-container button:disabled {\n  opacity: 0.5;\n  cursor: not-allowed;\n}\n.g-gantt-export-select {\n  border-radius: 4px;\n  font-size: 0.75rem;\n  padding-left: 2px;\n  padding-right: 2px;\n  padding-top: 0;\n  padding-bottom: 0;\n  height: 22px;\n}\n.g-gantt-export-loading {\n  margin-left: 4px;\n}\n.g-gantt-export-menu button:hover {\n  background: #f5f5f5;\n}\n@media screen and (max-width: 768px) {\n.g-gantt-command {\n    height: auto;\n    min-height: 0;\n    min-height: initial;\n    flex-direction: column;\n    align-items: stretch;\n    padding: 12px 6px;\n    gap: 12px;\n}\n.g-gantt-command > * {\n    width: 100%;\n}\n.g-gantt-command-block {\n    display: flex;\n    justify-content: center;\n    gap: 20px;\n}\n.g-gantt-command-fixed {\n    flex-direction: column;\n    gap: 8px;\n}\n.g-gantt-command-groups {\n    justify-content: center;\n    margin-right: 0;\n}\n.g-gantt-command-slider {\n    width: 100%;\n    justify-content: center;\n}\n.g-gantt-command-vertical {\n    flex-direction: row;\n    justify-content: center;\n}\n.g-gantt-command-zoom,\n  .g-gantt-command-history {\n    justify-content: center;\n}\n.g-gantt-command-export {\n    display: flex;\n    align-items: center;\n}\n.command-icon {\n    padding: 8px;\n    width: 16px;\n    height: 16px;\n}\n.g-gantt-scroller {\n    height: 12px;\n}\n.g-gantt-scroller::-webkit-slider-thumb {\n    width: 24px;\n    height: 24px;\n}\n.g-gantt-scroller::-moz-range-thumb {\n    width: 24px;\n    height: 24px;\n}\n}\n\n/* Scroller Styles */\n.g-gantt-scroller {\n  -webkit-appearance: none;\n  height: 8px;\n  border-radius: 4px;\n  outline: none;\n  background: linear-gradient(\n    to right,\n    var(--170a1ade) var(--value),\n    #ddd var(--value)\n  );\n}\n\n/* Scroller Thumb Styles */\n.g-gantt-scroller::-webkit-slider-thumb {\n  -webkit-appearance: none;\n  appearance: none;\n  width: 16px;\n  height: 16px;\n  background: var(--170a1ade);\n  border-radius: 50%;\n  cursor: pointer;\n  border: none;\n}\n.g-gantt-scroller::-moz-range-thumb {\n  width: 16px;\n  height: 16px;\n  background: var(--170a1ade);\n  border-radius: 50%;\n  cursor: pointer;\n  border: none;\n}\n\n/* Track Styles */\n.g-gantt-scroller::-moz-range-track {\n  height: 8px;\n  background: #ddd;\n  border-radius: 4px;\n  border: none;\n}\n\n/* Hover States */\n.g-gantt-scroller::-webkit-slider-thumb:hover {\n  background: var(--170a1ade);\n}\n.g-gantt-scroller::-moz-range-thumb:hover {\n  background: var(--170a1ade);\n}\n\n/* Icon Styles */\n.command-icon {\n  background: var(--170a1ade);\n  padding: 4px;\n  margin: 2px;\n  width: 14px;\n  height: 14px;\n  border-radius: 4px;\n}\nbutton {\n  display: flex;\n}\n.g-gantt-chart:focus-within {\n  outline: 2px solid var(--1a0a3e0a);\n  outline-offset: 2px;\n}\n.g-gantt-rounded-wrapper {\n  border-radius: 5px;\n  overflow: hidden;\n  border: 1px solid #eaeaea;\n  background: white;\n  display: flex;\n  flex-direction: column;\n}\n.g-gantt-rows-container::-webkit-scrollbar {\n  display: none;\n}\n.g-gantt-main-layout {\n  display: flex;\n  width: 100%;\n  position: relative;\n}\n.g-gantt-label-section {\n  position: relative;\n  display: flex;\n}\n.g-gantt-section-resizer {\n  position: absolute;\n  right: -4px;\n  top: 0;\n  width: 8px;\n  height: 100%;\n  cursor: col-resize;\n  background: transparent;\n  z-index: 10;\n  transition: background 0.2s ease;\n}\n.g-gantt-section-resizer:hover {\n  background: rgba(0, 0, 0, 0.1);\n}\n.g-gantt-section-resizer:active {\n  background: rgba(0, 0, 0, 0.2);\n}\n@media (max-width: 768px) {\n.g-gantt-section-resizer {\n    width: 16px;\n    right: -8px;\n}\n}\n.connection-preview {\n  pointer-events: none;\n}\n\n.g-gantt-row {\n  width: 100%;\n  transition: background 0.4s;\n  position: relative;\n}\n\n/*.g-gantt-row:last-child {\n  border-bottom: 0px !important;\n}*/\n.g-gantt-row > .g-gantt-row-bars-container {\n  position: relative;\n  width: 100%;\n}\n.g-gantt-row-label {\n  position: absolute;\n  top: 0;\n  left: 0px;\n  padding: 0px 8px;\n  display: flex;\n  align-items: center;\n  height: 60%;\n  min-height: 20px;\n  font-size: 0.8em;\n  font-weight: bold;\n  border-bottom-right-radius: 6px;\n  background: #f2f2f2;\n  z-index: 3;\n  box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.6);\n}\n.g-gantt-row-group-label {\n  font-weight: bold;\n  background: #e0e0e0 !important;\n}\n.g-gantt-row-children {\n  transition: max-height 0.3s ease-in-out;\n}\n.bar-transition-leave-active,\n.bar-transition-enter-active {\n  transition: all 0.2s;\n}\n.bar-transition-enter-from,\n.bar-transition-leave-to {\n  transform: scale(0.8);\n  opacity: 0;\n}\n\n.g-gantt-bar {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  background: cadetblue;\n  overflow: visible;\n  position: relative;\n}\n.g-gantt-bar-label {\n  width: 100%;\n  height: 100%;\n  box-sizing: border-box;\n  padding: 0 14px 0 14px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  position: relative;\n  z-index: 2;\n  pointer-events: none;\n}\n.g-gantt-bar-label > * {\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n.g-gantt-bar-handle-left,\n.g-gantt-bar-handle-right {\n  position: absolute;\n  width: 10px;\n  height: 100%;\n  background: white;\n  opacity: 0.7;\n  border-radius: 0px;\n  cursor: ew-resize;\n  top: 0;\n}\n.g-gantt-bar-handle-left {\n  left: 0;\n}\n.g-gantt-bar-handle-right {\n  right: 0;\n}\n.g-gantt-bar-label img {\n  pointer-events: none;\n}\n.g-gantt-bar-label-edit {\n  width: 100%;\n  height: 100%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  pointer-events: all;\n}\n.g-gantt-bar-label-input {\n  background: rgba(255, 255, 255, 0.2);\n  border-radius: 4px;\n  width: 100%;\n  height: 100%;\n  background: white;\n  color: black;\n  outline: none;\n  font: inherit;\n  padding: 2px;\n  text-align: center;\n}\n.is-group-bar {\n  background: transparent !important;\n}\n.group-bar-decoration {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n}\n.g-gantt-progress-bar {\n  position: absolute;\n  pointer-events: none;\n  overflow: hidden;\n  min-width: 8px;\n  display: flex;\n  align-items: center;\n  justify-content: flex-end;\n  padding-right: 10px;\n  color: #fff;\n  font-size: 0.8em;\n  font-weight: 500;\n  z-index: 1;\n}\n.g-gantt-progress-handle {\n  position: absolute;\n  top: 0;\n  width: 8px;\n  height: 100%;\n  background-color: rgba(0, 0, 0, 0.3);\n  cursor: ew-resize;\n  pointer-events: all;\n  transition: background-color 0.2s ease;\n  z-index: 3;\n}\n.g-gantt-progress-handle:hover {\n  background-color: rgba(0, 0, 0, 0.5);\n}\n.g-gantt-progress-handle:active {\n  background-color: rgba(0, 0, 0, 0.7);\n}\n.connection-point {\n  z-index: 10;\n}\n.connection-point:hover {\n  transform: translate(-50%, -50%) scale(1.2);\n}\n.connection-point.end:hover {\n  transform: translate(50%, -50%) scale(1.2);\n}\n\n.g-label-column {\n  display: flex;\n  flex-direction: column;\n  color: rgb(64, 64, 64);\n  font-feature-settings: "tnum";\n  font-variant-numeric: tabular-nums;\n  font-size: 0.9em;\n  background: white;\n  box-sizing: border-box;\n  flex-shrink: 0;\n}\n.g-label-column-header {\n  width: 100%;\n  height: 80px;\n  min-height: 80px;\n  overflow: visible;\n  display: flex;\n  align-items: center;\n  overflow: visible;\n}\n.g-label-column-row-inner {\n  display: flex;\n  width: 100%;\n  min-width: 100%;\n  flex-wrap: nowrap;\n  align-items: center;\n}\n.g-label-column-header-cell {\n  flex: none;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: 0 0.5rem;\n  height: 100%;\n  gap: 0.5rem;\n  box-sizing: border-box;\n  position: relative;\n  overflow: visible;\n  text-align: center;\n}\n.g-label-column-cell {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: 0.1rem 0.3rem;\n  box-sizing: border-box;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  flex: none;\n}\n.header-content {\n  width: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  gap: 0.5rem;\n  padding: 0 4px;\n}\n.cell-content {\n  display: flex;\n  align-items: center;\n  width: 100%;\n  gap: 4px;\n}\n.text-ellipsis {\n  flex: 1;\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n.text-ellipsis-value {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n.g-label-column-header-cell.sortable {\n  cursor: pointer;\n  transition: background-color 0.2s ease;\n}\n.g-label-column-header-cell.sortable:hover {\n  background-color: rgba(0, 0, 0, 0.1);\n}\n.g-label-column-rows {\n  width: 100%;\n  overflow-y: auto;\n  overflow-x: hidden;\n}\n.g-label-column-rows::-webkit-scrollbar {\n  display: none;\n}\n.g-label-column-row {\n  width: 100%;\n  display: flex;\n  box-sizing: border-box;\n  align-items: center;\n  flex-wrap: nowrap;\n}\n\n/*.g-label-column-row:last-child {\n  border-bottom: 0px !important;\n}*/\n.sort-icon {\n  display: inline-flex;\n  align-items: center;\n  opacity: 0.6;\n  font-size: 0.8em;\n  transition: opacity 0.2s ease;\n}\n.sortable:hover .sort-icon {\n  opacity: 1;\n}\n.column-resizer {\n  position: absolute;\n  right: -1px;\n  top: 0;\n  width: 8px;\n  height: 100%;\n  cursor: col-resize;\n  z-index: 1;\n  background: transparent;\n}\n.column-resizer:hover,\n.column-resizer.is-dragging,\n.column-resizer.is-touch-resizing {\n  background: rgba(0, 0, 0, 0.1);\n}\n.g-label-column-header-cell:has(.column-resizer.is-touch-resizing) {\n  background-color: rgba(0, 0, 0, 0.05);\n}\n@media (max-width: 768px) {\n.column-resizer {\n    width: 16px;\n}\n}\n.g-label-column {\n  -webkit-user-select: none;\n     -moz-user-select: none;\n          user-select: none;\n}\n.g-label-column.dragging {\n  cursor: col-resize;\n}\n.g-label-column-group {\n  font-weight: 600;\n  background-color: rgba(0, 0, 0, 0.03);\n}\n.group-toggle-button {\n  flex: 0 0 20px;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  width: 20px;\n  height: 20px;\n  padding: 0;\n  border: none;\n  background: transparent;\n  cursor: pointer;\n  transition: transform 0.2s ease;\n}\n.group-toggle-button:hover {\n  background-color: rgba(0, 0, 0, 0.05);\n  border-radius: 4px;\n}\n.group-icon {\n  width: 12px;\n  height: 12px;\n  transition: transform 0.2s ease;\n}\n.group-label {\n  font-weight: 600;\n}\n.g-label-column-row-draggable {\n  cursor: move;\n}\n.g-label-column-row-dragging {\n  opacity: 0.5;\n  background: #f0f0f0 !important;\n  background: var(--dragging-background, #f0f0f0) !important;\n}\n.g-label-column-row-drop-target {\n  position: relative;\n}\n.g-label-column-row-drop-before::before,\n.g-label-column-row-drop-after::after {\n  content: "";\n  position: absolute;\n  left: 0;\n  right: 0;\n  height: 2px;\n  background: #4a9eff;\n  background: var(--drop-indicator-color, #4a9eff);\n  z-index: 1;\n}\n.g-label-column-row-drop-before::before {\n  top: 0;\n}\n.g-label-column-row-drop-after::after {\n  bottom: 0;\n}\n.g-label-column-row-drop-child {\n  background: rgba(74, 158, 255, 0.1) !important;\n  background: var(--drop-child-background, rgba(74, 158, 255, 0.1)) !important;\n}\n.is-touch-dragging {\n  opacity: 0.8;\n  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n  pointer-events: none;\n}\n@media (max-width: 768px) {\n.group-toggle-button {\n    padding: 12px;\n}\n}\n.g-label-column-header-cell-ex {\n  position: relative;\n  flex-grow: 1;\n}\n\n.g-grid-container {\n  position: absolute;\n  top: 0;\n  left: 0%;\n  width: 100%;\n  height: 100%;\n  display: flex;\n  justify-content: space-between;\n}\n.g-grid-line {\n  width: 1px;\n  height: 100%;\n}\n.g-grid-line:first-child {\n  border-left: 0px !important;\n}\n\n.g-timeaxis {\n  position: sticky;\n  top: 0;\n  width: 100%;\n  height: 80px;\n  background: white;\n  z-index: 4;\n  display: flex;\n  flex-direction: column;\n  cursor: grab;\n}\n.g-timeaxis:active {\n  cursor: grabbing;\n}\n.g-timeunits-container {\n  display: flex;\n  width: 100%;\n  height: 50%;\n}\n.g-timeunit {\n  height: 100%;\n  font-size: 65%;\n  display: flex;\n  justify-content: center;\n}\n.g-upper-timeunit {\n  display: flex;\n  height: 100%;\n  justify-content: center;\n  align-items: center;\n}\n.g-timeaxis-hour-pin {\n  width: 1px;\n  height: 10px;\n}\n.label-unit {\n  flex-grow: 1;\n  text-align: center;\n  line-height: normal;\n}\n.g-timeunit-min {\n  display: flex;\n  flex-direction: row-reverse;\n  align-items: center;\n  width: 100%;\n  line-height: 20px;\n}\n.g-timeunit-step {\n  display: flex;\n  width: 100%;\n  line-height: 20px;\n}\n.g-events-container {\n  display: flex;\n  width: 100%;\n  position: relative;\n  overflow: hidden;\n  height: 100%;\n}\n.g-timeaxis-event {\n  height: 100%;\n  position: absolute;\n  font-size: 65%;\n  padding: 0 6px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  border: 1px solid;\n  box-sizing: border-box;\n  cursor: pointer;\n  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n  transition: box-shadow 0.2s ease;\n}\n.g-timeaxis-event:hover {\n  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n  z-index: 5;\n}\n\n.g-gantt-tooltip {\n  position: fixed;\n  background: black;\n  color: white;\n  z-index: 4;\n  font-size: 0.85em;\n  padding: 5px;\n  border-radius: 3px;\n  transition: opacity 0.2s;\n  display: flex;\n  align-items: center;\n  font-feature-settings: "tnum";\n  font-variant-numeric: tabular-nums;\n}\n.g-gantt-tooltip:before {\n  content: "";\n  position: absolute;\n  top: 0;\n  left: 10%;\n  width: 0;\n  height: 0;\n  border: 10px solid transparent;\n  border-bottom-color: black;\n  border-top: 0;\n  margin-left: -5px;\n  margin-top: -5px;\n}\n.g-gantt-tooltip-color-dot {\n  width: 8px;\n  height: 8px;\n  border-radius: 100%;\n  margin-right: 4px;\n}\n.g-fade-enter-active,\n.g-fade-leave-active {\n  transition: opacity 0.3s ease;\n}\n.g-fade-enter-from,\n.g-fade-leave-to {\n  opacity: 0;\n}\n\n.g-grid-current-time {\n  position: absolute;\n  height: 100%;\n  display: flex;\n  z-index: 5;\n  pointer-events: none;\n}\n.g-grid-current-time-marker {\n  width: 0px;\n  height: calc(100% - 2px);\n  display: flex;\n}\n.g-grid-current-time-text {\n  font-size: x-small;\n}\n\n.gantt-connector[data-v-a658cc88] {\n  overflow: visible;\n  pointer-events: none;\n}\n.connector-path[data-v-a658cc88] {\n  transition: d 0.3s ease;\n}\n.connector-path.selected[data-v-a658cc88] {\n  filter: drop-shadow(0 0 5px rgba(33, 150, 243, 0.6));\n}\n\n/* Animation for dash pattern */\n.connector-animated-dash-slow[data-v-a658cc88] {\n  animation: dashFlow-a658cc88 4s linear infinite;\n}\n.connector-animated-dash-normal[data-v-a658cc88] {\n  animation: dashFlow-a658cc88 2s linear infinite;\n}\n.connector-animated-dash-fast[data-v-a658cc88] {\n  animation: dashFlow-a658cc88 1s linear infinite;\n}\n\n/* Animation for dot pattern */\n.connector-animated-dot-slow[data-v-a658cc88] {\n  animation: dotFlow-a658cc88 4s linear infinite;\n}\n.connector-animated-dot-normal[data-v-a658cc88] {\n  animation: dotFlow-a658cc88 2s linear infinite;\n}\n.connector-animated-dot-fast[data-v-a658cc88] {\n  animation: dotFlow-a658cc88 1s linear infinite;\n}\n\n/* Animation for dashdot pattern */\n.connector-animated-dashdot-slow[data-v-a658cc88] {\n  animation: dashdotFlow-a658cc88 4s linear infinite;\n}\n.connector-animated-dashdot-normal[data-v-a658cc88] {\n  animation: dashdotFlow-a658cc88 2s linear infinite;\n}\n.connector-animated-dashdot-fast[data-v-a658cc88] {\n  animation: dashdotFlow-a658cc88 1s linear infinite;\n}\n.connector-path[data-v-a658cc88] {\n  marker-start: none;\n  transition:\n    d 0.3s ease, marker-start 0.3s ease;\n}\n.connection-endpoint[data-v-a658cc88] {\n  filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.3));\n  transition: all 0.3s ease;\n  border: 1px solid black;\n  border-radius: 100%;\n}\n.connection-endpoint[data-v-a658cc88]:hover {\n  r: 8;\n}\n@keyframes dashFlow-a658cc88 {\n0% {\n    stroke-dasharray: 10, 10;\n    stroke-dashoffset: 0;\n}\n100% {\n    stroke-dasharray: 10, 10;\n    stroke-dashoffset: -20;\n}\n}\n@keyframes dotFlow-a658cc88 {\n0% {\n    stroke-dasharray: 2, 8;\n    stroke-dashoffset: 0;\n}\n100% {\n    stroke-dasharray: 2, 8;\n    stroke-dashoffset: -10;\n}\n}\n@keyframes dashdotFlow-a658cc88 {\n0% {\n    stroke-dasharray: 12, 6, 3, 6;\n    stroke-dashoffset: 0;\n}\n100% {\n    stroke-dasharray: 12, 6, 3, 6;\n    stroke-dashoffset: -27;\n}\n}\n\n.g-gantt-milestone {\n  position: absolute;\n  height: 100%;\n  display: flex;\n  z-index: 5;\n  pointer-events: auto;\n  flex-direction: column;\n  align-items: center;\n}\n.g-gantt-milestone-marker {\n  width: 0px;\n  height: calc(100% - 30px);\n  display: flex;\n  margin-top: 25px;\n}\n.g-gantt-milestone-label {\n  padding: 2px 8px;\n  border-radius: 4px;\n  font-size: 0.8em;\n  white-space: nowrap;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n  position: absolute;\n  top: 4px;\n  transform: translateY(0);\n}\n.g-gantt-milestone-tooltip {\n  position: fixed;\n  padding: 8px;\n  border-radius: 4px;\n  font-size: 0.75em;\n  z-index: 1000;\n  min-width: 200px;\n  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n  transform: translateY(-100%);\n}\n.g-gantt-milestone-tooltip-title {\n  font-weight: bold;\n}\n.g-gantt-milestone-tooltip-date {\n  font-size: 0.9em;\n  opacity: 0.8;\n}\n.g-gantt-milestone-tooltip-description {\n  font-size: 0.9em;\n  line-height: 1.4;\n}\n.g-fade-enter-active,\n.g-fade-leave-active {\n  transition: opacity 0.3s ease;\n}\n.g-fade-enter-from,\n.g-fade-leave-to {\n  opacity: 0;\n}\n\n.g-grid-pointer-marker-container {\n  position: absolute;\n  height: 100%;\n  display: flex;\n  z-index: 5;\n  pointer-events: none;\n}\n.g-grid-pointer-marker-tooltip {\n  position: fixed;\n  padding: 8px;\n  border-radius: 4px;\n  font-size: 0.75em;\n  z-index: 1000;\n  min-width: 200px;\n  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n}\n.g-grid-pointer-marker-tooltip-content {\n  padding: 8px;\n}\n.g-grid-pointer-marker-marker {\n  width: 0px;\n  height: calc(100% - 2px);\n  display: flex;\n}\n.g-grid-pointer-marker-text {\n  font-size: x-small;\n}\n\n.g-gantt-holiday-tooltip {\n  position: fixed;\n  background: rgba(0, 0, 0, 0.8);\n  color: white;\n  padding: 4px 8px;\n  border-radius: 4px;\n  font-size: 12px;\n  z-index: 1000;\n  transform: translateX(-50%);\n  white-space: nowrap;\n}\n.g-gantt-holiday-tooltip:after {\n  content: "";\n  position: absolute;\n  bottom: -5px;\n  left: 50%;\n  transform: translateX(-50%);\n  width: 0;\n  height: 0;\n  border-left: 5px solid transparent;\n  border-right: 5px solid transparent;\n  border-top: 5px solid rgba(0, 0, 0, 0.8);\n}\n.g-fade-enter-active,\n.g-fade-leave-active {\n  transition: opacity 0.2s ease;\n}\n.g-fade-enter-from,\n.g-fade-leave-to {\n  opacity: 0;\n}\n\n.g-gantt-event-tooltip {\n  position: fixed;\n  z-index: 1000;\n  min-width: 180px;\n  max-width: 280px;\n  border-radius: 4px;\n  padding: 8px 12px;\n  font-size: 12px;\n  transform: translateX(-50%);\n  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n  pointer-events: none;\n}\n.g-gantt-event-tooltip:after {\n  content: "";\n  position: absolute;\n  bottom: -6px;\n  left: 50%;\n  transform: translateX(-50%);\n  width: 0;\n  height: 0;\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-top: 6px solid #2a2f42;\n  border-top: 6px solid var(--tooltip-background, #2a2f42);\n}\n.g-gantt-event-tooltip-title {\n  font-weight: bold;\n  margin-bottom: 4px;\n}\n.g-gantt-event-tooltip-time {\n  font-size: 11px;\n  opacity: 0.9;\n  margin-bottom: 4px;\n}\n.g-gantt-event-tooltip-description {\n  font-size: 11px;\n  line-height: 1.4;\n  opacity: 0.9;\n  margin-top: 4px;\n  white-space: normal;\n  word-break: break-word;\n}\n.g-fade-enter-active,\n.g-fade-leave-active {\n  transition: opacity 0.2s ease;\n}\n.g-fade-enter-from,\n.g-fade-leave-to {\n  opacity: 0;\n}\n', "top");
export {
  _sfc_main as GGanttChart,
  _sfc_main$2 as GGanttRow,
  hyvuegantt as default,
  extendDayjs,
  hyvuegantt
};