ts-gantt
Version:
simple gantt chart written using typescript
1 lines • 63.6 kB
JavaScript
const t="--tsg-separator-width",e="--tsg-header-height",n="--tsg-row-height",a="--tsg-gridlines-width",s="--tsg-bar-stroke-width",r={ROW_CLICK:"tsgrowclick",ROW_CONTEXT_MENU:"tsgrowcontextmenu",TABLE_COLUMN_REORDER:"tsgtablecolreorder",TABLE_BODY_CELL_EXPANDER_CLICK:"tsgexpanderclick",HANDLE_MOVE:"tsghandlemove",HANDLE_MOVE_END:"tsghandlemoveend",TASK_CHANGED_IN_CHART:"tsgtaskchangedinchart"},i={ROOT:{TEXT_SELECTION_DISABLED:"tsg-no-text-selection",MAIN_ELEMENT:"tsg-wrapper",CHART_WRAPPER:"tsg-chart-wrapper",TABLE_WRAPPER:"tsg-table-wrapper",FOOTER:"tsg-footer",SEPARATOR:"tsg-separator",ROW_SELECTED:"selected"},CHART:{MAIN_ELEMENT:"tsg-chart",HEADER:"tsg-chart-header",HEADER_BACKGROUND:"tsg-chart-header-bg",HEADER_GRIDLINES:"tsg-chart-header-gl",HEADER_TEXT:"tsg-chart-header-text",BODY:"tsg-chart-body",BODY_BACKGROUND:"tsg-chart-body-bg",BODY_GRIDLINES:"tsg-chart-body-gl",BODY_TODAY_LINE:"tsg-chart-body-gl-today",ROW_WRAPPER:"tsg-chart-row-wrapper",ROW:"tsg-chart-row",ROW_BACKGROUND:"tsg-chart-row-bg",BAR:{GROUP:"tsg-chart-bar-group",WRAPPER:"tsg-chart-bar-wrapper",PLANNED:"tsg-chart-bar-planned",PLANNED_PROGRESS:"tsg-chart-bar-planned-progress",ACTUAL:"tsg-chart-bar-actual",ACTUAL_PROGRESS:"tsg-chart-bar-actual-progress",HANDLE_WRAPPER:"tsg-chart-bar-handle-wrapper",HANDLE:"tsg-chart-bar-handle"}},TABLE:{MAIN_ELEMENT:"tsg-table",COLUMN_RESIZER:"tsg-table-col-resizer",HEADER:"tsg-table-header",BODY_ROW:"tsg-table-body-row",BODY_CELL:"tsg-table-body-cell",BODY_CELL_TEXT_WRAPPER:"tsg-table-body-cell-text-wrapper",BODY_CELL_TEXT:"tsg-table-body-cell-text",BODY_CELL_EXPANDER:"tsg-table-body-cell-text-expander",BODY_CELL_EXPANDER_NESTING_PREFIX:"nesting-"}};class o{constructor(t=null){this.bindParentDatesToChild=!1,this.enableChartEdit=!1,this.multilineSelection=!0,this.useCtrlKeyForMultilineSelection=!0,this.drawTodayLine=!0,this.highlightRowsDependingOnTaskState=!0,this.columnsMinWidthPx=[200,100,100,100,100,100,100,100],this.columnsContentAlign=["start","end","center","center","center","center","center","center"],this.separatorWidthPx=5,this.headerHeightPx=90,this.rowHeightPx=40,this.borderWidthPx=1,this.barStrokeWidthPx=2,this.barMarginPx=2,this.barCornerRadiusPx=6,this.rowSymbols={childless:"•",collapsed:"▾",expanded:"▴"},this.chartShowProgress=!0,this.chartDisplayMode="both",this.chartScale="month",this.chartDateOffsetDays={day:14,week:60,month:240,year:730},this.chartDateOffsetDaysMin={day:7,week:30,month:120,year:365},this.chartDayWidthPx={day:60,week:20,month:3,year:1},this.locale="en",this.localeDecimalSeparator={en:".",uk:",",ru:",",ja:"."},this.localeDateFormat={en:"MM/DD/YYYY",uk:"DD.MM.YYYY",ru:"DD.MM.YYYY",ja:"YYYY/MM/DD"},this.localeFirstWeekDay={en:0,uk:1,ru:1,ja:0},this.localeDateMonths={en:["January","February","March","April","May","June","July","August","September","October","November","December"],uk:["Січень","Лютий","Березень","Квітень","Травень","Червень","Липень","Серпень","Вересень","Жовтень","Листопад","Грудень"],ru:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],ja:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"]},this.localeDateDays={en:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],uk:["Неділя","Понеділок","Вівторок","Середа","Четвер","П'ятниця","Субота"],ru:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],ja:["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"]},this.localeDateDaysShort={en:["Su","Mo","Tu","We","Th","Fr","Sa"],uk:["Нд","Пн","Вт","Ср","Чт","Пт","Сб"],ru:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],ja:["日","月","火","水","木","金","土"]},this.localeDateScale={en:["Weeks","Months","Years"],uk:["Тижні","Місяці","Роки"],ru:["Недели","Месяцы","Годы"],ja:["週間","月間","年間"]},this.localeFooters={en:["Total tasks","Completed"],uk:["Всього задач","Завершено"],ru:["Всего задач","Завершено"],ja:["総タスク","完了"]},this.localeHeaders={en:["Name","Progress","Start date planned","End date planned","Start date actual","End date actual","Duration planned","Duration actual"],uk:["Ім'я","Прогрес","Дата початку планована","Дата завершення планована","Дата початку фактична","Дата завершення фактична","Тривалість планована","Тривалість фактична"],ru:["Имя","Прогресс","Дата начала планируемая","Дата окончания планируемая","Дата начала фактическая","Дата окончания фактическая","Длительность планируемая","Длительность фактическая"],ja:["タイトル","進捗","予定開始日","予定終了日","実績開始日","実績終了日","予定日数","実績日数"]},this.localeDurationFormatters={en:t=>1===t?"1 day":t+" days",uk:t=>{let e=t%100;return e>10&&e<20?t+" днів":(e%=10,1===e?t+" день":e<5&&e>0?t+" дні":t+" днів")},ru:t=>{let e=t%100;return e>10&&e<20?t+" дней":(e%=10,1===e?t+" день":e<5&&e>0?t+" дня":t+" дней")},ja:t=>1===t?"1 日":t+" 日間"},this.columnValueGetters=[t=>t.localizedNames&&t.localizedNames[this.locale]||t.name,t=>(+t.progress.toFixed(2)).toLocaleString("en-US").replace(".",this.localeDecimalSeparator[this.locale]||".")+" %",t=>t.datePlannedStart?t.datePlannedStart.format(this.localeDateFormat[this.locale]||"L"):"",t=>t.datePlannedEnd?t.datePlannedEnd.format(this.localeDateFormat[this.locale]||"L"):"",t=>t.dateActualStart?t.dateActualStart.format(this.localeDateFormat[this.locale]||"L"):"",t=>t.dateActualEnd?t.dateActualEnd.format(this.localeDateFormat[this.locale]||"L"):"",t=>{if(!t.datePlannedEnd||!t.datePlannedStart)return"";const e=t.datePlannedEnd,n=t.datePlannedStart,a=e.diff(n,"day")+1;return this.localeDurationFormatters[this.locale]?this.localeDurationFormatters[this.locale](a):a.toString()},t=>{if(!t.dateActualEnd||!t.dateActualStart)return"";const e=t.dateActualEnd,n=t.dateActualStart,a=e.diff(n,"day")+1;return this.localeDurationFormatters[this.locale]?this.localeDurationFormatters[this.locale](a):a.toString()}],null!=t&&Object.assign(this,t)}get dayWidthPx(){return this.chartDayWidthPx[this.chartScale]}}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var d={exports:{}},l=d.exports=function(){var t=1e3,e=6e4,n=36e5,a="millisecond",s="second",r="minute",i="hour",o="day",d="week",l="month",h="quarter",c="year",u="date",p="Invalid Date",g=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,f=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,m={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var e=["th","st","nd","rd"],n=t%100;return"["+t+(e[(n-20)%10]||e[n]||e[0])+"]"}},v=function(t,e,n){var a=String(t);return!a||a.length>=e?t:""+Array(e+1-a.length).join(n)+t},_={s:v,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),a=Math.floor(n/60),s=n%60;return(e<=0?"+":"-")+v(a,2,"0")+":"+v(s,2,"0")},m:function t(e,n){if(e.date()<n.date())return-t(n,e);var a=12*(n.year()-e.year())+(n.month()-e.month()),s=e.clone().add(a,l),r=n-s<0,i=e.clone().add(a+(r?-1:1),l);return+(-(a+(n-s)/(r?s-i:i-s))||0)},a:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},p:function(t){return{M:l,y:c,w:d,d:o,D:u,h:i,m:r,s:s,ms:a,Q:h}[t]||String(t||"").toLowerCase().replace(/s$/,"")},u:function(t){return void 0===t}},E="en",w={};w[E]=m;var b=function(t){return t instanceof D},y=function t(e,n,a){var s;if(!e)return E;if("string"==typeof e){var r=e.toLowerCase();w[r]&&(s=r),n&&(w[r]=n,s=r);var i=e.split("-");if(!s&&i.length>1)return t(i[0])}else{var o=e.name;w[o]=e,s=o}return!a&&s&&(E=s),s||!a&&E},T=function(t,e){if(b(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new D(n)},x=_;x.l=y,x.i=b,x.w=function(t,e){return T(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var D=function(){function m(t){this.$L=y(t.locale,null,!0),this.parse(t)}var v=m.prototype;return v.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(x.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var a=e.match(g);if(a){var s=a[2]-1||0,r=(a[7]||"0").substring(0,3);return n?new Date(Date.UTC(a[1],s,a[3]||1,a[4]||0,a[5]||0,a[6]||0,r)):new Date(a[1],s,a[3]||1,a[4]||0,a[5]||0,a[6]||0,r)}}return new Date(e)}(t),this.$x=t.x||{},this.init()},v.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},v.$utils=function(){return x},v.isValid=function(){return!(this.$d.toString()===p)},v.isSame=function(t,e){var n=T(t);return this.startOf(e)<=n&&n<=this.endOf(e)},v.isAfter=function(t,e){return T(t)<this.startOf(e)},v.isBefore=function(t,e){return this.endOf(e)<T(t)},v.$g=function(t,e,n){return x.u(t)?this[e]:this.set(n,t)},v.unix=function(){return Math.floor(this.valueOf()/1e3)},v.valueOf=function(){return this.$d.getTime()},v.startOf=function(t,e){var n=this,a=!!x.u(e)||e,h=x.p(t),p=function(t,e){var s=x.w(n.$u?Date.UTC(n.$y,e,t):new Date(n.$y,e,t),n);return a?s:s.endOf(o)},g=function(t,e){return x.w(n.toDate()[t].apply(n.toDate("s"),(a?[0,0,0,0]:[23,59,59,999]).slice(e)),n)},f=this.$W,m=this.$M,v=this.$D,_="set"+(this.$u?"UTC":"");switch(h){case c:return a?p(1,0):p(31,11);case l:return a?p(1,m):p(0,m+1);case d:var E=this.$locale().weekStart||0,w=(f<E?f+7:f)-E;return p(a?v-w:v+(6-w),m);case o:case u:return g(_+"Hours",0);case i:return g(_+"Minutes",1);case r:return g(_+"Seconds",2);case s:return g(_+"Milliseconds",3);default:return this.clone()}},v.endOf=function(t){return this.startOf(t,!1)},v.$set=function(t,e){var n,d=x.p(t),h="set"+(this.$u?"UTC":""),p=(n={},n[o]=h+"Date",n[u]=h+"Date",n[l]=h+"Month",n[c]=h+"FullYear",n[i]=h+"Hours",n[r]=h+"Minutes",n[s]=h+"Seconds",n[a]=h+"Milliseconds",n)[d],g=d===o?this.$D+(e-this.$W):e;if(d===l||d===c){var f=this.clone().set(u,1);f.$d[p](g),f.init(),this.$d=f.set(u,Math.min(this.$D,f.daysInMonth())).$d}else p&&this.$d[p](g);return this.init(),this},v.set=function(t,e){return this.clone().$set(t,e)},v.get=function(t){return this[x.p(t)]()},v.add=function(a,h){var u,p=this;a=Number(a);var g=x.p(h),f=function(t){var e=T(p);return x.w(e.date(e.date()+Math.round(t*a)),p)};if(g===l)return this.set(l,this.$M+a);if(g===c)return this.set(c,this.$y+a);if(g===o)return f(1);if(g===d)return f(7);var m=(u={},u[r]=e,u[i]=n,u[s]=t,u)[g]||1,v=this.$d.getTime()+a*m;return x.w(v,this)},v.subtract=function(t,e){return this.add(-1*t,e)},v.format=function(t){var e=this,n=this.$locale();if(!this.isValid())return n.invalidDate||p;var a=t||"YYYY-MM-DDTHH:mm:ssZ",s=x.z(this),r=this.$H,i=this.$m,o=this.$M,d=n.weekdays,l=n.months,h=function(t,n,s,r){return t&&(t[n]||t(e,a))||s[n].slice(0,r)},c=function(t){return x.s(r%12||12,t,"0")},u=n.meridiem||function(t,e,n){var a=t<12?"AM":"PM";return n?a.toLowerCase():a},g={YY:String(this.$y).slice(-2),YYYY:this.$y,M:o+1,MM:x.s(o+1,2,"0"),MMM:h(n.monthsShort,o,l,3),MMMM:h(l,o),D:this.$D,DD:x.s(this.$D,2,"0"),d:String(this.$W),dd:h(n.weekdaysMin,this.$W,d,2),ddd:h(n.weekdaysShort,this.$W,d,3),dddd:d[this.$W],H:String(r),HH:x.s(r,2,"0"),h:c(1),hh:c(2),a:u(r,i,!0),A:u(r,i,!1),m:String(i),mm:x.s(i,2,"0"),s:String(this.$s),ss:x.s(this.$s,2,"0"),SSS:x.s(this.$ms,3,"0"),Z:s};return a.replace(f,(function(t,e){return e||g[t]||s.replace(":","")}))},v.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},v.diff=function(a,u,p){var g,f=x.p(u),m=T(a),v=(m.utcOffset()-this.utcOffset())*e,_=this-m,E=x.m(this,m);return E=(g={},g[c]=E/12,g[l]=E,g[h]=E/3,g[d]=(_-v)/6048e5,g[o]=(_-v)/864e5,g[i]=_/n,g[r]=_/e,g[s]=_/t,g)[f]||_,p?E:x.a(E)},v.daysInMonth=function(){return this.endOf(l).$D},v.$locale=function(){return w[this.$L]},v.locale=function(t,e){if(!t)return this.$L;var n=this.clone(),a=y(t,e,!0);return a&&(n.$L=a),n},v.clone=function(){return x.w(this.$d,this)},v.toDate=function(){return new Date(this.valueOf())},v.toJSON=function(){return this.isValid()?this.toISOString():null},v.toISOString=function(){return this.$d.toISOString()},v.toString=function(){return this.$d.toUTCString()},m}(),k=D.prototype;return T.prototype=k,[["$ms",a],["$s",s],["$m",r],["$H",i],["$W",o],["$M",l],["$y",c],["$D",u]].forEach((function(t){k[t[1]]=function(e){return this.$g(e,t[0],t[1])}})),T.extend=function(t,e){return t.$i||(t(e,D,T),t.$i=!0),T},T.locale=y,T.isDayjs=b,T.unix=function(t){return T(1e3*t)},T.en=w[E],T.Ls=w,T.p={},T}();function h(t,e=[],n=[],a=null,s=null){const r=document.createElementNS("http://www.w3.org/2000/svg",t);for(const t of n)r.setAttribute(t[0],t[1]);return 0!==e.length&&r.classList.add(...e),s&&(r.innerHTML=s),a&&a.append(r),r}class c{constructor(t,e,n,a,s,r,i,o,d,h,c,u,p,g,f,m){Object.assign(this,null!=t?t:{}),arguments.length<2||(this.externalId=e,this.parentExternalId=n,this.uuid=g||crypto.getRandomValues(new Uint32Array(4)).join("-"),this.parentUuid=p,this.nestingLvl=null!=c?c:0,this.hasChildren=null!=u&&u,this.name=a,this.localizedNames=s,this.datePlannedStart=i?l(i):null,this.datePlannedEnd=o?l(o):null,this.dateActualStart=d?l(d):null,this.dateActualEnd=h?l(h):null,this.progress=!r||r<0?0:r>100?100:r,this.shown=null!=f&&f,this.expanded=null!=m&&m)}static convertModelsToTasks(t,e=new Map){const n=t.slice(),a=new Set(n.map((t=>t.parentId))),s=[];let r=[];for(let t=n.length-1;t>=0;t--){const i=n[t];if(!i.parentId){const o=new c(i,i.id,i.parentId,i.name,i.localizedNames,i.progress,i.datePlannedStart,i.datePlannedEnd,i.dateActualStart,i.dateActualEnd,0,a.has(i.id),null,e.get(i.id));s.push(o),r.push(o),n.splice(t,1)}}let i=1;for(;0!==r.length;){const t=[];r.filter((t=>t.hasChildren)).forEach((r=>{for(let o=n.length-1;o>=0;o--){const d=n[o];if(d.parentId===r.externalId){const l=new c(d,d.id,d.parentId,d.name,d.localizedNames,d.progress,d.datePlannedStart,d.datePlannedEnd,d.dateActualStart,d.dateActualEnd,i,a.has(d.id),r.uuid,e.get(d.id));s.push(l),t.push(l),n.splice(o,1)}}})),r=t,i++}return s}static detectTaskChanges(t){const{oldTasks:e,newTasks:n}=t,a=new Map;e.forEach((t=>{a.set(t.uuid,t)}));const s=new Set;n.forEach((t=>{s.add(t.uuid)}));const r=e.filter((t=>!s.has(t.uuid))),i=[],o=[],d=[];for(const t of n){if(!a.has(t.uuid)){i.push(t),d.push(t);continue}const e=a.get(t.uuid);t.equals(e)?d.push(e):(o.push(t),d.push(t))}return{deleted:r,added:i,changed:o,all:d}}static createTasksIdMap(t){const e=new Map;for(const n of t)e.has(n.externalId)||e.set(n.externalId,n.uuid);return e}static checkPaternity(t,e,n){var a;let s=n.parentUuid;for(;s;){if(s===e.uuid)return!0;s=null===(a=t.find((t=>t.uuid===s)))||void 0===a?void 0:a.parentUuid}return!1}static checkForCollapsedParent(t,e){for(;e.parentUuid;)if(!(e=t.find((t=>t.uuid===e.parentUuid))).expanded)return!0;return!1}static sortTasksRecursively(t,e){const n=t.filter((t=>t.parentUuid===e)).sort(c.defaultComparer),a=[];for(const e of n)a.push(e),a.push(...this.sortTasksRecursively(t,e.uuid));return a}static getMinMaxDates(t){let e=l(),n=l();for(const a of t){const t=l(a.datePlannedStart),s=l(a.datePlannedEnd),r=a.dateActualStart?l(a.dateActualStart):null,i=a.dateActualEnd?l(a.dateActualEnd):null;t.isBefore(e)&&(e=t),s.isAfter(n)&&(n=s),r&&r.isBefore(e)&&(e=r),i&&i.isAfter(n)&&(n=i)}return{minDate:e,maxDate:n}}equals(t){var e,n,a,s,r,i,o,d;return this.externalId===t.externalId&&this.parentExternalId===t.parentExternalId&&this.nestingLvl===t.nestingLvl&&this.hasChildren===t.hasChildren&&this.name===t.name&&this.progress===t.progress&&(null===(e=this.datePlannedStart)||void 0===e?void 0:e.unix())===(null===(n=t.datePlannedStart)||void 0===n?void 0:n.unix())&&(null===(a=this.datePlannedEnd)||void 0===a?void 0:a.unix())===(null===(s=t.datePlannedEnd)||void 0===s?void 0:s.unix())&&(null===(r=this.dateActualStart)||void 0===r?void 0:r.unix())===(null===(i=t.dateActualStart)||void 0===i?void 0:i.unix())&&(null===(o=this.dateActualEnd)||void 0===o?void 0:o.unix())===(null===(d=t.dateActualEnd)||void 0===d?void 0:d.unix())}compareTo(t){var e,n,a,s,r,i,o,d,l,h,c,u,p,g,f,m;return this.nestingLvl>t.nestingLvl?1:this.nestingLvl<t.nestingLvl?-1:((null===(e=this.datePlannedStart)||void 0===e?void 0:e.unix())||0)>((null===(n=t.datePlannedStart)||void 0===n?void 0:n.unix())||0)?1:((null===(a=this.datePlannedStart)||void 0===a?void 0:a.unix())||0)<(null===(s=t.datePlannedStart)||void 0===s?void 0:s.unix())?-1:((null===(r=this.datePlannedEnd)||void 0===r?void 0:r.unix())||0)>((null===(i=t.datePlannedEnd)||void 0===i?void 0:i.unix())||0)?1:((null===(o=this.datePlannedEnd)||void 0===o?void 0:o.unix())||0)<((null===(d=t.datePlannedEnd)||void 0===d?void 0:d.unix())||0)?-1:((null===(l=this.dateActualStart)||void 0===l?void 0:l.unix())||0)>((null===(h=t.dateActualStart)||void 0===h?void 0:h.unix())||0)?1:((null===(c=this.dateActualStart)||void 0===c?void 0:c.unix())||0)<((null===(u=t.dateActualStart)||void 0===u?void 0:u.unix())||0)?-1:((null===(p=this.dateActualEnd)||void 0===p?void 0:p.unix())||0)>((null===(g=t.dateActualEnd)||void 0===g?void 0:g.unix())||0)?1:((null===(f=this.dateActualEnd)||void 0===f?void 0:f.unix())||0)<((null===(m=t.dateActualEnd)||void 0===m?void 0:m.unix())||0)?-1:this.name.localeCompare(t.name)}getState(){return 0===this.progress?"not-started":100===this.progress?this.datePlannedEnd&&(this.dateActualEnd&&this.dateActualEnd.isAfter(this.datePlannedEnd)||this.dateActualStart&&this.dateActualStart.isAfter(this.datePlannedEnd))?"completed-late":"completed":this.datePlannedEnd&&this.datePlannedEnd.isBefore(l().startOf("day"))?"overdue":"in-progress"}toModel(){var t,e,n,a;const s={};return Object.assign(s,this),s.id=this.externalId,s.parentId=this.parentExternalId,s.name=this.name,s.progress=this.progress,s.datePlannedStart=(null===(t=this.datePlannedStart)||void 0===t?void 0:t.toDate())||null,s.datePlannedEnd=(null===(e=this.datePlannedEnd)||void 0===e?void 0:e.toDate())||null,s.dateActualStart=(null===(n=this.dateActualStart)||void 0===n?void 0:n.toDate())||null,s.dateActualEnd=(null===(a=this.dateActualEnd)||void 0===a?void 0:a.toDate())||null,s.localizedNames=this.localizedNames,s}toggleExpanded(){this.expanded=!this.expanded}getMinMaxDates(t){const{datePlannedStart:e,datePlannedEnd:n,dateActualStart:a,dateActualEnd:s}=this,r=e&&n,i=a&&s;let o,d;return"both"===t?(i||r)&&(i&&r?(o=e.isBefore(a)?e:a,d=n.isAfter(s)?n:s):r?(o=e,d=n):(o=a,d=s)):"planned"===t&&r?(o=e,d=n):"actual"===t&&i&&(o=a,d=s),{minDate:o,maxDate:d}}getHorizontalOffsetPx(t,e,n){const{minDate:a}=this.getMinMaxDates(t);if(!a)return null;return a.diff(e,"day")*n}updateParents(){}applyChangesFrom(t){this.datePlannedStart=t.datePlannedStart,this.datePlannedEnd=t.datePlannedEnd,this.dateActualStart=t.dateActualStart,this.dateActualEnd=t.dateActualEnd,this.progress=t.progress}clone(){return new c(this)}}c.defaultComparer=(t,e)=>t.compareTo(e);class u{constructor(t){this._tasks=[],this._taskByUuid=new Map,this._tasksByParentUuid=new Map,this._selectedTasks=[],this._options=t}get options(){return this._options}get dateMinOffset(){return this._dateMinOffset}get dateMaxOffset(){return this._dateMaxOffset}get tasks(){return this._tasks}get models(){return this._tasks.map((t=>t.toModel()))}get selectedTasks(){return this._selectedTasks}get selectedModels(){return this._selectedTasks.map((t=>t.toModel()))}getTaskByUuid(t){return this._taskByUuid.get(t)}getAllTasksAsChanged(){const t=this.updateMinMaxDates();return{deleted:[],added:[],changed:this._tasks,all:this._tasks,datesChanged:t}}getShownTaskUuidsRecursively(t=null){const e=this._tasksByParentUuid.get(t)||[],n=[];for(const t of e)n.push(t.uuid),t.expanded&&n.push(...this.getShownTaskUuidsRecursively(t.uuid));return n}updateTasks(t){const e=this._tasks,n=c.createTasksIdMap(e),a=c.convertModelsToTasks(t,n),s=c.detectTaskChanges({oldTasks:e,newTasks:a});this.updateInternalTaskCollections(s.all),this.groupAndSortTasks();const r=this.updateMinMaxDates();return Object.assign({},s,{datesChanged:r})}updateSingleTask(t){const e=this._taskByUuid.get(t.uuid);return e?(e.applyChangesFrom(t),this.options.bindParentDatesToChild,{deleted:[],added:[],changed:[e],all:this._tasks,datesChanged:this.updateMinMaxDates()}):{deleted:[],added:[],changed:[],all:this._tasks,datesChanged:!1}}expandAllTasks(t){for(const e of this._tasks)e.expanded=t,e.parentUuid&&(e.shown=t)}updateSelectedTasks(t){let e;if(!(null==t?void 0:t.length)||t[0]instanceof c)e=t||[];else{const n=new Set(t.map((t=>t.id)));e=this._tasks.filter((t=>n.has(t.externalId)))}const n=this._selectedTasks;if(0===n.length&&0===e.length)return null;const a=n.map((t=>t.uuid)),s=e.map((t=>t.uuid));if(function(t,e){if(t.size!==e.size)return!1;const n=new Set([...t,...e]);return t.size===n.size}(new Set(a),new Set(s)))return{selected:s,selectedTasks:e,deselected:[],deselectedTasks:[],changed:!1};this._selectedTasks=e;const r=n.filter((t=>!s.includes(t.uuid))),i=r.map((t=>t.uuid));return{selected:s,selectedTasks:e,deselected:i,deselectedTasks:r,changed:!0}}refreshSelectedTasks(){const t=this._selectedTasks.filter((t=>!c.checkForCollapsedParent(this._tasks,t)));return this.updateSelectedTasks(t)}toggleTaskSelection(t,e){if(!t)return;const n=[],a=this._selectedTasks.includes(t);return this._options.multilineSelection&&(!this._options.useCtrlKeyForMultilineSelection||this._options.useCtrlKeyForMultilineSelection&&e)?(n.push(...this._selectedTasks),a?n.splice(n.findIndex((e=>e===t)),1):n.push(t)):n.push(t),this.updateSelectedTasks(n)}updateInternalTaskCollections(t){this._tasks=[...t],this._taskByUuid=new Map;for(const e of t)this._taskByUuid.set(e.uuid,e)}groupAndSortTasks(){this._tasksByParentUuid.clear();for(const t of this._tasks)this._tasksByParentUuid.has(t.parentUuid)?this._tasksByParentUuid.get(t.parentUuid).push(t):this._tasksByParentUuid.set(t.parentUuid,[t]);this._tasksByParentUuid.forEach((t=>t.sort(this._options.taskComparer||c.defaultComparer)))}updateMinMaxDates(){const t=this._tasks,e=this._dateMinOffset,n=this._dateMaxOffset,a=this._options.chartScale,s=this._options.chartDateOffsetDaysMin[a],r=this._options.chartDateOffsetDays[a],{minDate:i,maxDate:o}=c.getMinMaxDates(t);return(!e||e.isAfter(i)||i.diff(e,"day")<s)&&(this._dateMinOffset=i.subtract(r,"day")),(!n||n.isBefore(o)||n.diff(o,"day")<s)&&(this._dateMaxOffset=o.add(r,"day")),this._dateMinOffset!==e||this._dateMaxOffset!==n}}class p{static buildFromGanttOptions(t,e){const n=[];let a=0;for(const s of e){const e=t.columnsMinWidthPx[s];if(!e)continue;const r=Object.assign(new p,{minWidth:e,order:a++,header:t.localeHeaders[t.locale][s]||"",textAlign:t.columnsContentAlign[s],valueGetter:t.columnValueGetters[s]||(t=>"")});n.push(r)}return n}}class g{constructor(t){this._columnOrder=Array.from(new Array(t).keys())}move(t,e){this._columnOrder.splice(e,0,this._columnOrder.splice(t,1)[0])}*[Symbol.iterator](){for(const t of this._columnOrder)yield t}}class f{destroy(){this._html.remove()}appendTo(t){t.append(this._html)}}class m extends f{constructor(t,e,n){super(),this._html=this.createElement(t,e,n)}createElement(t,e,n){const a=document.createElement("td");a.classList.add(i.TABLE.BODY_CELL);const s=document.createElement("div");s.classList.add(i.TABLE.BODY_CELL_TEXT_WRAPPER,e),null==n||n.appendTo(s);const r=document.createElement("p");return r.classList.add(i.TABLE.BODY_CELL_TEXT),r.innerHTML=t,s.append(r),a.append(s),a}}class v extends f{constructor(t,e){super(),this._options=t,this._task=e,this._html=this.createElement()}updateSymbol(){const t=this._task,e=this._options.rowSymbols;t.hasChildren?t.expanded?this._html.innerHTML=e.expanded:this._html.innerHTML=e.collapsed:this._html.innerHTML=e.childless}createElement(){const t=this._task,e=document.createElement("p");e.classList.add(i.TABLE.BODY_CELL_EXPANDER);const n=t.nestingLvl;return n&&e.classList.add(i.TABLE.BODY_CELL_EXPANDER_NESTING_PREFIX+(n<10?n:10)),t.hasChildren&&e.addEventListener("click",(n=>{e.dispatchEvent(new CustomEvent(r.TABLE_BODY_CELL_EXPANDER_CLICK,{bubbles:!0,composed:!0,detail:{task:t,event:n}}))})),e}}class _ extends f{constructor(t,e,n){super(),this._task=e,this._expander=new v(t,e),this._html=this.createElement(n,t.highlightRowsDependingOnTaskState)}appendTo(t){this._expander.updateSymbol(),super.appendTo(t)}select(){this._html.classList.add(i.ROOT.ROW_SELECTED)}deselect(){this._html.classList.remove(i.ROOT.ROW_SELECTED)}createElement(t,e){const n=this._task,a=document.createElement("tr");return a.classList.add(i.TABLE.BODY_ROW),a.addEventListener("click",(t=>{t.target.classList.contains(i.TABLE.BODY_CELL_EXPANDER)||a.dispatchEvent(new CustomEvent(r.ROW_CLICK,{bubbles:!0,composed:!0,detail:{task:n,event:t}}))})),a.addEventListener("contextmenu",(t=>{t.target.classList.contains(i.TABLE.BODY_CELL_EXPANDER)||a.dispatchEvent(new CustomEvent(r.ROW_CONTEXT_MENU,{bubbles:!0,composed:!0,detail:{task:n,event:t}}))})),e&&a.classList.add(n.getState()),t.forEach(((t,e)=>{const s=t.valueGetter(n);new m(s,t.textAlign,0===e?this._expander:null).appendTo(a)})),a}}class E extends f{constructor(t){super(),this._dragActive=!1,this.onPointerDownOnResizer=t=>{if(!t.isPrimary||2===t.button)return;const e=t.target;e.addEventListener("pointermove",this.onPointerMoveWhileResizing),e.addEventListener("pointerup",this.onPointerUpWhileResizing),e.addEventListener("pointerout",this.onPointerUpWhileResizing),e.setPointerCapture(t.pointerId),this._dragActive=!0},this.onPointerMoveWhileResizing=t=>{if(!t.isPrimary||!this._dragActive)return!1;const e=this._html.getBoundingClientRect().left,n=t.clientX-e;this._html.style.width=Math.max(this._columnDescriptor.minWidth,n)+"px",t.preventDefault()},this.onPointerUpWhileResizing=t=>{if(!t.isPrimary)return;const e=t.target;e.removeEventListener("pointermove",this.onPointerMoveWhileResizing),e.removeEventListener("pointerup",this.onPointerUpWhileResizing),e.removeEventListener("pointerout",this.onPointerUpWhileResizing),e.releasePointerCapture(t.pointerId),this._dragActive=!1},this._columnDescriptor=t,this._html=this.createElement()}createElement(){const{header:t,order:e,minWidth:n}=this._columnDescriptor,a=document.createElement("th");return a.classList.add(i.TABLE.HEADER),a.dataset.tsgColOrder=e+"",a.style.minWidth=n+"px",a.style.width=n+"px",a.draggable=!0,a.innerHTML=t,a.addEventListener("dragstart",(t=>{t.dataTransfer.setData("application/tsg-col-order",e+"")})),a.addEventListener("dragover",(t=>{t.preventDefault(),t.dataTransfer.dropEffect="move"})),a.addEventListener("drop",(t=>{t.preventDefault();const n=t.dataTransfer.getData("application/tsg-col-order");(n||"0"===n)&&a.dispatchEvent(new CustomEvent(r.TABLE_COLUMN_REORDER,{bubbles:!0,composed:!0,detail:{orderFrom:+n,orderTo:e,event:t}}))})),a.append(this.createResizer()),a}createResizer(){const t=document.createElement("div");return t.classList.add(i.TABLE.COLUMN_RESIZER),t.addEventListener("pointerdown",this.onPointerDownOnResizer),t}}class w extends f{constructor(t){super(),this._html=this.createElement(t)}createElement(t){const e=document.createElement("tr");for(const n of t)new E(n).appendTo(e);return e}}class b{constructor(t){this._activeUuids=[],this._dataRowByTaskUuid=new Map,this.onColumnReorder=t=>{const e=t.detail;e&&this.changeColumnIndex(e.orderFrom,e.orderTo)},this._data=t,this.initBaseHtml(),this.updateColumns(),this._html.addEventListener(r.TABLE_COLUMN_REORDER,this.onColumnReorder)}destroy(){this._html.removeEventListener(r.TABLE_COLUMN_REORDER,this.onColumnReorder),this._html.remove()}appendTo(t){t.append(this._html)}update(t,e,n){t&&this.updateColumns(),e&&this.updateRows(e),n&&(this._activeUuids=n),this.redraw()}applySelection(t){var e,n;const{selected:a,deselected:s}=t;for(const t of s)null===(e=this._dataRowByTaskUuid.get(t))||void 0===e||e.deselect();for(const t of a)null===(n=this._dataRowByTaskUuid.get(t))||void 0===n||n.select();this._lastSelectionResult=t}initBaseHtml(){const t=document.createElement("table");t.classList.add(i.TABLE.MAIN_ELEMENT);const e=t.createTHead(),n=t.createTBody();this._htmlHead=e,this._htmlBody=n,this._html=t}updateColumns(){this._columnOrder||(this._columnOrder=new g(this._data.options.columnsMinWidthPx.length)),this._columnDescriptors=p.buildFromGanttOptions(this._data.options,this._columnOrder),this._headerRow=new w(this._columnDescriptors)}updateRows(t){const e=this._columnDescriptors,n=this._dataRowByTaskUuid;t.deleted.forEach((t=>n.delete(t.uuid)));for(const a of t.changed.concat(t.added))n.set(a.uuid,new _(this._data.options,a,e))}changeColumnIndex(t,e){this._columnOrder.move(t,e),this.updateColumns(),this.updateRows(this._data.getAllTasksAsChanged()),this.redraw(),this.applySelection(this._lastSelectionResult)}redraw(){this._htmlHead.innerHTML="",this._headerRow.appendTo(this._htmlHead),this._htmlBody.innerHTML="",this._activeUuids.forEach((t=>{var e;return null===(e=this._dataRowByTaskUuid.get(t))||void 0===e?void 0:e.appendTo(this._htmlBody)}))}}class y extends CustomEvent{constructor(t){super(r.TASK_CHANGED_IN_CHART,{detail:t})}}class T{constructor(t,e,n){this._options=t,this.drawSvg(e,n)}get width(){return this._width}get height(){return this._height}get xCoords(){return this._xCoords}destroy(){this._svg.remove()}appendTo(t){t.append(this._svg)}createWrapper(t,e){const n=h("svg",[i.CHART.HEADER],[["width",t+""],["height",e+""]]);return h("rect",[i.CHART.HEADER_BACKGROUND],[["width",t+""],["height",e+""]],n),n}drawSvg(t,e){const n=this._options.chartScale,a=this._options.chartDayWidthPx[n],s=this._options.headerHeightPx,r=function(t,e){const n=t.startOf("day"),a=e.startOf("day");if(!n||!a||a.diff(n)<0)return[];if(0===a.diff(n))return[n];const s=[];let r=n;for(;r.isBefore(a)||r.isSame(a);)s.push(r),r=r.add(1,"day");return s}(t,e),i=r.length*a,o=this.createWrapper(i,s),d=this._options.locale,l=this._options.localeDateMonths[d],h=this._options.localeDateDaysShort[d];let c;"year"===n?c=this.drawYearScaledHeaderContent(o,r,e,a,s):"month"===n?c=this.drawMonthScaledHeaderContent(o,l,r,e,s,i,a):"week"!==n&&"day"!==n||(c=this.drawWeekDayScaledHeaderContent(o,l,h,r,e,s,i,a)),this._svg=o,this._width=i,this._height=s,this._xCoords=c}drawHeaderElementWrapper(t,e,n,a,s){return h("svg",[],[["x",e+""],["y",n+""],["width",a+""],["height",s+""]],t)}drawHorizontalBorder(t,e,n){h("line",[i.CHART.HEADER_GRIDLINES],[["x1","0"],["y1",e+""],["x2",n+""],["y2",e+""]],t)}drawVerticalBorder(t,e,n,a){h("line",[i.CHART.HEADER_GRIDLINES],[["x1",e+""],["y1",n+""],["x2",e+""],["y2",n+a+""]],t)}drawText(t,e){h("text",[i.CHART.HEADER_TEXT],[["x","50%"],["y","50%"],["dominant-baseline","middle"],["text-anchor","middle"]],t,e)}drawYear(t,e,n,a,s,r){const i=n-a,o=this.drawHeaderElementWrapper(t,a,s,i,r);i>=60&&this.drawText(o,e.year()+""),this.drawVerticalBorder(t,n,s,r)}drawMonth(t,e,n,a,s,r,i){const o=a-s,d=this.drawHeaderElementWrapper(t,s,r,o,i);if(o>=60){const t=e[n.month()];this.drawText(d,t)}this.drawVerticalBorder(t,a,r,i)}drawDay(t,e,n,a,s,r,i,o){const d=this.drawHeaderElementWrapper(t,a,i,r,o),l=r<30?n.date()+"":e[n.day()]+" "+n.date();this.drawText(d,l),this.drawVerticalBorder(t,s,i,o)}drawWeekDayScaledHeaderContent(t,e,n,a,s,r,i,o){const d=[],l=r/3,h=l,c=2*l;this.drawHorizontalBorder(t,h,i),this.drawHorizontalBorder(t,c,i);let u=0,p=0,g=0;for(const r of a){const a=p+o;(r.isSame(r.endOf("year").startOf("day"))||r.isSame(s))&&(this.drawYear(t,r,a,u,0,l),u=a),(r.isSame(r.endOf("month").startOf("day"))||r.isSame(s))&&(this.drawMonth(t,e,r,a,g,h,l),g=a),this.drawDay(t,n,r,p,a,o,c,l),d.push(a),p=a}return d}drawMonthScaledHeaderContent(t,e,n,a,s,r,i){const o=[],d=s/2,l=d;this.drawHorizontalBorder(t,l,r);let h=0,c=0,u=0;for(const s of n){const n=c+i;(s.isSame(s.endOf("year").startOf("day"))||s.isSame(a))&&(this.drawYear(t,s,n,h,0,d),h=n),(s.isSame(s.endOf("month").startOf("day"))||s.isSame(a))&&(this.drawMonth(t,e,s,n,u,l,d),o.push(n),u=n),c=n}return o}drawYearScaledHeaderContent(t,e,n,a,s){const r=[];let i=0,o=0;for(const d of e){const e=o+a;(d.isSame(d.endOf("year").startOf("day"))||d.isSame(n))&&(this.drawYear(t,d,e,i,0,s),r.push(e),i=e),o=e}return r}}class x{destroy(){this._svg.remove()}appendTo(t){t.append(this._svg)}appendToWithOffset(t,e,n=!1){if(this._svg&&(e||0===e)){if(n){e=(+this._svg.getAttribute("x")||0)+e}this._svg.setAttribute("x",e+""),t.append(this._svg)}}}class D extends x{constructor(t,e,n,a,s){super(),this._options=t.options,this.draw(e,t.dateMinOffset,n,a,s)}applySelection(t){const{selected:e,deselected:n}=t;for(const t of n){const e=this._chartRowBgs.get(t);e&&e.classList.remove(i.ROOT.ROW_SELECTED);const n=this._chartRowFgs.get(t);n&&n.classList.remove(i.ROOT.ROW_SELECTED)}for(const t of e){const e=this._chartRowBgs.get(t);e&&e.classList.add(i.ROOT.ROW_SELECTED);const n=this._chartRowFgs.get(t);n&&n.classList.add(i.ROOT.ROW_SELECTED)}}appendComponentToRow(t,e){const n=this._chartRowFgs.get(t);n&&e.appendTo(n)}draw(t,e,n,a,s){const{dayWidthPx:r,rowHeightPx:i,borderWidthPx:o,drawTodayLine:d}=this._options,l=i*t.length,h=this.createWrapper(a,s,l),c=this.drawRowBackgrounds(h,t.map((t=>t.uuid)),i,s);this.drawChartGridLines(h,t.length,i,s,l,o,n),d&&this.drawTodayLine(h,e,r,l);const u=new Map;t.forEach(((t,e)=>{const n=this.drawRowForeground(h,t,e*i,s,i);u.set(t.uuid,n)})),this._svg=h,this._chartRowBgs=c,this._chartRowFgs=u}drawRowForeground(t,e,n,a,s){const o=h("svg",[i.CHART.ROW_WRAPPER],[["y",n+""],["width",a+""],["height",s+""],["data-tsg-row-uuid",e.uuid]],t);return o.addEventListener("click",(t=>{t.target.classList.contains(i.CHART.BAR.HANDLE)||o.dispatchEvent(new CustomEvent(r.ROW_CLICK,{bubbles:!0,composed:!0,detail:{task:e,event:t}}))})),o.addEventListener("contextmenu",(t=>{o.dispatchEvent(new CustomEvent(r.ROW_CONTEXT_MENU,{bubbles:!0,composed:!0,detail:{task:e,event:t}}))})),h("rect",[i.CHART.ROW],[["width",a+""],["height",s+""]],o),o}drawRowBackground(t,e,n,a){return h("rect",[i.CHART.ROW_BACKGROUND],[["y",e*n+""],["width",a+""],["height",n+""]],t)}drawRowBackgrounds(t,e,n,a){const s=new Map;return e.forEach(((e,r)=>{s.set(e,this.drawRowBackground(t,r,n,a))})),s}drawChartGridLines(t,e,n,a,s,r,i){for(let s=0;s<e;){const e=++s*n-r/2;this.drawHorizontalLine(t,e,a)}i.forEach((e=>{this.drawVerticalLine(t,e,s)}))}drawTodayLine(t,e,n,a){const s=l().startOf("day").diff(e,"day")*n;h("line",[i.CHART.BODY_TODAY_LINE],[["x1",s+""],["y1","0"],["x2",s+""],["y2",a+""]],t)}drawHorizontalLine(t,e,n){h("line",[i.CHART.BODY_GRIDLINES],[["x1","0"],["y1",e+""],["x2",n+""],["y2",e+""]],t)}drawVerticalLine(t,e,n){h("line",[i.CHART.BODY_GRIDLINES],[["x1",e+""],["y1","0"],["x2",e+""],["y2",n+""]],t)}createWrapper(t,e,n){const a=h("svg",[i.CHART.BODY],[["y",t+""],["width",e+""],["height",n+""]]);return h("rect",[i.CHART.BODY_BACKGROUND],[["width",e+""],["height",n+""]],a),a}}class k{static getFromGanttOptions(t){const e=t.chartDisplayMode,n=t.chartShowProgress,a=t.enableChartEdit,s=t.dayWidthPx,r=t.rowHeightPx,i=t.borderWidthPx,o=t.barMarginPx,d=t.barStrokeWidthPx,l=t.barCornerRadiusPx,h=d+2*l,c=o-i/2;let u,p;switch(e){case"both":u=(r-3*o)/2,p=u+2*o-i/2;break;case"planned":case"actual":u=r-2*o}return Object.assign(new k,{mode:e,showProgress:n,showHandles:a,dayWidth:s,rowHeight:r,barMinWidth:h,barHeight:u,barBorder:d,barCornerR:l,y0:c,y1:p})}}class R extends x{constructor(t,e,n){super(),this.onPointerDown=t=>{if(!t.isPrimary||2===t.button)return;const e=t.target;e.addEventListener("pointermove",this.onPointerMove),e.addEventListener("pointerup",this.onPointerUp),e.addEventListener("pointerout",this.onPointerUp),e.setPointerCapture(t.pointerId),this._moveStartCoords={x:t.x,y:t.y}},this.onPointerMove=t=>{if(!this._moveStartCoords||!t.isPrimary)return;const e={x:t.x-this._moveStartCoords.x,y:t.y-this._moveStartCoords.y};(this._lastMoveCoords?Math.abs(t.x-this._lastMoveCoords.x):Math.abs(e.x))>this._descriptor.displacementThreshold&&(this._lastMoveCoords={x:t.x,y:t.y},this._currentDisplacement=e,this._callbackOnMove(e))},this.onPointerUp=t=>{if(!t.isPrimary)return;const e=t.target;e.removeEventListener("pointermove",this.onPointerMove),e.removeEventListener("pointerup",this.onPointerUp),e.removeEventListener("pointerout",this.onPointerUp),e.releasePointerCapture(t.pointerId);const n={x:t.x-this._moveStartCoords.x,y:t.y-this._moveStartCoords.y};this._moveStartCoords=null,this._lastMoveCoords=null,this._currentDisplacement=n,this._callbackOnMoveEnd(this._currentDisplacement)},this._descriptor=t,this._callbackOnMove=e,this._callbackOnMoveEnd=n,this.draw()}draw(){const t=this.createWrapper();this.drawHandle(t).addEventListener("pointerdown",this.onPointerDown),this._svg=t}createWrapper(){const{width:t,height:e}=this._descriptor;return h("svg",[i.CHART.BAR.HANDLE_WRAPPER],[["x","0"],["y","0"],["viewBox","0 0 100 100"],["width",t+""],["height",e+""]])}}class C extends CustomEvent{constructor(t){super(r.HANDLE_MOVE,{detail:t})}}class A extends CustomEvent{constructor(t){super(r.HANDLE_MOVE_END,{detail:t})}}class S extends R{constructor(t){super(t,(e=>{document.dispatchEvent(new C({handleType:"start",displacement:e,taskUuid:t.taskUuid,barType:t.barType}))}),(e=>{document.dispatchEvent(new A({handleType:"start",displacement:e,taskUuid:t.taskUuid,barType:t.barType}))}))}drawHandle(t){return h("polygon",[i.CHART.BAR.HANDLE],[["points","60 25, 60 75, 10 50"]],t)}}class L extends R{constructor(t){super(t,(e=>{document.dispatchEvent(new C({handleType:"end",displacement:e,taskUuid:t.taskUuid,barType:t.barType}))}),(e=>{document.dispatchEvent(new A({handleType:"end",displacement:e,taskUuid:t.taskUuid,barType:t.barType}))}))}drawHandle(t){return h("polygon",[i.CHART.BAR.HANDLE],[["points","40 25, 40 75, 90 50"]],t)}}class O extends R{constructor(t){super(t,(e=>{document.dispatchEvent(new C({handleType:"progress",displacement:e,taskUuid:t.taskUuid,barType:t.barType}))}),(e=>{document.dispatchEvent(new A({handleType:"progress",displacement:e,taskUuid:t.taskUuid,barType:t.barType}))}))}drawHandle(t){return h("circle",[i.CHART.BAR.HANDLE],[["cx","50"],["cy","50"],["r","25"]],t)}}class P extends x{constructor(t){super(),this._descriptor=t,this.draw()}appendToWithOffset(t,e,n=!1){n||(e+=this._defaultOffsetX),super.appendToWithOffset(t,e,n)}hide(){this._svg.style.visibility="hidden"}draw(){const{wrapper:t,bar:e,handles:n}=this.getDrawData(),a=this.createWrapper(t);this.drawTaskBar(a,e),this._descriptor.showProgress&&this.drawProgressBars(a,e),this._descriptor.showHandles&&this.drawHandles(a,n),this._defaultOffsetX=t.left,this._svg=a}getDrawData(){const{minDate:t,startDate:e,endDate:n,dayWidth:a,minWrapperWidth:s,wrapperHeight:r,borderWidth:i,topPosition:o,progress:d}=this._descriptor,l=e.diff(t,"day")*a,h=n.diff(e,"day")+1,c=Math.max(h*a,s),u=c+2*r,p=c-i,g=i/2+r,f=p*d/100,m=f<s-i?0:f;return{wrapper:{width:u,height:r,left:l-r,top:o},bar:{width:p,height:r-i,left:g,top:i/2,progressWidth:m},handles:{width:r,height:r,startHandleOffsetX:0,endHandleOffsetX:u-r,progressHandleOffsetX:g+m-r/2,displacementThreshold:a}}}drawTaskBar(t,e){const{barType:n,cornerRadius:a}=this._descriptor;h("rect","planned"===n?[i.CHART.BAR.PLANNED]:[i.CHART.BAR.ACTUAL],[["x",e.left+""],["y",e.top+""],["width",e.width+""],["height",e.height+""],["rx",a+""],["ry",a+""]],t)}drawProgressBars(t,e){const{barType:n,cornerRadius:a}=this._descriptor;h("rect","planned"===n?[i.CHART.BAR.PLANNED_PROGRESS]:[i.CHART.BAR.ACTUAL_PROGRESS],[["x",e.left+""],["y",e.top+""],["width",e.progressWidth+""],["height",e.height+""],["rx",a+""],["ry",a+""]],t)}drawHandles(t,e){const n={taskUuid:this._descriptor.taskUuid,width:e.width,height:e.height,displacementThreshold:e.displacementThreshold,barType:this._descriptor.barType};new S(n).appendToWithOffset(t,e.startHandleOffsetX);new L(n).appendToWithOffset(t,e.endHandleOffsetX);new O(Object.assign({},n,{displacementThreshold:1})).appendToWithOffset(t,e.progressHandleOffsetX)}createWrapper(t){return h("svg",[i.CHART.BAR.WRAPPER],[["x",t.left+""],["y",t.top+""],["width",t.width+""],["height",t.height+""]])}}class M{constructor(t,e,n){this.task=e,this._descriptor=t,this._minDate=n,this.draw()}set minDate(t){this._minDate=t}hide(){var t;null===(t=this._bars)||void 0===t||t.forEach((t=>{t.hide()}))}destroy(){var t;null===(t=this._bars)||void 0===t||t.forEach((t=>{t.destroy()}))}appendTo(t){var e;if(!(null===(e=this._bars)||void 0===e?void 0:e.length))return;const n=this.task.getHorizontalOffsetPx(this._descriptor.mode,this._minDate,this._descriptor.dayWidth);n&&this._bars.forEach((e=>{e.appendToWithOffset(t,n)}))}draw(){const{mode:t,showProgress:e,showHandles:n,dayWidth:a,barMinWidth:s,barHeight:r,barBorder:i,barCornerR:o,y0:d,y1:l}=this._descriptor,h=this.task,{minDate:c,maxDate:u}=h.getMinMaxDates(t);if(!c||!u)return;const{datePlannedStart:p,datePlannedEnd:g,dateActualStart:f,dateActualEnd:m}=h,v=p&&g,_=f&&m,E={minDate:c,showProgress:e,showHandles:n,dayWidth:a,minWrapperWidth:s,wrapperHeight:r,borderWidth:i,cornerRadius:o,progress:h.progress,taskUuid:h.uuid},w={barType:"planned",startDate:p,endDate:g},b={barType:"actual",startDate:f,endDate:m},y=[];"both"===t?(_||v)&&(v&&y.push(new P(Object.assign({},E,w,{topPosition:d}))),_&&y.push(new P(Object.assign({},E,b,{topPosition:l})))):"planned"===t&&v?y.push(new P(Object.assign({},E,w,{topPosition:d}))):"actual"===t&&_&&y.push(new P(Object.assign({},E,b,{topPosition:d}))),this._bars=y}}class W{constructor(t){this._activeUuids=[],this._barGroups=new Map,this.onHandleMove=t=>{var e;const{taskUuid:n,handleType:a,barType:s,displacement:r}=t.detail;if(this.destroyTempBarGroup(),!this._barGroupDescriptor)return;const i=this._data.getTaskByUuid(n);if(!i)return;const o=this.buildTempTask(i,a,s,this._data.options.dayWidthPx,r.x);null===(e=this._barGroups.get(o.uuid))||void 0===e||e.hide(),this._tempBarGroup=new M(this._barGroupDescriptor,o,this._data.dateMinOffset),this._body.appendComponentToRow(o.uuid,this._tempBarGroup)},this.onHandleMoveEnd=t=>{this._tempBarGroup&&(document.dispatchEvent(new y({manual:!0,task:this._tempBarGroup.task})),this.destroyTempBarGroup())},this._data=t,this._html=this.createChartDiv()}destroy(){this.removeEventListeners(),this._html.remove()}appendTo(t){t.append(this._html),this.addEventListeners()}update(t,e,n){const{options:a,dateMinOffset:s,dateMaxOffset:r}=this._data;((null==e?void 0:e.datesChanged)||t)&&(this._header=new T(a,s,r)),e&&this.updateBarGroups(e),n&&(this._activeUuids=n);const i=this._activeUuids.map((t=>this._barGroups.get(t))),o=i.map((t=>t.task));this._body=new D(this._data,o,this._header.xCoords,this._header.height,this._header.width),i.forEach((t=>this._body.appendComponentToRow(t.task.uuid,t))),this.redraw()}applySelection(t){var e;null===(e=this._body)||void 0===e||e.applySelection(t)}createChartDiv(){const t=document.createElement("div");return t.classList.add(i.CHART.MAIN_ELEMENT),t}updateBarGroups(t){if(t.deleted.concat(t.changed).forEach((t=>{var e;null===(e=this._barGroups.get(t.uuid))||void 0===e||e.destroy(),this._barGroups.delete(t.uuid)})),t.datesChanged){const t=this._data.dateMinOffset;this._barGroups.forEach((e=>e.minDate=t))}this._barGroupDescriptor=k.getFromGanttOptions(this._data.options),t.changed.concat(t.added).forEach((t=>this._barGroups.set(t.uuid,new M(this._barGroupDescriptor,t,this._data.dateMinOffset))))}redraw(){const t=this._html,e=this.createChartDiv();this._header.appendTo(e),this._body.appendTo(e),t.replaceWith(e),this._html=e}addEventListeners(){document.addEventListener(r.HANDLE_MOVE,this.onHandleMove),document.addEventListener(r.HANDLE_MOVE_END,this.onHandleMoveEnd)}removeEventListeners(){document.removeEventListener(r.HANDLE_MOVE,this.onHandleMove),document.removeEventListener(r.HANDLE_MOVE_END,this.onHandleMoveEnd)}buildTempTask(t,e,n,a,s){const r=t.clone(),i=Math.floor(s/a);switch(e){case"start":if("planned"===n){const t=r.datePlannedEnd,e=r.datePlannedStart.add(i,"days");r.datePlannedStart=e.isAfter(t)?t:e}else if("actual"===n){const t=r.dateActualEnd,e=r.dateActualStart.add(i,"days");r.dateActualStart=e.isAfter(t)?t:e}break;case"end":if("planned"===n){const t=r.datePlannedStart,e=r.datePlannedEnd.add(i,"days");r.datePlannedEnd=e.isBefore(t)?t:e}else if("actual"===n){const t=r.dateActualStart,e=r.dateActualEnd.add(i,"days");r.dateActualEnd=e.isBefore(t)?t:e}break;case"progress":const t=r.progress;let e;"planned"===n?e=r.datePlannedEnd.diff(r.datePlannedStart,"days")*a:"actual"===n&&(e=r.dateActualEnd.diff(r.dateActualStart,"days")*a);const o=e*t/100+s,d=Math.floor(Math.max(0,Math.min(100,o/e*100)));r.progress=d}return r}destroyTempBarGroup(){this._tempBarGroup&&(this._tempBarGroup.destroy(),this._tempBarGroup=null)}}class H{constructor(t,e=null){if(this._separatorDragActive=!1,this._ignoreNextScrollEvent=!1,this._baseComponents=[],this.onResize=t=>{const e=this._htmlWrapper.getBoundingClientRect().width,n=this._htmlTableWrapper.getBoundingClientRect().width;this._htmlChartWrapper.style.width=e-n-this._options.separatorWidthPx+"px"},this.onPointerDownOnPartsSeparator=t=>{if(!t.isPrimary||2===t.button)return;const e=t.target;e.addEventListener("pointermove",this.onPointerMoveWhileResizingParts),e.addEventListener("pointerup",this.onPointerUpWhileResizingParts),e.addEventListener("pointerout",this.onPointerUpWhileResizingParts),e.setPointerCapture(t.pointerId),this._separatorDragActive=!0},this.onPointerMoveWhileResizingParts=t=>{if(!this._separatorDragActive)return!1;const e=this._htmlWrapper.getBoundingClientRect(),n=e.left,a=e.width,s=t.clientX-n;this._htmlTableWrapper.style.width=s-this._options.separatorWidthPx+"px",this._htmlChartWrapper.style.width=a-s+"px"},this.onPointerUpWhileResizingParts=t=>{if(!t.isPrimary)return;const e=t.target;e.removeEventListener("pointermove",this.onPointerMoveWhileResizingParts),e.removeEventListener("pointerup",this.onPointerUpWhileResizingParts),e.removeEventListener("pointerout",this.onPointerUpWhileResizingParts),e.releasePointerCapture(t.pointerId),this._separatorDragActive=!1},this.onWrapperScroll=t=>{if(this._ignoreNextScrollEvent)return void(this._ignoreNextScrollEvent=!1);this._ignoreNextScrollEvent=!0;const e=t.currentTarget,n=e.scrollTop;e===this._htmlTableWrapper?this._htmlChartWrapper.scrollTop!==n&&(this._htmlChartWrapper.scrollTop=n):e===this._htmlChartWrapper&&this._htmlTableWrapper.scrollTop!==n&&(this._htmlTableWrapper.scrollTop=n)},this.onRowClick=t=>{const e=t.detail;if(!e)return;const{task:n,event:a}=e;1===a.detail?(this.toggleTaskSelection(n,a.ctrlKey),this.onRowClickCb&&this.onRowClickCb(n.toModel(),a)):2===a.detail&&this.onRowDoubleClickCb&&this.onRowDoubleClickCb(n.toModel(),a)},this.onRowContextMenu=t=>{const e=t.detail;if(!e)return;const{task:n,event:a}=e;this.onRowContextMenuCb&&this.onRowContextMenuCb(n.toModel(),a)},this.onRowExpanderClick=t=>{this.toggleTaskExpanded(t.detail.task)},this.onTaskChange=t=>{var e,n;if(!(null===(e=t.detail)||void 0===e?void 0:e.task))return;const a=this._data.updateSingleTask(t.detail.task);(null===(n=a.changed)||void 0===n?void 0:n.length)&&this.update(a)},e=e instanceof o?e:new o(e),this._data=new u(e),this.setCssVariables(this._options),this._htmlContainer=document.querySelector(t),!this._htmlContainer)throw new Error("Container is null");this.createLayout()}get _options(){var t;return null===(t=this._data)||void 0===t?void 0:t.options}get tasks(){return this._data.models}set tasks(t){this.updateTasks(t)}get selectedTasks(){return this._data.selectedModels}set selectedTasks(t){this.updateSelection(t)}set locale(t){t!==this._options.locale&&(this._options.locale=t,this.updateLocale())}set chartScale(t){t!==this._options.chartScale&&(this._options.chartScale=t,this.updateChartScale())}set chartDisplayMode(t){t!==this._options.chartDisplayMode&&(this._options.chartDisplayMode=t,this.updateChartDisplayMode())}destroy(){this.removeGlobalEventListeners(),this._baseComponents.forEach((t=>t.destroy())),this._htmlWrapper.remove()}expandAll(t){this._data.expandAllTasks(t),this.update(null)}setCssVariables(r){document.documentElement.style.setProperty(t,r.separatorWidthPx+"px"),document.documentElement.style.setProperty(e,r.headerHeightPx+"px"),document.documentElement.style.setProperty(n,r.rowHeightPx+"px"),document.documentElement.style.setProperty(a,r.borderWidthPx+"px"),document.documentElement.style.setProperty(s,r.barStrokeWidthPx+"px")}createLayout(){const t=document.createElement("div");t.classList.add(i.ROOT.MAIN_ELEMENT,i.ROOT.TEXT_SELECTION_DISABLED);const e=document.createElement("div");e.classList.add(i.ROOT.TABLE_WRAPPER);const n=document.createElement("div");n.classList.add(i.ROOT.CHART_WRAPPER);const a=document.createElement("div");a.classList.add(i.ROOT.SEPARATOR),this._table=new b(this._data),this._chart=new W(this._data),this._baseComponents.push(this._table,this._chart),t.append(e),t.append(a),t.append(n),this._table.appendTo(e),this._chart.appendTo(n),e.addEventListener("scroll",this.onWrapperScroll),n.addEventListener("scroll",this.onWrapperScroll),a.addEventListener("pointerdown",this.onPointerDownOnPartsSeparator),this._options.useShadowDom?(this._shadowRoot=this._htmlContainer.attachShadow({mode:"open"}),this._shadowRoot.innerHTML="\n<style>\n :host {\n --tsg-table-min-width-final: var(--tsg-table-min-width, 100px);\n --tsg-chart-min-width-final: var(--tsg-chart-min-width, 100px);\n --tsg-nesting-indent-final: var(--tsg-nesting-indent, 20px);\n\n --tsg-background-color-final: var(--tsg-background-color, white);\n --tsg-foreground-color-final: var(--tsg-foreground-color, black);\n --tsg-separator-color-final: var(--tsg-separator-color, dimgray);\n --tsg-header-color-final: var(--tsg-header-color, ghostwhite);\n --tsg-border-color-final: var(--tsg-border-color, lightgray);\n --tsg-symbol-color-final: var(--tsg-symbol-color, dimgray);\n --tsg-selection-color-final: var(--tsg-selection-color, ghostwhite);\n --tsg-scrollbar-track-color-final: var(--tsg-scrollbar-track-color, #eeeeee);\n --tsg-scrollbar-thumb-color-final: var(--tsg-scrollbar-thumb-color, #b0b0b0);\n\n --tsg-not-started-fg-color-final: var(--tsg-not-started-f