{"version":3,"file":"frappe-gantt.mjs","sources":["../src/date_utils.js","../src/svg_utils.js","../src/bar.js","../src/arrow.js","../src/popup.js","../src/index.js"],"sourcesContent":["const YEAR = 'year';\nconst MONTH = 'month';\nconst DAY = 'day';\nconst HOUR = 'hour';\nconst MINUTE = 'minute';\nconst SECOND = 'second';\nconst MILLISECOND = 'millisecond';\n\nconst month_names = {\n    en: [\n        'January',\n        'February',\n        'March',\n        'April',\n        'May',\n        'June',\n        'July',\n        'August',\n        'September',\n        'October',\n        'November',\n        'December',\n    ],\n    es: [\n        'Enero',\n        'Febrero',\n        'Marzo',\n        'Abril',\n        'Mayo',\n        'Junio',\n        'Julio',\n        'Agosto',\n        'Septiembre',\n        'Octubre',\n        'Noviembre',\n        'Diciembre',\n    ],\n    ru: [\n        'Январь',\n        'Февраль',\n        'Март',\n        'Апрель',\n        'Май',\n        'Июнь',\n        'Июль',\n        'Август',\n        'Сентябрь',\n        'Октябрь',\n        'Ноябрь',\n        'Декабрь',\n    ],\n    ptBr: [\n        'Janeiro',\n        'Fevereiro',\n        'Março',\n        'Abril',\n        'Maio',\n        'Junho',\n        'Julho',\n        'Agosto',\n        'Setembro',\n        'Outubro',\n        'Novembro',\n        'Dezembro',\n    ],\n    fr: [\n        'Janvier',\n        'Février',\n        'Mars',\n        'Avril',\n        'Mai',\n        'Juin',\n        'Juillet',\n        'Août',\n        'Septembre',\n        'Octobre',\n        'Novembre',\n        'Décembre',\n    ],\n    tr: [\n        'Ocak',\n        'Şubat',\n        'Mart',\n        'Nisan',\n        'Mayıs',\n        'Haziran',\n        'Temmuz',\n        'Ağustos',\n        'Eylül',\n        'Ekim',\n        'Kasım',\n        'Aralık',\n    ],\n    zh: [\n        '一月',\n        '二月',\n        '三月',\n        '四月',\n        '五月',\n        '六月',\n        '七月',\n        '八月',\n        '九月',\n        '十月',\n        '十一月',\n        '十二月',\n    ],\n};\n\nexport default {\n    parse(date, date_separator = '-', time_separator = /[.:]/) {\n        if (date instanceof Date) {\n            return date;\n        }\n        if (typeof date === 'string') {\n            let date_parts, time_parts;\n            const parts = date.split(' ');\n\n            date_parts = parts[0]\n                .split(date_separator)\n                .map((val) => parseInt(val, 10));\n            time_parts = parts[1] && parts[1].split(time_separator);\n\n            // month is 0 indexed\n            date_parts[1] = date_parts[1] - 1;\n\n            let vals = date_parts;\n\n            if (time_parts && time_parts.length) {\n                if (time_parts.length == 4) {\n                    time_parts[3] = '0.' + time_parts[3];\n                    time_parts[3] = parseFloat(time_parts[3]) * 1000;\n                }\n                vals = vals.concat(time_parts);\n            }\n\n            return new Date(...vals);\n        }\n    },\n\n    to_string(date, with_time = false) {\n        if (!(date instanceof Date)) {\n            throw new TypeError('Invalid argument type');\n        }\n        const vals = this.get_date_values(date).map((val, i) => {\n            if (i === 1) {\n                // add 1 for month\n                val = val + 1;\n            }\n\n            if (i === 6) {\n                return padStart(val + '', 3, '0');\n            }\n\n            return padStart(val + '', 2, '0');\n        });\n        const date_string = `${vals[0]}-${vals[1]}-${vals[2]}`;\n        const time_string = `${vals[3]}:${vals[4]}:${vals[5]}.${vals[6]}`;\n\n        return date_string + (with_time ? ' ' + time_string : '');\n    },\n\n    format(date, format_string = 'YYYY-MM-DD HH:mm:ss.SSS', lang = 'en') {\n        const values = this.get_date_values(date).map((d) => padStart(d, 2, 0));\n        const format_map = {\n            YYYY: values[0],\n            MM: padStart(+values[1] + 1, 2, 0),\n            DD: values[2],\n            HH: values[3],\n            mm: values[4],\n            ss: values[5],\n            SSS: values[6],\n            D: values[2],\n            MMMM: month_names[lang][+values[1]],\n            MMM: month_names[lang][+values[1]],\n        };\n\n        let str = format_string;\n        const formatted_values = [];\n\n        Object.keys(format_map)\n            .sort((a, b) => b.length - a.length) // big string first\n            .forEach((key) => {\n                if (str.includes(key)) {\n                    str = str.replace(key, `$${formatted_values.length}`);\n                    formatted_values.push(format_map[key]);\n                }\n            });\n\n        formatted_values.forEach((value, i) => {\n            str = str.replace(`$${i}`, value);\n        });\n\n        return str;\n    },\n\n    diff(date_a, date_b, scale = DAY) {\n        let milliseconds, seconds, hours, minutes, days, months, years;\n\n        milliseconds = date_a - date_b;\n        seconds = milliseconds / 1000;\n        minutes = seconds / 60;\n        hours = minutes / 60;\n        days = hours / 24;\n        months = days / 30;\n        years = months / 12;\n\n        if (!scale.endsWith('s')) {\n            scale += 's';\n        }\n\n        return Math.floor(\n            {\n                milliseconds,\n                seconds,\n                minutes,\n                hours,\n                days,\n                months,\n                years,\n            }[scale]\n        );\n    },\n\n    today() {\n        const vals = this.get_date_values(new Date()).slice(0, 3);\n        return new Date(...vals);\n    },\n\n    now() {\n        return new Date();\n    },\n\n    add(date, qty, scale) {\n        qty = parseInt(qty, 10);\n        const vals = [\n            date.getFullYear() + (scale === YEAR ? qty : 0),\n            date.getMonth() + (scale === MONTH ? qty : 0),\n            date.getDate() + (scale === DAY ? qty : 0),\n            date.getHours() + (scale === HOUR ? qty : 0),\n            date.getMinutes() + (scale === MINUTE ? qty : 0),\n            date.getSeconds() + (scale === SECOND ? qty : 0),\n            date.getMilliseconds() + (scale === MILLISECOND ? qty : 0),\n        ];\n        return new Date(...vals);\n    },\n\n    start_of(date, scale) {\n        const scores = {\n            [YEAR]: 6,\n            [MONTH]: 5,\n            [DAY]: 4,\n            [HOUR]: 3,\n            [MINUTE]: 2,\n            [SECOND]: 1,\n            [MILLISECOND]: 0,\n        };\n\n        function should_reset(_scale) {\n            const max_score = scores[scale];\n            return scores[_scale] <= max_score;\n        }\n\n        const vals = [\n            date.getFullYear(),\n            should_reset(YEAR) ? 0 : date.getMonth(),\n            should_reset(MONTH) ? 1 : date.getDate(),\n            should_reset(DAY) ? 0 : date.getHours(),\n            should_reset(HOUR) ? 0 : date.getMinutes(),\n            should_reset(MINUTE) ? 0 : date.getSeconds(),\n            should_reset(SECOND) ? 0 : date.getMilliseconds(),\n        ];\n\n        return new Date(...vals);\n    },\n\n    clone(date) {\n        return new Date(...this.get_date_values(date));\n    },\n\n    get_date_values(date) {\n        return [\n            date.getFullYear(),\n            date.getMonth(),\n            date.getDate(),\n            date.getHours(),\n            date.getMinutes(),\n            date.getSeconds(),\n            date.getMilliseconds(),\n        ];\n    },\n\n    get_days_in_month(date) {\n        const no_of_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n        const month = date.getMonth();\n\n        if (month !== 1) {\n            return no_of_days[month];\n        }\n\n        // Feb\n        const year = date.getFullYear();\n        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {\n            return 29;\n        }\n        return 28;\n    },\n};\n\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart\nfunction padStart(str, targetLength, padString) {\n    str = str + '';\n    targetLength = targetLength >> 0;\n    padString = String(typeof padString !== 'undefined' ? padString : ' ');\n    if (str.length > targetLength) {\n        return String(str);\n    } else {\n        targetLength = targetLength - str.length;\n        if (targetLength > padString.length) {\n            padString += padString.repeat(targetLength / padString.length);\n        }\n        return padString.slice(0, targetLength) + String(str);\n    }\n}\n","export function $(expr, con) {\n    return typeof expr === 'string'\n        ? (con || document).querySelector(expr)\n        : expr || null;\n}\n\nexport function createSVG(tag, attrs) {\n    const elem = document.createElementNS('http://www.w3.org/2000/svg', tag);\n    for (let attr in attrs) {\n        if (attr === 'append_to') {\n            const parent = attrs.append_to;\n            parent.appendChild(elem);\n        } else if (attr === 'innerHTML') {\n            elem.innerHTML = attrs.innerHTML;\n        } else {\n            elem.setAttribute(attr, attrs[attr]);\n        }\n    }\n    return elem;\n}\n\nexport function animateSVG(svgElement, attr, from, to) {\n    const animatedSvgElement = getAnimationElement(svgElement, attr, from, to);\n\n    if (animatedSvgElement === svgElement) {\n        // triggered 2nd time programmatically\n        // trigger artificial click event\n        const event = document.createEvent('HTMLEvents');\n        event.initEvent('click', true, true);\n        event.eventName = 'click';\n        animatedSvgElement.dispatchEvent(event);\n    }\n}\n\nfunction getAnimationElement(\n    svgElement,\n    attr,\n    from,\n    to,\n    dur = '0.4s',\n    begin = '0.1s'\n) {\n    const animEl = svgElement.querySelector('animate');\n    if (animEl) {\n        $.attr(animEl, {\n            attributeName: attr,\n            from,\n            to,\n            dur,\n            begin: 'click + ' + begin, // artificial click\n        });\n        return svgElement;\n    }\n\n    const animateElement = createSVG('animate', {\n        attributeName: attr,\n        from,\n        to,\n        dur,\n        begin,\n        calcMode: 'spline',\n        values: from + ';' + to,\n        keyTimes: '0; 1',\n        keySplines: cubic_bezier('ease-out'),\n    });\n    svgElement.appendChild(animateElement);\n\n    return svgElement;\n}\n\nfunction cubic_bezier(name) {\n    return {\n        ease: '.25 .1 .25 1',\n        linear: '0 0 1 1',\n        'ease-in': '.42 0 1 1',\n        'ease-out': '0 0 .58 1',\n        'ease-in-out': '.42 0 .58 1',\n    }[name];\n}\n\n$.on = (element, event, selector, callback) => {\n    if (!callback) {\n        callback = selector;\n        $.bind(element, event, callback);\n    } else {\n        $.delegate(element, event, selector, callback);\n    }\n};\n\n$.off = (element, event, handler) => {\n    element.removeEventListener(event, handler);\n};\n\n$.bind = (element, event, callback) => {\n    event.split(/\\s+/).forEach(function (event) {\n        element.addEventListener(event, callback);\n    });\n};\n\n$.delegate = (element, event, selector, callback) => {\n    element.addEventListener(event, function (e) {\n        const delegatedTarget = e.target.closest(selector);\n        if (delegatedTarget) {\n            e.delegatedTarget = delegatedTarget;\n            callback.call(this, e, delegatedTarget);\n        }\n    });\n};\n\n$.closest = (selector, element) => {\n    if (!element) return null;\n\n    if (element.matches(selector)) {\n        return element;\n    }\n\n    return $.closest(selector, element.parentNode);\n};\n\n$.attr = (element, attr, value) => {\n    if (!value && typeof attr === 'string') {\n        return element.getAttribute(attr);\n    }\n\n    if (typeof attr === 'object') {\n        for (let key in attr) {\n            $.attr(element, key, attr[key]);\n        }\n        return;\n    }\n\n    element.setAttribute(attr, value);\n};\n","import date_utils from './date_utils';\nimport { $, createSVG, animateSVG } from './svg_utils';\n\nexport default class Bar {\n    constructor(gantt, task) {\n        this.set_defaults(gantt, task);\n        this.prepare();\n        this.draw();\n        this.bind();\n    }\n\n    set_defaults(gantt, task) {\n        this.action_completed = false;\n        this.gantt = gantt;\n        this.task = task;\n    }\n\n    prepare() {\n        this.prepare_values();\n        this.prepare_helpers();\n    }\n\n    prepare_values() {\n        this.invalid = this.task.invalid;\n        this.height = this.gantt.options.bar_height;\n        this.x = this.compute_x();\n        this.y = this.compute_y();\n        this.corner_radius = this.gantt.options.bar_corner_radius;\n        this.duration =\n            date_utils.diff(this.task._end, this.task._start, 'hour') /\n            this.gantt.options.step;\n        this.width = this.gantt.options.column_width * this.duration;\n        this.progress_width =\n            this.gantt.options.column_width *\n                this.duration *\n                (this.task.progress / 100) || 0;\n        this.group = createSVG('g', {\n            class: 'bar-wrapper ' + (this.task.custom_class || ''),\n            'data-id': this.task.id,\n        });\n        this.bar_group = createSVG('g', {\n            class: 'bar-group',\n            append_to: this.group,\n        });\n        this.handle_group = createSVG('g', {\n            class: 'handle-group',\n            append_to: this.group,\n        });\n    }\n\n    prepare_helpers() {\n        SVGElement.prototype.getX = function () {\n            return +this.getAttribute('x');\n        };\n        SVGElement.prototype.getY = function () {\n            return +this.getAttribute('y');\n        };\n        SVGElement.prototype.getWidth = function () {\n            return +this.getAttribute('width');\n        };\n        SVGElement.prototype.getHeight = function () {\n            return +this.getAttribute('height');\n        };\n        SVGElement.prototype.getEndX = function () {\n            return this.getX() + this.getWidth();\n        };\n    }\n\n    draw() {\n        this.draw_bar();\n        this.draw_progress_bar();\n        this.draw_label();\n        this.draw_resize_handles();\n    }\n\n    draw_bar() {\n        this.$bar = createSVG('rect', {\n            x: this.x,\n            y: this.y,\n            width: this.width,\n            height: this.height,\n            rx: this.corner_radius,\n            ry: this.corner_radius,\n            class: 'bar',\n            append_to: this.bar_group,\n        });\n\n        animateSVG(this.$bar, 'width', 0, this.width);\n\n        if (this.invalid) {\n            this.$bar.classList.add('bar-invalid');\n        }\n    }\n\n    draw_progress_bar() {\n        if (this.invalid) return;\n        this.$bar_progress = createSVG('rect', {\n            x: this.x,\n            y: this.y,\n            width: this.progress_width,\n            height: this.height,\n            rx: this.corner_radius,\n            ry: this.corner_radius,\n            class: 'bar-progress',\n            append_to: this.bar_group,\n        });\n\n        animateSVG(this.$bar_progress, 'width', 0, this.progress_width);\n    }\n\n    draw_label() {\n        createSVG('text', {\n            x: this.x + this.width / 2,\n            y: this.y + this.height / 2,\n            innerHTML: this.task.name,\n            class: 'bar-label',\n            append_to: this.bar_group,\n        });\n        // labels get BBox in the next tick\n        requestAnimationFrame(() => this.update_label_position());\n    }\n\n    draw_resize_handles() {\n        if (this.invalid) return;\n\n        const bar = this.$bar;\n        const handle_width = 8;\n\n        createSVG('rect', {\n            x: bar.getX() + bar.getWidth() - 9,\n            y: bar.getY() + 1,\n            width: handle_width,\n            height: this.height - 2,\n            rx: this.corner_radius,\n            ry: this.corner_radius,\n            class: 'handle right',\n            append_to: this.handle_group,\n        });\n\n        createSVG('rect', {\n            x: bar.getX() + 1,\n            y: bar.getY() + 1,\n            width: handle_width,\n            height: this.height - 2,\n            rx: this.corner_radius,\n            ry: this.corner_radius,\n            class: 'handle left',\n            append_to: this.handle_group,\n        });\n\n        if (this.task.progress && this.task.progress < 100) {\n            this.$handle_progress = createSVG('polygon', {\n                points: this.get_progress_polygon_points().join(','),\n                class: 'handle progress',\n                append_to: this.handle_group,\n            });\n        }\n    }\n\n    get_progress_polygon_points() {\n        const bar_progress = this.$bar_progress;\n        return [\n            bar_progress.getEndX() - 5,\n            bar_progress.getY() + bar_progress.getHeight(),\n            bar_progress.getEndX() + 5,\n            bar_progress.getY() + bar_progress.getHeight(),\n            bar_progress.getEndX(),\n            bar_progress.getY() + bar_progress.getHeight() - 8.66,\n        ];\n    }\n\n    bind() {\n        if (this.invalid) return;\n        this.setup_click_event();\n    }\n\n    setup_click_event() {\n        $.on(this.group, 'focus ' + this.gantt.options.popup_trigger, (e) => {\n            if (this.action_completed) {\n                // just finished a move action, wait for a few seconds\n                return;\n            }\n\n            this.show_popup();\n            this.gantt.unselect_all();\n            this.group.classList.add('active');\n        });\n\n        $.on(this.group, 'dblclick', (e) => {\n            if (this.action_completed) {\n                // just finished a move action, wait for a few seconds\n                return;\n            }\n\n            this.gantt.trigger_event('click', [this.task]);\n        });\n    }\n\n    show_popup() {\n        if (this.gantt.bar_being_dragged) return;\n\n        const start_date = date_utils.format(\n            this.task._start,\n            'MMM D',\n            this.gantt.options.language\n        );\n        const end_date = date_utils.format(\n            date_utils.add(this.task._end, -1, 'second'),\n            'MMM D',\n            this.gantt.options.language\n        );\n        const subtitle = start_date + ' - ' + end_date;\n\n        this.gantt.show_popup({\n            target_element: this.$bar,\n            title: this.task.name,\n            subtitle: subtitle,\n            task: this.task,\n        });\n    }\n\n    update_bar_position({ x = null, width = null }) {\n        const bar = this.$bar;\n        if (x) {\n            // get all x values of parent task\n            const xs = this.task.dependencies.map((dep) => {\n                return this.gantt.get_bar(dep).$bar.getX();\n            });\n            // child task must not go before parent\n            const valid_x = xs.reduce((prev, curr) => {\n                return x >= curr;\n            }, x);\n            if (!valid_x) {\n                width = null;\n                return;\n            }\n            this.update_attr(bar, 'x', x);\n        }\n        if (width && width >= this.gantt.options.column_width) {\n            this.update_attr(bar, 'width', width);\n        }\n        this.update_label_position();\n        this.update_handle_position();\n        this.update_progressbar_position();\n        this.update_arrow_position();\n    }\n\n    date_changed() {\n        let changed = false;\n        const { new_start_date, new_end_date } = this.compute_start_end_date();\n\n        if (Number(this.task._start) !== Number(new_start_date)) {\n            changed = true;\n            this.task._start = new_start_date;\n        }\n\n        if (Number(this.task._end) !== Number(new_end_date)) {\n            changed = true;\n            this.task._end = new_end_date;\n        }\n\n        if (!changed) return;\n\n        this.gantt.trigger_event('date_change', [\n            this.task,\n            new_start_date,\n            date_utils.add(new_end_date, -1, 'second'),\n        ]);\n    }\n\n    progress_changed() {\n        const new_progress = this.compute_progress();\n        this.task.progress = new_progress;\n        this.gantt.trigger_event('progress_change', [this.task, new_progress]);\n    }\n\n    set_action_completed() {\n        this.action_completed = true;\n        setTimeout(() => (this.action_completed = false), 1000);\n    }\n\n    compute_start_end_date() {\n        const bar = this.$bar;\n        const x_in_units = bar.getX() / this.gantt.options.column_width;\n        const new_start_date = date_utils.add(\n            this.gantt.gantt_start,\n            x_in_units * this.gantt.options.step,\n            'hour'\n        );\n        const width_in_units = bar.getWidth() / this.gantt.options.column_width;\n        const new_end_date = date_utils.add(\n            new_start_date,\n            width_in_units * this.gantt.options.step,\n            'hour'\n        );\n\n        return { new_start_date, new_end_date };\n    }\n\n    compute_progress() {\n        const progress =\n            (this.$bar_progress.getWidth() / this.$bar.getWidth()) * 100;\n        return parseInt(progress, 10);\n    }\n\n    compute_x() {\n        const { step, column_width } = this.gantt.options;\n        const task_start = this.task._start;\n        const gantt_start = this.gantt.gantt_start;\n\n        const diff = date_utils.diff(task_start, gantt_start, 'hour');\n        let x = (diff / step) * column_width;\n\n        if (this.gantt.view_is('Month')) {\n            const diff = date_utils.diff(task_start, gantt_start, 'day');\n            x = (diff * column_width) / 30;\n        }\n        return x;\n    }\n\n    compute_y() {\n        return (\n            this.gantt.options.header_height +\n            this.gantt.options.padding +\n            this.task._index * (this.height + this.gantt.options.padding)\n        );\n    }\n\n    get_snap_position(dx) {\n        let odx = dx,\n            rem,\n            position;\n\n        if (this.gantt.view_is('Week')) {\n            rem = dx % (this.gantt.options.column_width / 7);\n            position =\n                odx -\n                rem +\n                (rem < this.gantt.options.column_width / 14\n                    ? 0\n                    : this.gantt.options.column_width / 7);\n        } else if (this.gantt.view_is('Month')) {\n            rem = dx % (this.gantt.options.column_width / 30);\n            position =\n                odx -\n                rem +\n                (rem < this.gantt.options.column_width / 60\n                    ? 0\n                    : this.gantt.options.column_width / 30);\n        } else {\n            rem = dx % this.gantt.options.column_width;\n            position =\n                odx -\n                rem +\n                (rem < this.gantt.options.column_width / 2\n                    ? 0\n                    : this.gantt.options.column_width);\n        }\n        return position;\n    }\n\n    update_attr(element, attr, value) {\n        value = +value;\n        if (!isNaN(value)) {\n            element.setAttribute(attr, value);\n        }\n        return element;\n    }\n\n    update_progressbar_position() {\n        this.$bar_progress.setAttribute('x', this.$bar.getX());\n        this.$bar_progress.setAttribute(\n            'width',\n            this.$bar.getWidth() * (this.task.progress / 100)\n        );\n    }\n\n    update_label_position() {\n        const bar = this.$bar,\n            label = this.group.querySelector('.bar-label');\n\n        if (label.getBBox().width > bar.getWidth()) {\n            label.classList.add('big');\n            label.setAttribute('x', bar.getX() + bar.getWidth() + 5);\n        } else {\n            label.classList.remove('big');\n            label.setAttribute('x', bar.getX() + bar.getWidth() / 2);\n        }\n    }\n\n    update_handle_position() {\n        const bar = this.$bar;\n        this.handle_group\n            .querySelector('.handle.left')\n            .setAttribute('x', bar.getX() + 1);\n        this.handle_group\n            .querySelector('.handle.right')\n            .setAttribute('x', bar.getEndX() - 9);\n        const handle = this.group.querySelector('.handle.progress');\n        handle &&\n            handle.setAttribute('points', this.get_progress_polygon_points());\n    }\n\n    update_arrow_position() {\n        this.arrows = this.arrows || [];\n        for (let arrow of this.arrows) {\n            arrow.update();\n        }\n    }\n}\n\nfunction isFunction(functionToCheck) {\n    var getType = {};\n    return (\n        functionToCheck &&\n        getType.toString.call(functionToCheck) === '[object Function]'\n    );\n}\n","import { createSVG } from './svg_utils';\n\nexport default class Arrow {\n    constructor(gantt, from_task, to_task) {\n        this.gantt = gantt;\n        this.from_task = from_task;\n        this.to_task = to_task;\n\n        this.calculate_path();\n        this.draw();\n    }\n\n    calculate_path() {\n        let start_x =\n            this.from_task.$bar.getX() + this.from_task.$bar.getWidth() / 2;\n\n        const condition = () =>\n            this.to_task.$bar.getX() < start_x + this.gantt.options.padding &&\n            start_x > this.from_task.$bar.getX() + this.gantt.options.padding;\n\n        while (condition()) {\n            start_x -= 10;\n        }\n\n        const start_y =\n            this.gantt.options.header_height +\n            this.gantt.options.bar_height +\n            (this.gantt.options.padding + this.gantt.options.bar_height) *\n                this.from_task.task._index +\n            this.gantt.options.padding;\n\n        const end_x = this.to_task.$bar.getX() - this.gantt.options.padding / 2;\n        const end_y =\n            this.gantt.options.header_height +\n            this.gantt.options.bar_height / 2 +\n            (this.gantt.options.padding + this.gantt.options.bar_height) *\n                this.to_task.task._index +\n            this.gantt.options.padding;\n\n        const from_is_below_to =\n            this.from_task.task._index > this.to_task.task._index;\n        const curve = this.gantt.options.arrow_curve;\n        const clockwise = from_is_below_to ? 1 : 0;\n        const curve_y = from_is_below_to ? -curve : curve;\n        const offset = from_is_below_to\n            ? end_y + this.gantt.options.arrow_curve\n            : end_y - this.gantt.options.arrow_curve;\n\n        this.path = `\n            M ${start_x} ${start_y}\n            V ${offset}\n            a ${curve} ${curve} 0 0 ${clockwise} ${curve} ${curve_y}\n            L ${end_x} ${end_y}\n            m -5 -5\n            l 5 5\n            l -5 5`;\n\n        if (\n            this.to_task.$bar.getX() <\n            this.from_task.$bar.getX() + this.gantt.options.padding\n        ) {\n            const down_1 = this.gantt.options.padding / 2 - curve;\n            const down_2 =\n                this.to_task.$bar.getY() +\n                this.to_task.$bar.getHeight() / 2 -\n                curve_y;\n            const left = this.to_task.$bar.getX() - this.gantt.options.padding;\n\n            this.path = `\n                M ${start_x} ${start_y}\n                v ${down_1}\n                a ${curve} ${curve} 0 0 1 -${curve} ${curve}\n                H ${left}\n                a ${curve} ${curve} 0 0 ${clockwise} -${curve} ${curve_y}\n                V ${down_2}\n                a ${curve} ${curve} 0 0 ${clockwise} ${curve} ${curve_y}\n                L ${end_x} ${end_y}\n                m -5 -5\n                l 5 5\n                l -5 5`;\n        }\n    }\n\n    draw() {\n        this.element = createSVG('path', {\n            d: this.path,\n            'data-from': this.from_task.task.id,\n            'data-to': this.to_task.task.id,\n        });\n    }\n\n    update() {\n        this.calculate_path();\n        this.element.setAttribute('d', this.path);\n    }\n}\n","export default class Popup {\n    constructor(parent, custom_html) {\n        this.parent = parent;\n        this.custom_html = custom_html;\n        this.make();\n    }\n\n    make() {\n        this.parent.innerHTML = `\n            <div class=\"title\"></div>\n            <div class=\"subtitle\"></div>\n            <div class=\"pointer\"></div>\n        `;\n\n        this.hide();\n\n        this.title = this.parent.querySelector('.title');\n        this.subtitle = this.parent.querySelector('.subtitle');\n        this.pointer = this.parent.querySelector('.pointer');\n    }\n\n    show(options) {\n        if (!options.target_element) {\n            throw new Error('target_element is required to show popup');\n        }\n        if (!options.position) {\n            options.position = 'left';\n        }\n        const target_element = options.target_element;\n\n        if (this.custom_html) {\n            let html = this.custom_html(options.task);\n            html += '<div class=\"pointer\"></div>';\n            this.parent.innerHTML = html;\n            this.pointer = this.parent.querySelector('.pointer');\n        } else {\n            // set data\n            this.title.innerHTML = options.title;\n            this.subtitle.innerHTML = options.subtitle;\n            this.parent.style.width = this.parent.clientWidth + 'px';\n        }\n\n        // set position\n        let position_meta;\n        if (target_element instanceof HTMLElement) {\n            position_meta = target_element.getBoundingClientRect();\n        } else if (target_element instanceof SVGElement) {\n            position_meta = options.target_element.getBBox();\n        }\n\n        if (options.position === 'left') {\n            this.parent.style.left =\n                position_meta.x + (position_meta.width + 10) + 'px';\n            this.parent.style.top = position_meta.y + 'px';\n\n            this.pointer.style.transform = 'rotateZ(90deg)';\n            this.pointer.style.left = '-7px';\n            this.pointer.style.top = '2px';\n        }\n\n        // show\n        this.parent.style.opacity = 1;\n    }\n\n    hide() {\n        this.parent.style.opacity = 0;\n        this.parent.style.left = 0;\n    }\n}\n","import date_utils from './date_utils';\nimport { $, createSVG } from './svg_utils';\nimport Bar from './bar';\nimport Arrow from './arrow';\nimport Popup from './popup';\n\nimport './gantt.scss';\n\nconst VIEW_MODE = {\n    QUARTER_DAY: 'Quarter Day',\n    HALF_DAY: 'Half Day',\n    DAY: 'Day',\n    WEEK: 'Week',\n    MONTH: 'Month',\n    YEAR: 'Year',\n};\n\nexport class Gantt {\n    constructor(wrapper, tasks, options) {\n        this.setup_wrapper(wrapper);\n        this.setup_options(options);\n        this.setup_tasks(tasks);\n        // initialize with default view mode\n        this.change_view_mode();\n        this.bind_events();\n    }\n\n    setup_wrapper(element) {\n        let svg_element, wrapper_element;\n\n        // CSS Selector is passed\n        if (typeof element === 'string') {\n            element = document.querySelector(element);\n        }\n\n        // get the SVGElement\n        if (element instanceof HTMLElement) {\n            wrapper_element = element;\n            svg_element = element.querySelector('svg');\n        } else if (element instanceof SVGElement) {\n            svg_element = element;\n        } else {\n            throw new TypeError(\n                'Frappé Gantt only supports usage of a string CSS selector,' +\n                    \" HTML DOM element or SVG DOM element for the 'element' parameter\"\n            );\n        }\n\n        // svg element\n        if (!svg_element) {\n            // create it\n            this.$svg = createSVG('svg', {\n                append_to: wrapper_element,\n                class: 'gantt',\n            });\n        } else {\n            this.$svg = svg_element;\n            this.$svg.classList.add('gantt');\n        }\n\n        // wrapper element\n        this.$container = document.createElement('div');\n        this.$container.classList.add('gantt-container');\n\n        const parent_element = this.$svg.parentElement;\n        parent_element.appendChild(this.$container);\n        this.$container.appendChild(this.$svg);\n\n        // popup wrapper\n        this.popup_wrapper = document.createElement('div');\n        this.popup_wrapper.classList.add('popup-wrapper');\n        this.$container.appendChild(this.popup_wrapper);\n    }\n\n    setup_options(options) {\n        const default_options = {\n            header_height: 50,\n            column_width: 30,\n            step: 24,\n            view_modes: [...Object.values(VIEW_MODE)],\n            bar_height: 20,\n            bar_corner_radius: 3,\n            arrow_curve: 5,\n            padding: 18,\n            view_mode: 'Day',\n            date_format: 'YYYY-MM-DD',\n            popup_trigger: 'click',\n            custom_popup_html: null,\n            language: 'en',\n        };\n        this.options = Object.assign({}, default_options, options);\n    }\n\n    setup_tasks(tasks) {\n        // prepare tasks\n        this.tasks = tasks.map((task, i) => {\n            // convert to Date objects\n            task._start = date_utils.parse(task.start);\n            task._end = date_utils.parse(task.end);\n\n            // make task invalid if duration too large\n            if (date_utils.diff(task._end, task._start, 'year') > 10) {\n                task.end = null;\n            }\n\n            // cache index\n            task._index = i;\n\n            // invalid dates\n            if (!task.start && !task.end) {\n                const today = date_utils.today();\n                task._start = today;\n                task._end = date_utils.add(today, 2, 'day');\n            }\n\n            if (!task.start && task.end) {\n                task._start = date_utils.add(task._end, -2, 'day');\n            }\n\n            if (task.start && !task.end) {\n                task._end = date_utils.add(task._start, 2, 'day');\n            }\n\n            // if hours is not set, assume the last day is full day\n            // e.g: 2018-09-09 becomes 2018-09-09 23:59:59\n            const task_end_values = date_utils.get_date_values(task._end);\n            if (task_end_values.slice(3).every((d) => d === 0)) {\n                task._end = date_utils.add(task._end, 24, 'hour');\n            }\n\n            // invalid flag\n            if (!task.start || !task.end) {\n                task.invalid = true;\n            }\n\n            // dependencies\n            if (typeof task.dependencies === 'string' || !task.dependencies) {\n                let deps = [];\n                if (task.dependencies) {\n                    deps = task.dependencies\n                        .split(',')\n                        .map((d) => d.trim())\n                        .filter((d) => d);\n                }\n                task.dependencies = deps;\n            }\n\n            // uids\n            if (!task.id) {\n                task.id = generate_id(task);\n            }\n\n            return task;\n        });\n\n        this.setup_dependencies();\n    }\n\n    setup_dependencies() {\n        this.dependency_map = {};\n        for (let t of this.tasks) {\n            for (let d of t.dependencies) {\n                this.dependency_map[d] = this.dependency_map[d] || [];\n                this.dependency_map[d].push(t.id);\n            }\n        }\n    }\n\n    refresh(tasks) {\n        this.setup_tasks(tasks);\n        this.change_view_mode();\n    }\n\n    change_view_mode(mode = this.options.view_mode) {\n        this.update_view_scale(mode);\n        this.setup_dates();\n        this.render();\n        // fire viewmode_change event\n        this.trigger_event('view_change', [mode]);\n    }\n\n    update_view_scale(view_mode) {\n        this.options.view_mode = view_mode;\n\n        if (view_mode === VIEW_MODE.DAY) {\n            this.options.step = 24;\n            this.options.column_width = 38;\n        } else if (view_mode === VIEW_MODE.HALF_DAY) {\n            this.options.step = 24 / 2;\n            this.options.column_width = 38;\n        } else if (view_mode === VIEW_MODE.QUARTER_DAY) {\n            this.options.step = 24 / 4;\n            this.options.column_width = 38;\n        } else if (view_mode === VIEW_MODE.WEEK) {\n            this.options.step = 24 * 7;\n            this.options.column_width = 140;\n        } else if (view_mode === VIEW_MODE.MONTH) {\n            this.options.step = 24 * 30;\n            this.options.column_width = 120;\n        } else if (view_mode === VIEW_MODE.YEAR) {\n            this.options.step = 24 * 365;\n            this.options.column_width = 120;\n        }\n    }\n\n    setup_dates() {\n        this.setup_gantt_dates();\n        this.setup_date_values();\n    }\n\n    setup_gantt_dates() {\n        this.gantt_start = this.gantt_end = null;\n\n        for (let task of this.tasks) {\n            // set global start and end date\n            if (!this.gantt_start || task._start < this.gantt_start) {\n                this.gantt_start = task._start;\n            }\n            if (!this.gantt_end || task._end > this.gantt_end) {\n                this.gantt_end = task._end;\n            }\n        }\n\n        this.gantt_start = date_utils.start_of(this.gantt_start, 'day');\n        this.gantt_end = date_utils.start_of(this.gantt_end, 'day');\n\n        // add date padding on both sides\n        if (this.view_is([VIEW_MODE.QUARTER_DAY, VIEW_MODE.HALF_DAY])) {\n            this.gantt_start = date_utils.add(this.gantt_start, -7, 'day');\n            this.gantt_end = date_utils.add(this.gantt_end, 7, 'day');\n        } else if (this.view_is(VIEW_MODE.MONTH)) {\n            this.gantt_start = date_utils.start_of(this.gantt_start, 'year');\n            this.gantt_end = date_utils.add(this.gantt_end, 1, 'year');\n        } else if (this.view_is(VIEW_MODE.YEAR)) {\n            this.gantt_start = date_utils.add(this.gantt_start, -2, 'year');\n            this.gantt_end = date_utils.add(this.gantt_end, 2, 'year');\n        } else {\n            this.gantt_start = date_utils.add(this.gantt_start, -1, 'month');\n            this.gantt_end = date_utils.add(this.gantt_end, 1, 'month');\n        }\n    }\n\n    setup_date_values() {\n        this.dates = [];\n        let cur_date = null;\n\n        while (cur_date === null || cur_date < this.gantt_end) {\n            if (!cur_date) {\n                cur_date = date_utils.clone(this.gantt_start);\n            } else {\n                if (this.view_is(VIEW_MODE.YEAR)) {\n                    cur_date = date_utils.add(cur_date, 1, 'year');\n                } else if (this.view_is(VIEW_MODE.MONTH)) {\n                    cur_date = date_utils.add(cur_date, 1, 'month');\n                } else {\n                    cur_date = date_utils.add(\n                        cur_date,\n                        this.options.step,\n                        'hour'\n                    );\n                }\n            }\n            this.dates.push(cur_date);\n        }\n    }\n\n    bind_events() {\n        this.bind_grid_click();\n        this.bind_bar_events();\n    }\n\n    render() {\n        this.clear();\n        this.setup_layers();\n        this.make_grid();\n        this.make_dates();\n        this.make_bars();\n        this.make_arrows();\n        this.map_arrows_on_bars();\n        this.set_width();\n        this.set_scroll_position();\n    }\n\n    setup_layers() {\n        this.layers = {};\n        const layers = ['grid', 'date', 'arrow', 'progress', 'bar', 'details'];\n        // make group layers\n        for (let layer of layers) {\n            this.layers[layer] = createSVG('g', {\n                class: layer,\n                append_to: this.$svg,\n            });\n        }\n    }\n\n    make_grid() {\n        this.make_grid_background();\n        this.make_grid_rows();\n        this.make_grid_header();\n        this.make_grid_ticks();\n        this.make_grid_highlights();\n    }\n\n    make_grid_background() {\n        const grid_width = this.dates.length * this.options.column_width;\n        const grid_height =\n            this.options.header_height +\n            this.options.padding +\n            (this.options.bar_height + this.options.padding) *\n                this.tasks.length;\n\n        createSVG('rect', {\n            x: 0,\n            y: 0,\n            width: grid_width,\n            height: grid_height,\n            class: 'grid-background',\n            append_to: this.layers.grid,\n        });\n\n        $.attr(this.$svg, {\n            height: grid_height + this.options.padding + 100,\n            width: '100%',\n        });\n    }\n\n    make_grid_rows() {\n        const rows_layer = createSVG('g', { append_to: this.layers.grid });\n        const lines_layer = createSVG('g', { append_to: this.layers.grid });\n\n        const row_width = this.dates.length * this.options.column_width;\n        const row_height = this.options.bar_height + this.options.padding;\n\n        let row_y = this.options.header_height + this.options.padding / 2;\n\n        for (let task of this.tasks) {\n            createSVG('rect', {\n                x: 0,\n                y: row_y,\n                width: row_width,\n                height: row_height,\n                class: 'grid-row',\n                append_to: rows_layer,\n            });\n\n            createSVG('line', {\n                x1: 0,\n                y1: row_y + row_height,\n                x2: row_width,\n                y2: row_y + row_height,\n                class: 'row-line',\n                append_to: lines_layer,\n            });\n\n            row_y += this.options.bar_height + this.options.padding;\n        }\n    }\n\n    make_grid_header() {\n        const header_width = this.dates.length * this.options.column_width;\n        const header_height = this.options.header_height + 10;\n        createSVG('rect', {\n            x: 0,\n            y: 0,\n            width: header_width,\n            height: header_height,\n            class: 'grid-header',\n            append_to: this.layers.grid,\n        });\n    }\n\n    make_grid_ticks() {\n        let tick_x = 0;\n        let tick_y = this.options.header_height + this.options.padding / 2;\n        let tick_height =\n            (this.options.bar_height + this.options.padding) *\n            this.tasks.length;\n\n        for (let date of this.dates) {\n            let tick_class = 'tick';\n            // thick tick for monday\n            if (this.view_is(VIEW_MODE.DAY) && date.getDate() === 1) {\n                tick_class += ' thick';\n            }\n            // thick tick for first week\n            if (\n                this.view_is(VIEW_MODE.WEEK) &&\n                date.getDate() >= 1 &&\n                date.getDate() < 8\n            ) {\n                tick_class += ' thick';\n            }\n            // thick ticks for quarters\n            if (\n                this.view_is(VIEW_MODE.MONTH) &&\n                (date.getMonth() + 1) % 3 === 0\n            ) {\n                tick_class += ' thick';\n            }\n\n            createSVG('path', {\n                d: `M ${tick_x} ${tick_y} v ${tick_height}`,\n                class: tick_class,\n                append_to: this.layers.grid,\n            });\n\n            if (this.view_is(VIEW_MODE.MONTH)) {\n                tick_x +=\n                    (date_utils.get_days_in_month(date) *\n                        this.options.column_width) /\n                    30;\n            } else {\n                tick_x += this.options.column_width;\n            }\n        }\n    }\n\n    make_grid_highlights() {\n        // highlight today's date\n        if (this.view_is(VIEW_MODE.DAY)) {\n            const x =\n                (date_utils.diff(date_utils.today(), this.gantt_start, 'hour') /\n                    this.options.step) *\n                this.options.column_width;\n            const y = 0;\n\n            const width = this.options.column_width;\n            const height =\n                (this.options.bar_height + this.options.padding) *\n                    this.tasks.length +\n                this.options.header_height +\n                this.options.padding / 2;\n\n            createSVG('rect', {\n                x,\n                y,\n                width,\n                height,\n                class: 'today-highlight',\n                append_to: this.layers.grid,\n            });\n        }\n    }\n\n    make_dates() {\n        for (let date of this.get_dates_to_draw()) {\n            createSVG('text', {\n                x: date.lower_x,\n                y: date.lower_y,\n                innerHTML: date.lower_text,\n                class: 'lower-text',\n                append_to: this.layers.date,\n            });\n\n            if (date.upper_text) {\n                const $upper_text = createSVG('text', {\n                    x: date.upper_x,\n                    y: date.upper_y,\n                    innerHTML: date.upper_text,\n                    class: 'upper-text',\n                    append_to: this.layers.date,\n                });\n\n                // remove out-of-bound dates\n                if (\n                    $upper_text.getBBox().x2 > this.layers.grid.getBBox().width\n                ) {\n                    $upper_text.remove();\n                }\n            }\n        }\n    }\n\n    get_dates_to_draw() {\n        let last_date = null;\n        const dates = this.dates.map((date, i) => {\n            const d = this.get_date_info(date, last_date, i);\n            last_date = date;\n            return d;\n        });\n        return dates;\n    }\n\n    get_date_info(date, last_date, i) {\n        if (!last_date) {\n            last_date = date_utils.add(date, 1, 'year');\n        }\n        const date_text = {\n            'Quarter Day_lower': date_utils.format(\n                date,\n                'HH',\n                this.options.language\n            ),\n            'Half Day_lower': date_utils.format(\n                date,\n                'HH',\n                this.options.language\n            ),\n            Day_lower:\n                date.getDate() !== last_date.getDate()\n                    ? date_utils.format(date, 'D', this.options.language)\n                    : '',\n            Week_lower:\n                date.getMonth() !== last_date.getMonth()\n                    ? date_utils.format(date, 'D MMM', this.options.language)\n                    : date_utils.format(date, 'D', this.options.language),\n            Month_lower: date_utils.format(date, 'MMMM', this.options.language),\n            Year_lower: date_utils.format(date, 'YYYY', this.options.language),\n            'Quarter Day_upper':\n                date.getDate() !== last_date.getDate()\n                    ? date_utils.format(date, 'D MMM', this.options.language)\n                    : '',\n            'Half Day_upper':\n                date.getDate() !== last_date.getDate()\n                    ? date.getMonth() !== last_date.getMonth()\n                        ? date_utils.format(\n                              date,\n                              'D MMM',\n                              this.options.language\n                          )\n                        : date_utils.format(date, 'D', this.options.language)\n                    : '',\n            Day_upper:\n                date.getMonth() !== last_date.getMonth()\n                    ? date_utils.format(date, 'MMMM', this.options.language)\n                    : '',\n            Week_upper:\n                date.getMonth() !== last_date.getMonth()\n                    ? date_utils.format(date, 'MMMM', this.options.language)\n                    : '',\n            Month_upper:\n                date.getFullYear() !== last_date.getFullYear()\n                    ? date_utils.format(date, 'YYYY', this.options.language)\n                    : '',\n            Year_upper:\n                date.getFullYear() !== last_date.getFullYear()\n                    ? date_utils.format(date, 'YYYY', this.options.language)\n                    : '',\n        };\n\n        const base_pos = {\n            x: i * this.options.column_width,\n            lower_y: this.options.header_height,\n            upper_y: this.options.header_height - 25,\n        };\n\n        const x_pos = {\n            'Quarter Day_lower': (this.options.column_width * 4) / 2,\n            'Quarter Day_upper': 0,\n            'Half Day_lower': (this.options.column_width * 2) / 2,\n            'Half Day_upper': 0,\n            Day_lower: this.options.column_width / 2,\n            Day_upper: (this.options.column_width * 30) / 2,\n            Week_lower: 0,\n            Week_upper: (this.options.column_width * 4) / 2,\n            Month_lower: this.options.column_width / 2,\n            Month_upper: (this.options.column_width * 12) / 2,\n            Year_lower: this.options.column_width / 2,\n            Year_upper: (this.options.column_width * 30) / 2,\n        };\n\n        return {\n            upper_text: date_text[`${this.options.view_mode}_upper`],\n            lower_text: date_text[`${this.options.view_mode}_lower`],\n            upper_x: base_pos.x + x_pos[`${this.options.view_mode}_upper`],\n            upper_y: base_pos.upper_y,\n            lower_x: base_pos.x + x_pos[`${this.options.view_mode}_lower`],\n            lower_y: base_pos.lower_y,\n        };\n    }\n\n    make_bars() {\n        this.bars = this.tasks.map((task) => {\n            const bar = new Bar(this, task);\n            this.layers.bar.appendChild(bar.group);\n            return bar;\n        });\n    }\n\n    make_arrows() {\n        this.arrows = [];\n        for (let task of this.tasks) {\n            let arrows = [];\n            arrows = task.dependencies\n                .map((task_id) => {\n                    const dependency = this.get_task(task_id);\n                    if (!dependency) return;\n                    const arrow = new Arrow(\n                        this,\n                        this.bars[dependency._index], // from_task\n                        this.bars[task._index] // to_task\n                    );\n                    this.layers.arrow.appendChild(arrow.element);\n                    return arrow;\n                })\n                .filter(Boolean); // filter falsy values\n            this.arrows = this.arrows.concat(arrows);\n        }\n    }\n\n    map_arrows_on_bars() {\n        for (let bar of this.bars) {\n            bar.arrows = this.arrows.filter((arrow) => {\n                return (\n                    arrow.from_task.task.id === bar.task.id ||\n                    arrow.to_task.task.id === bar.task.id\n                );\n            });\n        }\n    }\n\n    set_width() {\n        const cur_width = this.$svg.getBoundingClientRect().width;\n        const actual_width = this.$svg\n            .querySelector('.grid .grid-row')\n            .getAttribute('width');\n        if (cur_width < actual_width) {\n            this.$svg.setAttribute('width', actual_width);\n        }\n    }\n\n    set_scroll_position() {\n        const parent_element = this.$svg.parentElement;\n        if (!parent_element) return;\n\n        const hours_before_first_task = date_utils.diff(\n            this.get_oldest_starting_date(),\n            this.gantt_start,\n            'hour'\n        );\n\n        const scroll_pos =\n            (hours_before_first_task / this.options.step) *\n                this.options.column_width -\n            this.options.column_width;\n\n        parent_element.scrollLeft = scroll_pos;\n    }\n\n    bind_grid_click() {\n        $.on(\n            this.$svg,\n            this.options.popup_trigger,\n            '.grid-row, .grid-header',\n            () => {\n                this.unselect_all();\n                this.hide_popup();\n            }\n        );\n    }\n\n    bind_bar_events() {\n        let is_dragging = false;\n        let x_on_start = 0;\n        let y_on_start = 0;\n        let is_resizing_left = false;\n        let is_resizing_right = false;\n        let parent_bar_id = null;\n        let bars = []; // instanceof Bar\n        this.bar_being_dragged = null;\n\n        function action_in_progress() {\n            return is_dragging || is_resizing_left || is_resizing_right;\n        }\n\n        $.on(this.$svg, 'mousedown', '.bar-wrapper, .handle', (e, element) => {\n            const bar_wrapper = $.closest('.bar-wrapper', element);\n\n            if (element.classList.contains('left')) {\n                is_resizing_left = true;\n            } else if (element.classList.contains('right')) {\n                is_resizing_right = true;\n            } else if (element.classList.contains('bar-wrapper')) {\n                is_dragging = true;\n            }\n\n            bar_wrapper.classList.add('active');\n\n            x_on_start = e.offsetX;\n            y_on_start = e.offsetY;\n\n            parent_bar_id = bar_wrapper.getAttribute('data-id');\n            const ids = [\n                parent_bar_id,\n                ...this.get_all_dependent_tasks(parent_bar_id),\n            ];\n            bars = ids.map((id) => this.get_bar(id));\n\n            this.bar_being_dragged = parent_bar_id;\n\n            bars.forEach((bar) => {\n                const $bar = bar.$bar;\n                $bar.ox = $bar.getX();\n                $bar.oy = $bar.getY();\n                $bar.owidth = $bar.getWidth();\n                $bar.finaldx = 0;\n            });\n        });\n\n        $.on(this.$svg, 'mousemove', (e) => {\n            if (!action_in_progress()) return;\n            const dx = e.offsetX - x_on_start;\n            const dy = e.offsetY - y_on_start;\n\n            bars.forEach((bar) => {\n                const $bar = bar.$bar;\n                $bar.finaldx = this.get_snap_position(dx);\n                this.hide_popup();\n                if (is_resizing_left) {\n                    if (parent_bar_id === bar.task.id) {\n                        bar.update_bar_position({\n                            x: $bar.ox + $bar.finaldx,\n                            width: $bar.owidth - $bar.finaldx,\n                        });\n                    } else {\n                        bar.update_bar_position({\n                            x: $bar.ox + $bar.finaldx,\n                        });\n                    }\n                } else if (is_resizing_right) {\n                    if (parent_bar_id === bar.task.id) {\n                        bar.update_bar_position({\n                            width: $bar.owidth + $bar.finaldx,\n                        });\n                    }\n                } else if (is_dragging) {\n                    bar.update_bar_position({ x: $bar.ox + $bar.finaldx });\n                }\n            });\n        });\n\n        document.addEventListener('mouseup', (e) => {\n            if (is_dragging || is_resizing_left || is_resizing_right) {\n                bars.forEach((bar) => bar.group.classList.remove('active'));\n            }\n\n            is_dragging = false;\n            is_resizing_left = false;\n            is_resizing_right = false;\n        });\n\n        $.on(this.$svg, 'mouseup', (e) => {\n            this.bar_being_dragged = null;\n            bars.forEach((bar) => {\n                const $bar = bar.$bar;\n                if (!$bar.finaldx) return;\n                bar.date_changed();\n                bar.set_action_completed();\n            });\n        });\n\n        this.bind_bar_progress();\n    }\n\n    bind_bar_progress() {\n        let x_on_start = 0;\n        let y_on_start = 0;\n        let is_resizing = null;\n        let bar = null;\n        let $bar_progress = null;\n        let $bar = null;\n\n        $.on(this.$svg, 'mousedown', '.handle.progress', (e, handle) => {\n            is_resizing = true;\n            x_on_start = e.offsetX;\n            y_on_start = e.offsetY;\n\n            const $bar_wrapper = $.closest('.bar-wrapper', handle);\n            const id = $bar_wrapper.getAttribute('data-id');\n            bar = this.get_bar(id);\n\n            $bar_progress = bar.$bar_progress;\n            $bar = bar.$bar;\n\n            $bar_progress.finaldx = 0;\n            $bar_progress.owidth = $bar_progress.getWidth();\n            $bar_progress.min_dx = -$bar_progress.getWidth();\n            $bar_progress.max_dx = $bar.getWidth() - $bar_progress.getWidth();\n        });\n\n        $.on(this.$svg, 'mousemove', (e) => {\n            if (!is_resizing) return;\n            let dx = e.offsetX - x_on_start;\n            let dy = e.offsetY - y_on_start;\n\n            if (dx > $bar_progress.max_dx) {\n                dx = $bar_progress.max_dx;\n            }\n            if (dx < $bar_progress.min_dx) {\n                dx = $bar_progress.min_dx;\n            }\n\n            const $handle = bar.$handle_progress;\n            $.attr($bar_progress, 'width', $bar_progress.owidth + dx);\n            $.attr($handle, 'points', bar.get_progress_polygon_points());\n            $bar_progress.finaldx = dx;\n        });\n\n        $.on(this.$svg, 'mouseup', () => {\n            is_resizing = false;\n            if (!($bar_progress && $bar_progress.finaldx)) return;\n            bar.progress_changed();\n            bar.set_action_completed();\n        });\n    }\n\n    get_all_dependent_tasks(task_id) {\n        let out = [];\n        let to_process = [task_id];\n        while (to_process.length) {\n            const deps = to_process.reduce((acc, curr) => {\n                acc = acc.concat(this.dependency_map[curr]);\n                return acc;\n            }, []);\n\n            out = out.concat(deps);\n            to_process = deps.filter((d) => !to_process.includes(d));\n        }\n\n        return out.filter(Boolean);\n    }\n\n    get_snap_position(dx) {\n        let odx = dx,\n            rem,\n            position;\n\n        if (this.view_is(VIEW_MODE.WEEK)) {\n            rem = dx % (this.options.column_width / 7);\n            position =\n                odx -\n                rem +\n                (rem < this.options.column_width / 14\n                    ? 0\n                    : this.options.column_width / 7);\n        } else if (this.view_is(VIEW_MODE.MONTH)) {\n            rem = dx % (this.options.column_width / 30);\n            position =\n                odx -\n                rem +\n                (rem < this.options.column_width / 60\n                    ? 0\n                    : this.options.column_width / 30);\n        } else {\n            rem = dx % this.options.column_width;\n            position =\n                odx -\n                rem +\n                (rem < this.options.column_width / 2\n                    ? 0\n                    : this.options.column_width);\n        }\n        return position;\n    }\n\n    unselect_all() {\n        [...this.$svg.querySelectorAll('.bar-wrapper')].forEach((el) => {\n            el.classList.remove('active');\n        });\n    }\n\n    view_is(modes) {\n        if (typeof modes === 'string') {\n            return this.options.view_mode === modes;\n        }\n\n        if (Array.isArray(modes)) {\n            return modes.some((mode) => this.options.view_mode === mode);\n        }\n\n        return false;\n    }\n\n    get_task(id) {\n        return this.tasks.find((task) => {\n            return task.id === id;\n        });\n    }\n\n    get_bar(id) {\n        return this.bars.find((bar) => {\n            return bar.task.id === id;\n        });\n    }\n\n    show_popup(options) {\n        if (!this.popup) {\n            this.popup = new Popup(\n                this.popup_wrapper,\n                this.options.custom_popup_html\n            );\n        }\n        this.popup.show(options);\n    }\n\n    hide_popup() {\n        this.popup && this.popup.hide();\n    }\n\n    trigger_event(event, args) {\n        if (this.options['on_' + event]) {\n            this.options['on_' + event].apply(null, args);\n        }\n    }\n\n    /**\n     * Gets the oldest starting date from the list of tasks\n     *\n     * @returns Date\n     * @memberof Gantt\n     */\n    get_oldest_starting_date() {\n        return this.tasks\n            .map((task) => task._start)\n            .reduce((prev_date, cur_date) =>\n                cur_date <= prev_date ? cur_date : prev_date\n            );\n    }\n\n    /**\n     * Clear all elements from the parent svg element\n     *\n     * @memberof Gantt\n     */\n    clear() {\n        this.$svg.innerHTML = '';\n    }\n}\n\nGantt.VIEW_MODE = VIEW_MODE;\n\nfunction generate_id(task) {\n    return task.name + '_' + Math.random().toString(36).slice(2, 12);\n}\n"],"names":["month_names","en","es","ru","ptBr","fr","tr","zh","date_utils","parse","date","date_separator","time_separator","Date","date_parts","time_parts","parts","split","map","val","parseInt","vals","length","parseFloat","concat","to_string","with_time","TypeError","this","get_date_values","i","padStart","date_string","time_string","format","format_string","lang","values","d","format_map","YYYY","MM","DD","HH","mm","ss","SSS","D","MMMM","MMM","str","formatted_values","Object","keys","sort","a","b","forEach","key","includes","replace","push","value","diff","date_a","date_b","scale","milliseconds","seconds","hours","minutes","days","months","years","endsWith","Math","floor","today","slice","now","add","qty","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","getMilliseconds","start_of","scores","year","month","day","hour","minute","second","millisecond","should_reset","_scale","clone","get_days_in_month","no_of_days","targetLength","padString","String","repeat","$","expr","con","document","querySelector","createSVG","tag","attrs","elem","createElementNS","attr","append_to","appendChild","innerHTML","setAttribute","animateSVG","svgElement","from","to","animatedSvgElement","dur","begin","animEl","attributeName","animateElement","calcMode","keyTimes","keySplines","cubic_bezier","getAnimationElement","event","createEvent","initEvent","eventName","dispatchEvent","name","ease","linear","on","element","selector","callback","delegate","bind","off","handler","removeEventListener","addEventListener","e","delegatedTarget","target","closest","call","matches","parentNode","getAttribute","Bar","constructor","gantt","task","set_defaults","prepare","draw","action_completed","prepare_values","prepare_helpers","invalid","height","options","bar_height","x","compute_x","y","compute_y","corner_radius","bar_corner_radius","duration","_end","_start","step","width","column_width","progress_width","progress","group","class","custom_class","id","bar_group","handle_group","SVGElement","prototype","getX","getY","getWidth","getHeight","getEndX","draw_bar","draw_progress_bar","draw_label","draw_resize_handles","$bar","rx","ry","classList","$bar_progress","requestAnimationFrame","update_label_position","bar","$handle_progress","points","get_progress_polygon_points","join","bar_progress","setup_click_event","popup_trigger","show_popup","unselect_all","trigger_event","bar_being_dragged","subtitle","language","target_element","title","update_bar_position","dependencies","dep","get_bar","reduce","prev","curr","update_attr","update_handle_position","update_progressbar_position","update_arrow_position","date_changed","changed","new_start_date","new_end_date","compute_start_end_date","Number","progress_changed","new_progress","compute_progress","set_action_completed","setTimeout","x_in_units","gantt_start","width_in_units","task_start","view_is","header_height","padding","_index","get_snap_position","dx","rem","position","odx","isNaN","label","getBBox","remove","handle","arrows","arrow","update","Arrow","from_task","to_task","calculate_path","start_x","condition","start_y","end_x","end_y","from_is_below_to","curve","arrow_curve","clockwise","curve_y","offset","path","down_1","down_2","left","Popup","parent","custom_html","make","hide","pointer","show","Error","html","style","clientWidth","position_meta","HTMLElement","getBoundingClientRect","top","transform","opacity","VIEW_MODE","QUARTER_DAY","HALF_DAY","DAY","WEEK","MONTH","YEAR","Gantt","wrapper","tasks","setup_wrapper","setup_options","setup_tasks","change_view_mode","bind_events","svg_element","wrapper_element","$svg","$container","createElement","parentElement","popup_wrapper","default_options","view_modes","view_mode","date_format","custom_popup_html","assign","start","end","every","deps","trim","filter","random","toString","generate_id","setup_dependencies","dependency_map","t","refresh","mode","update_view_scale","setup_dates","render","setup_gantt_dates","setup_date_values","gantt_end","dates","cur_date","bind_grid_click","bind_bar_events","clear","setup_layers","make_grid","make_dates","make_bars","make_arrows","map_arrows_on_bars","set_width","set_scroll_position","layers","layer","make_grid_background","make_grid_rows","make_grid_header","make_grid_ticks","make_grid_highlights","grid_width","grid_height","grid","rows_layer","lines_layer","row_width","row_height","row_y","x1","y1","x2","y2","tick_x","tick_y","tick_height","tick_class","get_dates_to_draw","lower_x","lower_y","lower_text","upper_text","$upper_text","upper_x","upper_y","last_date","get_date_info","date_text","Day_lower","Week_lower","Month_lower","Year_lower","Day_upper","Week_upper","Month_upper","Year_upper","base_pos","x_pos","bars","task_id","dependency","get_task","Boolean","cur_width","actual_width","parent_element","scroll_pos","get_oldest_starting_date","scrollLeft","hide_popup","is_dragging","x_on_start","y_on_start","is_resizing_left","is_resizing_right","parent_bar_id","bar_wrapper","contains","offsetX","offsetY","ids","get_all_dependent_tasks","ox","oy","owidth","finaldx","bind_bar_progress","is_resizing","min_dx","max_dx","$handle","out","to_process","acc","querySelectorAll","el","modes","Array","isArray","some","find","popup","args","apply","prev_date"],"mappings":"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"}