");
+ $target.dialog({
+ width: width,
+ appendTo: document.body,
+ modal: true,
+ resizable: false,
+ dialogClass: 'modal'
+ });
+ $target.dialog("close");
+ }
+ return $target;
+ },
+ startsWith: function (text, char) {
+ if (text.startsWith) {
+ return text.startsWith(char);
+ }
+ return text.toString().charAt(0) === char;
+ },
+ isSameMoment: function (date1, date2) {
+ if (!moment.isMoment(date1)) return false;
+ if (!moment.isMoment(date2)) return false;
+ return date1.isSame(date2);
+ },
+ /**
+ * Utility function for measuring performance of some code
+ * @example
+ * var perf = createPerformanceMeter("myFunction");
+ * perf("part 1");
+ * perf("part 2");
+ * perf.whole();
+ * @param {String} groupName
+ * @return {Function}
+ */
+ createPerformanceMeter: function (groupName) {
+ var lastTime = window.performance.now();
+ var silence = false;
+ var initTime = lastTime;
+ var func = function (/** @param {String} name*/ name) {
+ if (silence) return;
+ var nowTime = window.performance.now();
+ var nameString = groupName + " " + name + ": ";
+ nameString = nameString.substr(0, 30);
+ var diffString = " " + (nowTime - lastTime).toFixed(3);
+ diffString = diffString.substr(diffString.length - 10);
+ console.debug(nameString + diffString + " ms");
+ lastTime = nowTime;
+ };
+ func.whole = function () {
+ if (silence) return;
+ var nowTime = window.performance.now();
+ var nameString = groupName + ": ";
+ nameString = nameString.substr(0, 30);
+ var diffString = " " + (nowTime - initTime).toFixed(3);
+ diffString = diffString.substr(diffString.length - 10);
+ console.debug(nameString + diffString + " ms");
+ };
+ func.silence = function (verbose) {
+ silence = !verbose;
+ };
+ return func;
+ },
+ /**
+ *
+ * @param {Array.<{name:String,value:String}>} formData
+ * @return {Object}
+ */
+ formToJson: function (formData) {
+ var result = {};
+ var prolong = function (result, split, value) {
+ var key = split.shift();
+ if (key === "") {
+ result.push(value);
+ } else {
+ if (split.length > 0) {
+ var next = split[0];
+ if (!result[key]) {
+ if (next === "") {
+ result[key] = [];
+ } else {
+ result[key] = {};
+ }
+ }
+ prolong(result[key], split, value);
+ } else {
+ result[key] = value;
+ }
+ }
+ };
+ for (var i = 0; i < formData.length; i++) {
+ var split = formData[i].name.split(/]\[|\[|]/);
+ if (split.length > 1) {
+ split.pop();
+ }
+ prolong(result, split, formData[i].value);
+ }
+ return result;
+ },
+ escapeText: function (text) {
+ var tmp = document.createElement('div');
+ tmp.appendChild(document.createTextNode(text));
+ return tmp.innerHTML;
+ }
+});
\ No newline at end of file
diff --git a/plugins/easy_gantt/assets/javascripts/easy_gantt/view.js b/plugins/easy_gantt/assets/javascripts/easy_gantt/view.js
new file mode 100644
index 0000000..97b1d77
--- /dev/null
+++ b/plugins/easy_gantt/assets/javascripts/easy_gantt/view.js
@@ -0,0 +1,48 @@
+/* view.js */
+/* global ysy */
+window.ysy = window.ysy || {};
+ysy.view = ysy.view || {};
+$.extend(ysy.view, {
+ onRepaint: [],
+ patch: function () {
+ this.applyGanttRewritePatch();
+ this.addGanttAddons();
+ this.applyGanttPatch();
+ if (!window.initEasyAutocomplete) {
+ window.initEasyAutocomplete = function () {
+ };
+ }
+ if (ysy.settings.easyRedmine && $("#content").children(".easy-content-page").length === 0) {
+ $("#easy_gantt").addClass("easy-content-page");
+ }
+ },
+ start: function () {
+ this.labels = ysy.settings.labels;
+ var main = new ysy.view.Main();
+ main.init(ysy.data.projects);
+ this.anim();
+ },
+ anim: function () {
+ var view = ysy.view;
+ for (var i = 0; i < view.onRepaint.length; i++) {
+ view.onRepaint[i]();
+ }
+ //requestAnimFrame($.proxy(this.anim, this));
+ requestAnimFrame(view.anim);
+ },
+ getTemplate: function (name) {
+ return this.templates[name];
+ },
+ getLabel: function () {
+ var temp = this.labels;
+ for (var i = 0; i < arguments.length; i++) {
+ var arg = arguments[i];
+ if (temp[arg]) {
+ temp = temp[arg];
+ } else {
+ return temp;
+ }
+ }
+ return temp;
+ }
+});
diff --git a/plugins/easy_gantt/assets/javascripts/easy_gantt/widget.js b/plugins/easy_gantt/assets/javascripts/easy_gantt/widget.js
new file mode 100644
index 0000000..77c618a
--- /dev/null
+++ b/plugins/easy_gantt/assets/javascripts/easy_gantt/widget.js
@@ -0,0 +1,266 @@
+/* widget.js */
+/* global ysy */
+window.ysy = window.ysy || {};
+ysy.view = ysy.view || {};
+ysy.view.Widget = function () {
+ /*
+ *Widget class is a base class for all other Widgets.
+ *It implement basic repaint, init and _register functions, which in most cases dont have to changed.
+ */
+ //this.template = null; // nutne zakomentovat, aby to
+ this.$target = null;
+ this.parent = null;
+ this.children = [];
+ this.repaintRequested = true;
+ this.keepPaintedState = false;
+ this.deleted = false;
+ this.regs = [null, null, null, null];
+};
+ysy.view.Widget.prototype = {
+ name: "Widget",
+ init: function (modl) {
+ if (modl instanceof Array) {
+ ysy.log.error("Array Model");
+ }
+ if (this.model) {
+ this.model.unregister(this);
+ }
+ if (arguments.length > 1) {
+ for (var i = 1; i < arguments.length; i++) {
+ if (!arguments[i]) continue;
+ this._register(arguments[i], i);
+ }
+ }
+ if (modl) {
+ this.model = modl;
+ this._register(modl);
+ }
+ this._updateChildren();
+ this._postInit();
+ return this;
+ },
+ requestRepaint: function () {
+ this.repaintRequested = true;
+ },
+ _updateChildren: function () {
+ },
+ _postInit: function () {
+ },
+ _register: function (model, pos) {
+ //if (model === undefined) {
+ // ysy.log.error("no model for register in "+this.name);
+ //}
+ if (!model) return;
+ if (pos) {
+ if (this.regs[pos]) {
+ this.regs[pos].unregister(this);
+ }
+ this.regs[pos] = model;
+ }
+ model.register(function () {
+ this._updateChildren();
+ this.requestRepaint();
+ }, this);
+ },
+ out: function () {
+
+ },
+ repaint: function (force) {
+ if (this.hidden) {
+ this.repaintRequested = true;
+ return;
+ }
+ if (this.keepPaintedState) {
+ this.onNoRepaint();
+ return;
+ }
+ if (this.repaintRequested || force) {
+ ysy.log.log("--- RepaintCore in " + this.name);
+ this.repaintRequested = !!this._repaintCore();
+ } else {
+ this.onNoRepaint();
+ for (var i = 0; i < this.children.length; i++) {
+ this.children[i].repaint();
+ }
+ }
+ },
+ _repaintCore: function () {
+ if (!this.template) {
+ var templ = ysy.view.getTemplate(this.templateName);
+ if (templ) {
+ this.template = templ;
+ } else {
+ return true;
+ }
+ }
+ if (this.$target === null) {
+ throw "Target is null for " + this.templateName;
+ }
+ this.$target.html(Mustache.render(this.template, this.out() || {})); // REPAINT
+ this.tideFunctionality(); // TIDE FUNCTIONALITY
+ for (var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ this.setChildTarget(child, i); // SET CHILD TARGET
+ child.repaint(true); // CHILD REPAINT
+ }
+ return false;
+ },
+ onNoRepaint: function () {
+
+ },
+ tideFunctionality: function () {
+
+ },
+ setChildTarget: function (child, i) {
+
+ },
+ destroy: function () {
+ this.deleted = true;
+ },
+ _getChildByID: function (id) {
+ for (var i = 0; i < this.children.length; i++) {
+ if (this.children[i].id === id) {
+ return this.children[i];
+ }
+ }
+ return null;
+ },
+ _getChildByName: function (name) {
+ for (var i = 0; i < this.children.length; i++) {
+ if (this.children[i].name === name) {
+ return this.children[i];
+ }
+ }
+ return null;
+ }
+};
+ysy.view.Main = function () {
+ ysy.view.Widget.call(this);
+ this.name = "MainWidget";
+};
+ysy.main.extender(ysy.view.Widget, ysy.view.Main, {
+ init: function (mod) {
+ this.$target = $("#easy_gantt");
+ this.model = mod;
+ ysy.view.onRepaint.push($.proxy(this.repaint, this));
+ this._register(null);
+ this._updateChildren();
+ ysy.view.mainWidget = this;
+ },
+ _updateChildren: function () {
+ if (this.children.length > 0) {
+ return;
+ }
+ var toolbars = new ysy.view.Toolbars();
+ toolbars.init();
+ toolbars.$target = $("#content");
+ this.children.push(toolbars);
+
+ var mainGantt = new ysy.view.Gantt();
+ mainGantt.$target = $("#gantt_cont")[0];
+ mainGantt.init(/*ysy.data.limits,*//*ysy.data.loader,*/ ysy.data.baselines);
+ this.children.push(mainGantt);
+ },
+ _repaintCore: function () {
+ for (var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ this.setChildTarget(child, i);
+ child.repaint(true);
+ }
+ },
+ setChildTarget: function (child/*, i*/) {
+ //if (this.childTargets[child.name]) {
+ // child.$target = this.$target.find(this.childTargets[child.name]);
+ //}
+ //if (child.name === "AllButtonsWidget") {
+ // child.$target = $("#content");
+ //}
+ }
+});
+//##############################################################################
+
+//##############################################################################
+
+//##############################################################################
+ysy.view.LinkPopup = function () {
+ ysy.view.Widget.call(this);
+};
+ysy.main.extender(ysy.view.Widget, ysy.view.LinkPopup, {
+ name: "PopupWidget",
+ templateName: "LinkConfigPopup",
+ init: function (model, dhtml) {
+ if (this.model) {
+ this.model.unregister(this);
+ }
+ this.model = model;
+ this.dhtml = dhtml;
+ this._register(model);
+ return this;
+ },
+ requestRepaint: function () {
+ ysy.log.debug("Popup requestRepaint()", "link_config");
+ //this.$target.hide();
+ },
+ out: function () {
+ ysy.log.debug("Popup out()", "link_config");
+ var delayLabels = ysy.view.getLabel("delay");
+ var buttonLabels = ysy.view.getLabel("buttons");
+ return {
+ readonly:this.dhtml.readonly,
+ title: delayLabels.title,
+ delay: this.dhtml.delay,
+ label_delay: delayLabels.label,
+ button_delete: buttonLabels.button_delete,
+ button_submit: buttonLabels.button_submit,
+ minimal:ysy.settings.workDayDelays?-1:""
+ };
+ },
+ tideFunctionality: function () {
+ var model = this.model;
+ var dhtml = this.dhtml;
+ var $target = this.$target;
+ var sourceIssue = gantt.getTask(dhtml.source);
+ var targetIssue = gantt.getTask(dhtml.target);
+ if (!ysy.settings.easyRedmine) $target.addClass("redmine");
+ var close = function () {
+ ysy.log.debug("close link popup", "link_config");
+ hideModal();
+ };
+ $target.find("#link_delete").on("click", function () {
+ model.remove();
+ close();
+ });
+ $target.keyup(function (event) {
+ if (event.keyCode == 13) {
+ $("#link_close").click();
+ }
+ });
+ $target.find("#link_close").on("click", function () {
+ var delay = parseInt($target.find("#link_delay_input").val());
+ if (!isNaN(delay) && delay < -1 ){
+ delay = -1;
+ showFlashMessage("warning", Mustache.render(ysy.settings.labels.warnings.change_link_length, {
+ source_task: sourceIssue.text,
+ target_task: targetIssue.text,
+ minimum_link_length: -1
+ }), 15000);
+ }
+ close();
+ if (isNaN(delay) || delay === dhtml.delay) return;
+ if(ysy.settings.workDayDelays && delay < -1) return;
+ dhtml.delay = delay || 0;
+ dhtml.widget.update(dhtml);
+ });
+ $target.find("#link_fix_actual").on("click", function () {
+ var delay = model.getActDelay();
+ close();
+ dhtml.delay = delay || 0;
+ dhtml.widget.update(dhtml);
+ });
+ $target.find("#link_remove_delay").on("click", function () {
+ close();
+ dhtml.delay = 0;
+ dhtml.widget.update(dhtml);
+ });
+ }
+});
diff --git a/plugins/easy_gantt/assets/stylesheets/easy_gantt/dhtmlxgantt.css b/plugins/easy_gantt/assets/stylesheets/easy_gantt/dhtmlxgantt.css
new file mode 100644
index 0000000..2ee152a
--- /dev/null
+++ b/plugins/easy_gantt/assets/stylesheets/easy_gantt/dhtmlxgantt.css
@@ -0,0 +1,1367 @@
+/*
+@license
+
+dhtmlxGantt v.3.2.1 Stardard
+This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
+
+(c) Dinamenta, UAB.
+*/
+
+.gridHoverStyle,
+.gridSelection,
+.timelineSelection {
+ background-color: #fff3a1
+}
+.gantt_grid_scale .gantt_grid_head_cell {
+ color: #a6a6a6;
+ border-top: none!important;
+ /*border-right: none!important*/
+}
+/*.gantt_grid_data .gantt_cell {
+ border-right: none;
+ color: #454545
+}*/
+.gantt_task_link .gantt_link_arrow_right {
+ border-width: 6px;
+ margin-top: -3px
+}
+.gantt_task_link .gantt_link_arrow_left {
+ border-width: 6px;
+ margin-left: -6px;
+ margin-top: -3px
+}
+.gantt_task_link .gantt_link_arrow_down,
+.gantt_task_link .gantt_link_arrow_top {
+ border-width: 6px
+}
+.gantt_task_line .gantt_task_progress_drag {
+ bottom: -4px;
+ height: 16px;
+ margin-left: -8px;
+ width: 16px
+}
+.chartHeaderBg {
+ background-color: #fff
+}
+.gantt_task .gantt_task_scale .gantt_scale_cell {
+ color: #a6a6a6;
+ border-right: 1px solid #ebebeb
+}
+
+/*.gantt_row.gantt_project-type,*/
+/*.gantt_row.odd.gantt_project-type {*/
+/*background-color: #edffef*/
+/*}*/
+.gantt_task_row.gantt_project-type,
+.gantt_task_row.odd.gantt_project-type {
+ background-color: #f5fff6
+}
+.gantt_task_line.gantt_project-type {
+ background-color: #65c16f;
+ border: 1px solid #3c9445
+}
+.gantt_task_line.gantt_project-type .gantt_task_progress {
+ background-color: #46ad51
+}
+.buttonBg {
+ background: #fff
+}
+.gantt_cal_light .gantt_btn_set {
+ margin: 5px 10px
+}
+.gantt_btn_set.gantt_cancel_btn_set {
+ background: #fff;
+ color: #454545;
+ border: 1px solid #cecece
+}
+.gantt_btn_set.gantt_save_btn_set {
+ background: #3db9d3;
+ text-shadow: 0 -1px 0 #248a9f;
+ color: #fff
+}
+.gantt_btn_set.gantt_delete_btn_set {
+ background: #ec8e00;
+ text-shadow: 0 -1px 0 #a60;
+ color: #fff
+}
+.gantt_cal_light_wide {
+ padding-left: 0!important;
+ padding-right: 0!important
+}
+.gantt_cal_light_wide .gantt_cal_larea {
+ border-left: none!important;
+ border-right: none!important
+}
+.dhtmlx_popup_button.dhtmlx_ok_button {
+ background: #3db9d3;
+ text-shadow: 0 -1px 0 #248a9f;
+ color: #fff;
+ font-weight: 700;
+ border-width: 0
+}
+.dhtmlx_popup_button.dhtmlx_cancel_button {
+ font-weight: 700;
+ color: #454544
+}
+.gantt_qi_big_icon.icon_edit {
+ color: #454545;
+ background: #fff
+}
+.gantt_qi_big_icon.icon_delete {
+ text-shadow: 0 -1px 0 #a60;
+ background: #ec8e00;
+ color: #fff;
+ border-width: 0
+}
+.gantt_container {
+ font-family: Arial;
+ font-size: 13px;
+ border: 1px solid #cecece;
+ position: relative;
+ white-space: nowrap
+}
+.gantt_grid {
+ border-right: 1px solid #cecece
+}
+.gantt_task_scroll {
+ overflow-x: scroll
+}
+.gantt_task {
+ position: relative
+}
+.gantt_grid,
+.gantt_task {
+ overflow-x: hidden;
+ overflow-y: hidden;
+ display: inline-block;
+ vertical-align: top
+}
+.gantt_grid_scale,
+.gantt_task_scale {
+ color: #6b6b6b;
+ font-size: 12px;
+ border-bottom: 1px solid #cecece;
+ background-color: #fff
+}
+.gantt_scale_line {
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ border-top: 1px solid #cecece
+}
+.gantt_scale_line:first-child {
+ border-top: none
+}
+.gantt_grid_head_cell {
+ display: inline-block;
+ vertical-align: top;
+ border-right: 1px solid #cecece;
+ text-align: center;
+ position: relative;
+ cursor: default;
+ height: 100%;
+ -moz-user-select: -moz-none;
+ -webkit-user-select: none;
+ -user-select: none;
+ -ms-user-select: none;
+ overflow: hidden
+}
+.gantt_scale_line {
+ clear: both
+}
+.gantt_grid_data {
+ width: 100%;
+ overflow: hidden
+}
+.gantt_row {
+ position: relative;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -moz-user-select: -moz-none
+}
+.gantt_add,
+.gantt_grid_head_add {
+ width: 100%;
+ height: 100%;
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTQ3MjMyMENDNkI0MTFFMjk4MTI5QTg3MDhFNDVDQTkiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTQ3MjMyMERDNkI0MTFFMjk4MTI5QTg3MDhFNDVDQTkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1NDcyMzIwQUM2QjQxMUUyOTgxMjlBODcwOEU0NUNBOSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1NDcyMzIwQkM2QjQxMUUyOTgxMjlBODcwOEU0NUNBOSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PshZT8UAAABbSURBVHjaYrTdeZmBEsCER+4wEP+H4sPkGGCDg020ARR7gb4GIAcYDKMDdPnDyAbYkGG5DVW9cIQMvUdBBAuUY4vDz8iAcZinA2zgCHqAYQMseAywJcYFAAEGAM+UFGuohFczAAAAAElFTkSuQmCC);
+ background-position: center center;
+ background-repeat: no-repeat;
+ cursor: pointer;
+ position: relative;
+ -moz-opacity: .3;
+ opacity: .3
+}
+.gantt_grid_head_cell.gantt_grid_head_add {
+ -moz-opacity: .6;
+ opacity: .6;
+ top: 0
+}
+.gantt_grid_head_cell.gantt_grid_head_add:hover {
+ -moz-opacity: 1;
+ opacity: 1
+}
+@media screen {
+ .gantt_grid_data .gantt_row.odd:hover,
+ .gantt_grid_data .gantt_row:hover {
+ background-color: #fff3a1
+ }
+}
+.gantt_grid_data .gantt_row.odd:hover .gantt_add,
+.gantt_grid_data .gantt_row:hover .gantt_add {
+ -moz-opacity: 1;
+ opacity: 1
+}
+.gantt_row,
+.gantt_task_row {
+ border-bottom: 1px solid #ebebeb;
+ /*background-color: #fff*/
+}
+.gantt_row.odd,
+.gantt_task_row.odd {
+ /*background-color: #fff*/
+}
+.gantt_cell,
+.gantt_grid_head_cell,
+.gantt_row,
+.gantt_scale_cell,
+.gantt_task_cell,
+.gantt_task_row {
+ box-sizing: border-box;
+ -moz-box-sizing: border-box
+}
+.gantt_grid_head_cell,
+.gantt_scale_cell {
+ line-height: inherit
+}
+.gantt_grid .gantt_grid_resize_wrap {
+ cursor: col-resize;
+ position: absolute;
+ width: 13px;
+ z-index: 1
+}
+.gantt_grid_resize_wrap .gantt_grid_resize {
+ background-color: #cecece;
+ width: 1px;
+ margin: 0 auto
+}
+.gantt_drag_marker.gantt_grid_resize_area {
+ background-color: rgba(231, 231, 231, .5);
+ border-left: 1px solid #cecece;
+ border-right: 1px solid #cecece;
+ height: 100%;
+ width: 100%;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box
+}
+.gantt_cell {
+ display: inline-block;
+ vertical-align: top;
+ border-right: 1px solid #ebebeb;
+ padding-left: 6px;
+ padding-right: 6px;
+ height: 100%;
+ overflow: hidden;
+ white-space: nowrap;
+ font-size: 13px
+}
+.gantt_grid_data .gantt_last_cell,
+.gantt_grid_scale .gantt_last_cell,
+.gantt_task_bg .gantt_last_cell,
+.gantt_task_scale .gantt_last_cell {
+ border-right-width: 0
+}
+.gantt_task_bg {
+ overflow: hidden
+}
+.gantt_scale_cell {
+ display: inline-block;
+ white-space: nowrap;
+ overflow: hidden;
+ border-right: 1px solid #cecece;
+ text-align: center;
+ height: 100%
+}
+.gantt_task_cell {
+ display: inline-block;
+ height: 100%;
+ border-right: 1px solid #ebebeb
+}
+.gantt_ver_scroll {
+ width: 0;
+ background-color: transparent;
+ height: 1px;
+ overflow-x: hidden;
+ overflow-y: scroll;
+ display: none;
+ position: absolute;
+ right: 0
+}
+.gantt_ver_scroll>div {
+ width: 1px;
+ height: 1px
+}
+.gantt_hor_scroll {
+ height: 0;
+ background-color: transparent;
+ width: 100%;
+ clear: both;
+ overflow-x: scroll;
+ overflow-y: hidden;
+ display: none
+}
+.gantt_hor_scroll>div {
+ width: 5000px;
+ height: 1px
+}
+.gantt_tree_indent {
+ width: 15px;
+ /*height: 100%;*/
+ display: inline-block
+}
+.gantt_tree_content,
+.gantt_tree_icon {
+ vertical-align: top
+}
+.gantt_tree_icon {
+ width: 28px;
+ height: 100%;
+ display: inline-block;
+ background-repeat: no-repeat;
+ background-position: center center
+}
+.gantt_tree_content {
+ height: 100%;
+ display: inline-block
+}
+.gantt_tree_icon.gantt_open {
+ background-image: url(data:image/gif;base64,R0lGODlhEgASALMJAMrKyt3d3ejp6d7f3+/v75aWlvf39////wAAAP///wAAAAAAAAAAAAAAAAAAAAAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6M0I5RTczQjVDMDdBMTFFMTgxRjc4Mzk4M0Q3MjVFQzAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6M0I5RTczQjZDMDdBMTFFMTgxRjc4Mzk4M0Q3MjVFQzAiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDozQjlFNzNCM0MwN0ExMUUxODFGNzgzOTgzRDcyNUVDMCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDozQjlFNzNCNEMwN0ExMUUxODFGNzgzOTgzRDcyNUVDMCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAkALAAAAAASABIAAARJMMlJq704661B+SAIXAVhnKhBFKSZnmuLImhslXPN3ibi+6pdBXc4IIpB2YkGE1IKAoL0ICUInJNCYMDtDgJYiScUGnHO6LQkAgA7);
+ width: 18px;
+ cursor: pointer
+}
+.gantt_tree_icon.gantt_close {
+ background-image: url(data:image/gif;base64,R0lGODlhEgASALMJAMrKyt3d3ejp6d7f3+/v75aWlvf39wAAAP///////wAAAAAAAAAAAAAAAAAAAAAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MzY0QzNGM0VDMDdBMTFFMUE3MDlCNUM2QjU1NDA5RjgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MzY0QzNGM0ZDMDdBMTFFMUE3MDlCNUM2QjU1NDA5RjgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDozNjRDM0YzQ0MwN0ExMUUxQTcwOUI1QzZCNTU0MDlGOCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDozNjRDM0YzREMwN0ExMUUxQTcwOUI1QzZCNTU0MDlGOCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAkALAAAAAASABIAAARDMMlJq704661B+SAIXAVhnKhBFKSZnmv7wqxVzmpd3Uff5zKEUAi0uV4xm4DAbBIEOkohMKhaB4HoxBMKjTjgsFgSAQA7);
+ width: 18px;
+ cursor: pointer
+}
+.gantt_tree_icon.gantt_blank {
+ width: 18px
+}
+.gantt_tree_icon.gantt_folder_open {
+ background-image: url(data:image/gif;base64,R0lGODlhEgASAJECAJeXl7Gvrf///wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTdDRDM3QzVDMDZEMTFFMUJGMzhFMDhCN0RGRjBGQ0YiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTdDRDM3QzZDMDZEMTFFMUJGMzhFMDhCN0RGRjBGQ0YiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1N0NEMzdDM0MwNkQxMUUxQkYzOEUwOEI3REZGMEZDRiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1N0NEMzdDNEMwNkQxMUUxQkYzOEUwOEI3REZGMEZDRiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAIALAAAAAASABIAAAIzlI+pywcPm3mhWgkCsjBOvVkimElG9ZlCBlXd+2XjjLKg5GqoeZXqvsOQXK/ijUZTKVUFADs=)
+}
+.gantt_tree_icon.gantt_folder_closed {
+ background-image: url(data:image/gif;base64,R0lGODlhEgASAJECAJeXl7Gvrf///wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTAyMTU1RTNDMDZEMTFFMUJGNzZCRThBRkFCRjg4MTIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTAyMTU1RTRDMDZEMTFFMUJGNzZCRThBRkFCRjg4MTIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1MDIxNTVFMUMwNkQxMUUxQkY3NkJFOEFGQUJGODgxMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1MDIxNTVFMkMwNkQxMUUxQkY3NkJFOEFGQUJGODgxMiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAIALAAAAAASABIAAAIwlI+pywcPm3mhWgkCsjBOvVkimElG9ZlCuYIY6TYs+6bmHDO4igfdD3GNhheV0VQAADs=)
+}
+.gantt_tree_icon.gantt_file {
+ background-image: url(data:image/gif;base64,R0lGODlhEgASAJECAJeXl7Gvrf///wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzkxQzI4RjZDMDZEMTFFMTgwRjhBQURDQzI3NDU3QUEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzkxQzI4RjdDMDZEMTFFMTgwRjhBQURDQzI3NDU3QUEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3OTFDMjhGNEMwNkQxMUUxODBGOEFBRENDMjc0NTdBQSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3OTFDMjhGNUMwNkQxMUUxODBGOEFBRENDMjc0NTdBQSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAIALAAAAAASABIAAAIylI+pwN16QJiUQiFThRlJm3RRFYSlR5qXMKmXaMDuuMoyOi8n/e6xn8NMHETgh5RaKQsAOw==)
+}
+.gantt_grid_head_cell .gantt_sort {
+ position: absolute;
+ right: 5px;
+ top: 8px;
+ width: 7px;
+ height: 13px;
+ background-repeat: no-repeat;
+ background-position: center center
+}
+.gantt_grid_head_cell .gantt_sort.gantt_asc {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAANCAYAAABlyXS1AAAARUlEQVR4nGNgQAKGxib/GbABkIS7b8B/DAUwCRiGK0CXwFBAb1DfP/U/LszwHwi2X7qFgUEArBtdAVwCBmAKMCSQFSDzAWXXaOHsXeqkAAAAAElFTkSuQmCC)
+}
+.gantt_grid_head_cell .gantt_sort.gantt_desc {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAANCAYAAABlyXS1AAAARUlEQVR42mNgQAL1/VP/M2ADIIntF2/9x1AAlrh0C47hCmA60DFYwX88gIFGwNDY5D8uDFbg7hvwHx2jmIBTAlkB0e4BAEjlaNtBWJPnAAAAAElFTkSuQmCC)
+}
+.gantt_inserted,
+.gantt_updated {
+ font-weight: 700
+}
+.gantt_deleted {
+ text-decoration: line-through
+}
+.gantt_invalid {
+ background-color: #FFE0E0
+}
+.gantt_error {
+ color: red
+}
+.gantt_status {
+ right: 1px;
+ padding: 5px 10px;
+ background: rgba(155, 155, 155, .1);
+ position: absolute;
+ top: 1px;
+ -webkit-transition: opacity .2s;
+ transition: opacity .2s;
+ opacity: 0
+}
+.gantt_status.gantt_status_visible {
+ opacity: 1
+}
+#gantt_ajax_dots span {
+ -webkit-transition: opacity .2s;
+ transition: opacity .2s;
+ background-repeat: no-repeat;
+ opacity: 0
+}
+#gantt_ajax_dots span.gantt_dot_visible {
+ opacity: 1
+}
+.dhtmlx_message_area {
+ position: fixed;
+ right: 5px;
+ width: 250px;
+ z-index: 1000
+}
+.dhtmlx-message { // HOSEK
+ min-width: 120px;
+ font-family: Arial;
+ z-index: 10000;
+ margin: 5px 5px 10px;
+ -webkit-transition: all .5s ease;
+ -moz-transition: all .5s ease;
+ -o-transition: all .5s ease;
+ transition: all .5s ease;
+ font-size: 14px;
+ color: #000;
+ box-shadow: 3px 3px 3px rgba(0, 0, 0, .07);
+ padding: 0;
+ background-color: #FFF;
+ border-radius: 3px;
+ border: 1px solid #fff
+}
+.dhtmlx-message.hidden { // HOSEK
+ height: 0;
+ padding: 0;
+ border-width: 0;
+ margin: 0;
+ overflow: hidden
+}
+.dhtmlx_modal_box {
+ overflow: hidden;
+ display: inline-block;
+ min-width: 250px;
+ width: 250px;
+ text-align: center;
+ position: fixed;
+ z-index: 20000;
+ box-shadow: 3px 3px 3px rgba(0, 0, 0, .07);
+ font-family: Arial;
+ border-radius: 6px;
+ border: 1px solid #cecece;
+ background: #fff
+}
+.dhtmlx_popup_title {
+ border-top-left-radius: 6px;
+ border-top-right-radius: 6px;
+ border-width: 0
+}
+.dhtmlx_button,
+.dhtmlx_popup_button {
+ border: 1px solid #cecece;
+ height: 30px;
+ line-height: 30px;
+ display: inline-block;
+ margin: 0 5px;
+ border-radius: 4px;
+ background: #fff
+}
+.dhtmlx-message, /* HOSEK*/
+.dhtmlx_button,
+.dhtmlx_popup_button {
+ user-select: none;
+ -webkit-user-select: none;
+ -moz-user-select: -moz-none;
+ -ms-user-select: none;
+ cursor: pointer
+}
+.dhtmlx_popup_text {
+ overflow: hidden
+}
+.dhtmlx_popup_controls {
+ border-radius: 6px;
+ padding: 10px
+}
+.dhtmlx_popup_button {
+ min-width: 100px
+}
+div.dhx_modal_cover {
+ background-color: #000;
+ cursor: default;
+ filter: alpha(opacity=20);
+ opacity: .2;
+ position: fixed;
+ z-index: 19999;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ border: none;
+ zoom: 1
+}
+.dhtmlx-message img, /* HOSEK */
+.dhtmlx_modal_box img {
+ float: left;
+ margin-right: 20px
+}
+.dhtmlx-alert-error,
+.dhtmlx-confirm-error {
+ border: 1px solid red
+}
+.dhtmlx_button input,
+.dhtmlx_popup_button div {
+ border-radius: 4px;
+ font-size: 14px;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ padding: 0;
+ margin: 0;
+ vertical-align: top
+}
+.dhtmlx_popup_title {
+ color: #fff;
+ text-shadow: 1px 1px #000;
+ height: 40px;
+ line-height: 40px;
+ font-size: 20px
+}
+.dhtmlx_popup_text {
+ margin: 15px 15px 5px;
+ font-size: 14px;
+ color: #000;
+ min-height: 30px;
+ border-radius: 6px
+}
+
+/* HOSEK V */
+/*.dhtmlx-error,
+.dhtmlx-info {
+ font-size: 14px;
+ color: #000;
+ box-shadow: 3px 3px 3px rgba(0, 0, 0, .07);
+ padding: 0;
+ background-color: #FFF;
+ border-radius: 3px;
+ border: 1px solid #fff
+}*/
+.dhtmlx-message div {
+ padding: 5px 10px;
+ border-radius: 3px;
+}
+.dhtmlx-info div {
+ background-color: #fff;
+ border: 1px solid #cecece;
+}
+.dhtmlx-error {
+ background-color: #d81b1b;
+ border: 1px solid #ff3c3c;
+}
+.dhtmlx-error div {
+ background-color: #d81b1b;
+ border: 1px solid #940000;
+ color: #FFF;
+}
+.dhtmlx-success {
+ background-color: #2dff2d;
+ border: 1px solid #6CFF6C;
+}
+.dhtmlx-success div {
+ background-color: #2dff2d;
+ border: 1px solid #1B991B;
+ /*color: #FFF*/
+}
+/* HOSEK A */
+.gantt_data_area div,
+.gantt_grid div {
+ -ms-touch-action: none;
+ -webkit-tap-highlight-color: transparent
+}
+.gantt_data_area {
+ position: relative;
+ overflow-x: hidden;
+ overflow-y: hidden;
+ -moz-user-select: -moz-none;
+ -webkit-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.gantt_links_area {
+ position: absolute;
+ left: 0;
+ top: 0
+}
+.gantt_side_content,
+.gantt_task_content,
+.gantt_task_progress {
+ line-height: inherit;
+ overflow: hidden;
+ height: 100%
+}
+.gantt_task_content {
+ font-size: 12px;
+ /*color: #fff;*/
+ width: 100%;
+ top: 0;
+ position: absolute;
+ white-space: nowrap;
+ text-align: center
+}
+.gantt_task_progress {
+ text-align: center;
+ z-index: 0;
+ background: #299cb4
+}
+.gantt_task_line {
+ -webkit-border-radius: 2px;
+ -moz-border-radius: 2px;
+ border-radius: 2px;
+ position: absolute;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ background-color: #3db9d3;
+ border: 1px solid #2898b0;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -moz-user-select: -moz-none
+}
+.gantt_task_line.gantt_drag_move div {
+ cursor: move
+}
+.gantt_touch_move,
+.gantt_touch_progress .gantt_touch_resize {
+ -moz-transform: scale(1.02, 1.1);
+ -o-transform: scale(1.02, 1.1);
+ -webkit-transform: scale(1.02, 1.1);
+ transform: scale(1.02, 1.1);
+ -moz-transform-origin: 50%;
+ -o-transform-origin: 50%;
+ -webkit-transform-origin: 50%;
+ transform-origin: 50%
+}
+.gantt_touch_progress .gantt_task_progress_drag,
+.gantt_touch_resize .gantt_task_drag {
+ -moz-transform: scaleY(1.3);
+ -o-transform: scaleY(1.3);
+ -webkit-transform: scaleY(1.3);
+ transform: scaleY(1.3);
+ -moz-transform-origin: 50%;
+ -o-transform-origin: 50%;
+ -webkit-transform-origin: 50%;
+ transform-origin: 50%
+}
+.gantt_side_content {
+ position: absolute;
+ white-space: nowrap;
+ /*color: #6e6e6e;*/
+ bottom: 1px;
+ /*font-size: 14px*/
+}
+.gantt_side_content.gantt_left {
+ right: 100%;
+ padding-right: 15px
+}
+.gantt_side_content.gantt_right {
+ left: 100%;
+ padding-left: 15px
+}
+.gantt_side_content.gantt_link_crossing {
+ /*bottom: 8.75px*/
+}
+.gantt_link_arrow,
+.gantt_task_link .gantt_line_wrapper {
+ position: absolute;
+ cursor: pointer
+}
+.gantt_line_wrapper div {
+ /*background-color: #ffa011;*/
+ border: 1px solid #ffa011;
+}
+.gantt_task_link:hover .gantt_line_wrapper div {
+ box-shadow: 0 0 5px 0 #ffa011
+}
+.gantt_task_link div.gantt_link_arrow {
+ background-color: transparent;
+ border-style: solid;
+ width: 0;
+ height: 0
+}
+.gantt_link_control {
+ position: absolute;
+ width: 13px;
+ top: 0
+}
+.gantt_link_control div {
+ display: none;
+ cursor: pointer;
+ box-sizing: border-box;
+ position: relative;
+ top: 50%;
+ margin-top: -7.5px;
+ vertical-align: middle;
+ border: 1px solid #929292;
+ -webkit-border-radius: 6.5px;
+ -moz-border-radius: 6.5px;
+ border-radius: 6.5px;
+ height: 13px;
+ width: 13px;
+ background-color: #f0f0f0
+}
+.gantt_link_control div:hover {
+ background-color: #fff
+}
+.gantt_link_control.task_left {
+ left: -13px
+}
+.gantt_link_control.task_right {
+ right: -13px
+}
+.gantt_link_target .gantt_link_control div,
+.gantt_task_line.gantt_selected .gantt_link_control div,
+.gantt_task_line:hover .gantt_link_control div {
+ display: block
+}
+.gantt_link_source,
+.gantt_link_target {
+ box-shadow: 0 0 3px #3db9d3
+}
+.gantt_link_target.link_finish_allow,
+.gantt_link_target.link_start_allow {
+ box-shadow: 0 0 3px #ffbf5e
+}
+.gantt_link_target.link_finish_deny,
+.gantt_link_target.link_start_deny {
+ box-shadow: 0 0 3px #e87e7b
+}
+.link_finish_allow .gantt_link_control.task_right div,
+.link_start_allow .gantt_link_control.task_left div {
+ background-color: #ffbf5e;
+ border-color: #ffa011
+}
+.link_finish_deny .gantt_link_control.task_right div,
+.link_start_deny .gantt_link_control.task_left div {
+ background-color: #e87e7b;
+ border-color: #dd3e3a
+}
+.gantt_link_arrow_right {
+ border-width: 4px 0 4px 6px;
+ border-top-color: transparent!important;
+ border-right-color: transparent!important;
+ border-bottom-color: transparent!important;
+ border-color: #ffa011;
+ margin-top: -1px
+}
+.gantt_link_arrow_left {
+ border-width: 4px 6px 4px 0;
+ margin-top: -1px;
+ border-top-color: transparent!important;
+ border-color: #ffa011;
+ border-bottom-color: transparent!important;
+ border-left-color: transparent!important
+}
+.gantt_link_arrow_top {
+ border-width: 0 4px 6px;
+ border-color: #ffa011;
+ border-top-color: transparent!important;
+ border-right-color: transparent!important;
+ border-left-color: transparent!important
+}
+.gantt_link_arrow_down {
+ border-width: 4px 6px 0 4px;
+ border-color: #ffa011;
+ border-right-color: transparent!important;
+ border-bottom-color: transparent!important;
+ border-left-color: transparent!important
+}
+.gantt_task_drag,
+.gantt_task_progress_drag {
+ cursor: w-resize;
+ height: 100%;
+ display: none;
+ position: absolute
+}
+.gantt_task_line.gantt_selected .gantt_task_drag,
+.gantt_task_line.gantt_selected .gantt_task_progress_drag,
+.gantt_task_line:hover .gantt_task_drag,
+.gantt_task_line:hover .gantt_task_progress_drag {
+ display: block
+}
+.gantt_task_drag {
+ width: 6px;
+ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAACCAYAAAB7Xa1eAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QYDDjkw3UJvAwAAABRJREFUCNdj/P//PwM2wASl/6PTAKrrBf4+lD8LAAAAAElFTkSuQmCC);
+ z-index: 1;
+ top: 0
+}
+.gantt_task_drag.task_left {
+ left: 0
+}
+.gantt_task_drag.task_right {
+ right: 0
+}
+.gantt_task_progress_drag {
+ height: 8px;
+ width: 8px;
+ bottom: -4px;
+ margin-left: -4px;
+ background-position: bottom;
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAALCAYAAAB24g05AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MkY3Rjk0RUVDMkYzMTFFMkI1OThEQTA3ODU0OTkzMEEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MkY3Rjk0RUZDMkYzMTFFMkI1OThEQTA3ODU0OTkzMEEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyRjdGOTRFQ0MyRjMxMUUyQjU5OERBMDc4NTQ5OTMwQSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyRjdGOTRFREMyRjMxMUUyQjU5OERBMDc4NTQ5OTMwQSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PobPBzIAAADkSURBVHjaYpk2bRoDDsAExL1QdjEQ/8OmiAWHZk4gXqymqhQM4ty6fU8OSMUA8XdiDBAB4k0a6iqWRga6EKcwMQXduHlnL5DpB8Rv0J2JDFSA+JiOtgZcMwiA2CAxkBxUDVYDLEAKgIpV9XQ0MZwFEgPJAZnHoWpRDAgC4n2W5saiQKfjClQGkBxQDciL+6B6wAbkA/EqJwdrTkUFOQZCAKQGpBbIXA3SCzJggo+XK7OEuBgDsQCkFqgHrBfsBT5eHgZSAUwP2IBfv36TbABMDygdtK1Zv6UESLORaAbIhG6AAAMAKN8wE24DXWcAAAAASUVORK5CYII=);
+ background-repeat: no-repeat;
+ z-index: 2
+}
+.gantt_link_tooltip {
+ box-shadow: 3px 3px 3px #888;
+ background-color: #fff;
+ border-left: 1px dotted #cecece;
+ border-top: 1px dotted #cecece;
+ font-family: Tahoma;
+ font-size: 8pt;
+ color: #444;
+ padding: 6px;
+ line-height: 20px
+}
+.gantt_link_direction {
+ height: 0;
+ border: 0 #ffa011;
+ border-bottom-style: dashed;
+ border-bottom-width: 2px;
+ transform-origin: 0 0;
+ -ms-transform-origin: 0 0;
+ -webkit-transform-origin: 0 0;
+ z-index: 2;
+ margin-left: 1px;
+ position: absolute
+}
+.gantt_grid_data .gantt_row.gantt_selected,
+.gantt_grid_data .gantt_row.odd.gantt_selected,
+.gantt_task_row.gantt_selected {
+ background-color: #fff3a1
+}
+.gantt_task_row.gantt_selected .gantt_task_cell {
+ border-right-color: #ffec6e
+}
+.gantt_task_line.gantt_selected {
+ box-shadow: 0 0 5px #299cb4
+}
+.gantt_task_line.gantt_project-type.gantt_selected {
+ box-shadow: 0 0 5px #46ad51
+}
+.gantt_task_line.gantt_milestone-type {
+ visibility: hidden;
+ background-color: #d33daf;
+ border: 0 solid #61164f;
+ box-sizing: content-box;
+ -moz-box-sizing: content-box
+}
+.gantt_task_line.gantt_milestone-type div {
+ visibility: visible
+}
+.gantt_task_line.gantt_milestone-type .gantt_task_content {
+ background: inherit;
+ border: inherit;
+ border-width: 1px;
+ border-radius: inherit;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-transform: rotate(45deg);
+ -moz-transform: rotate(45deg);
+ -ms-transform: rotate(45deg);
+ -o-transform: rotate(45deg);
+ transform: rotate(45deg)
+}
+.gantt_task_line.gantt_task_inline_color {
+ border-color: #999
+}
+.gantt_task_line.gantt_task_inline_color .gantt_task_progress {
+ background-color: #363636;
+ opacity: .2
+}
+.gantt_task_line.gantt_task_inline_color.gantt_project-type.gantt_selected,
+.gantt_task_line.gantt_task_inline_color.gantt_selected {
+ box-shadow: 0 0 5px #999
+}
+.gantt_task_link.gantt_link_inline_color:hover .gantt_line_wrapper div {
+ box-shadow: 0 0 5px 0 #999
+}
+.gantt_critical_task {
+ background-color: #e63030;
+ border-color: #9d3a3a
+}
+.gantt_critical_task .gantt_task_progress {
+ background-color: rgba(0, 0, 0, .4)
+}
+.gantt_critical_link .gantt_line_wrapper>div {
+ background-color: #e63030
+}
+.gantt_critical_link .gantt_link_arrow {
+ border-color: #e63030
+}
+.gantt_unselectable,
+.gantt_unselectable div {
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -moz-user-select: -moz-none;
+ -ms-user-select: none;
+}
+.gantt_cal_light {
+ -webkit-tap-highlight-color: transparent;
+ background: #fff;
+ border-radius: 6px;
+ font-family: Arial;
+ border: 1px solid #cecece;
+ color: #6b6b6b;
+ font-size: 12px;
+ position: absolute;
+ z-index: 10001;
+ width: 550px;
+ height: 250px;
+ box-shadow: 3px 3px 3px rgba(0, 0, 0, .07)
+}
+.gantt_cal_light select {
+ font-family: Arial;
+ border: 1px solid #cecece;
+ font-size: 13px;
+ padding: 2px;
+ margin: 0
+}
+.gantt_cal_ltitle {
+ padding: 7px 10px;
+ overflow: hidden;
+ white-space: nowrap;
+ -webkit-border-radius: 6px 6px 0 0;
+ -moz-border-radius-topleft: 6px;
+ -moz-border-radius-bottomleft: 0;
+ -moz-border-radius-topright: 6px;
+ -moz-border-radius-bottomright: 0;
+ border-radius: 6px 6px 0 0
+}
+.gantt_cal_ltitle span {
+ white-space: nowrap
+}
+.gantt_cal_lsection {
+ color: #727272;
+ font-weight: 700;
+ padding: 12px 0 5px 10px
+}
+.gantt_cal_lsection .gantt_fullday {
+ float: right;
+ margin-right: 5px;
+ font-size: 12px;
+ font-weight: 400;
+ line-height: 20px;
+ vertical-align: top;
+ cursor: pointer
+}
+.gantt_cal_lsection {
+ font-size: 13px
+}
+.gantt_cal_ltext {
+ padding: 2px 10px;
+ overflow: hidden
+}
+.gantt_cal_ltext textarea {
+ overflow: auto;
+ font-family: Arial;
+ font-size: 13px;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ border: 1px solid #cecece;
+ height: 100%;
+ width: 100%;
+ outline: 0!important;
+ resize: none
+}
+.gantt_time {
+ font-weight: 700
+}
+.gantt_cal_light .gantt_title {
+ padding-left: 10px
+}
+.gantt_cal_larea {
+ border: 1px solid #cecece;
+ border-left: none;
+ border-right: none;
+ background-color: #fff;
+ overflow: hidden;
+ height: 1px
+}
+.gantt_btn_set {
+ margin: 10px 7px 5px 10px;
+ padding: 5px 15px 5px 10px;
+ float: left;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ border-width: 0;
+ border-color: #cecece;
+ border-style: solid;
+ height: 32px;
+ font-weight: 700;
+ background: #fff;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ cursor: pointer
+}
+.gantt_btn_set div {
+ float: left;
+ font-size: 13px;
+ height: 22px;
+ line-height: 22px;
+ background-repeat: no-repeat;
+ vertical-align: middle
+}
+.gantt_save_btn {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTk1OUU5RDFDMzA0MTFFMkExMUZBQTdDNDAzOUE5RjMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTk1OUU5RDJDMzA0MTFFMkExMUZBQTdDNDAzOUE5RjMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoxOTU5RTlDRkMzMDQxMUUyQTExRkFBN0M0MDM5QTlGMyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoxOTU5RTlEMEMzMDQxMUUyQTExRkFBN0M0MDM5QTlGMyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PjDroXYAAAEXSURBVHjaYvz//z8DJYCRUgPIAUxAbAnEHiAHMIBcQCwGaRYXF3e6evXqoffv39/dv38/CymaGSUkJBzv3LlzCsj///fv3wdAihkkIQnEvkAshU8zLy+v7a1bt06ANP/79+87kDIAy505cybq06dPr3p7ezuwGQLTfOPGjWP/ESAZLg8kPKBO+g01RBJNszWyZqC6uSgWgIg/f/4shxnS2dnZBjMEqNkSFGBImi8CKTYMA4BYCGjIczRDHC5dunQQSfN7IKWI4UUkjjdMMdCwnw8ePLjwHxV4Yw1gZA5Q47z/2EELzhhCE+ABGvIQWSeQvwcU38QaAML2wHj+C/X3MyAlijeB4ZBoBOIPQGxJKIVSnBsBAgwABddBclWfcZUAAAAASUVORK5CYII=);
+ margin-top: 2px;
+ width: 21px
+}
+.gantt_cancel_btn {
+ margin-top: 2px;
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDkzMDA3MzlDMzA0MTFFMjg2QTVFMzFEQzgwRkJERDYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MDkzMDA3M0FDMzA0MTFFMjg2QTVFMzFEQzgwRkJERDYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowOTMwMDczN0MzMDQxMUUyODZBNUUzMURDODBGQkRENiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowOTMwMDczOEMzMDQxMUUyODZBNUUzMURDODBGQkRENiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PmYuYOUAAAEdSURBVHjaYvz//z8DJYAFXWDlypU8QKoIiD2A2AwqfAqIdwBxX3h4+Bdk9YzILgBqtgdS84FYEYeF94E4EWjIQZgAE5LmQCB1AKoZZKMPEAtAMYh9GSp3AKjWD8UFQAEhIPshEIOc3wHENUBb/qJ57SyQMoJyPwKxElDNO1gYFEE17wMKVmIJlzNQzeegrjaA6qmBecEbSvfh0GwMxGeBhoPoemQ9MAO0kEIbl2YTqPAFKK2IbMB3AjabYIkRZmQD7kNpMyI0G0PpO8gGbIUFJj7NQDk2INWIrIcJKfBAKcwJqvkcDs0TgFgXGo19KCkRmpDWQdWDEk0NUoCBoq0FqhkE/IEWbKJKUmZEz43QzFSKIzN1481M5ACAAAMAlfl/lCwRpagAAAAASUVORK5CYII=);
+ width: 20px
+}
+.gantt_delete_btn {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MjFENzI3NUNDMzA0MTFFMjhBNjJGQTc3MUIyQzYzNEYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MjFENzI3NURDMzA0MTFFMjhBNjJGQTc3MUIyQzYzNEYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyMUQ3Mjc1QUMzMDQxMUUyOEE2MkZBNzcxQjJDNjM0RiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyMUQ3Mjc1QkMzMDQxMUUyOEE2MkZBNzcxQjJDNjM0RiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PmUD0gAAAABvSURBVHjaYvz//z8DIyMjAxYQicReji4J0ofKQNP8HwmgGQbXB8IsWGwDSSwDuioKjY9uBthVjFAXYHUGAQA2kYmBUoAUBpGk0LAwgBvwH+YX4mkwptgLowYMRgOITUyYKRFIN/wnDjQgJySAAAMApryKzL8wjfUAAAAASUVORK5CYII=);
+ margin-top: 2px;
+ width: 20px
+}
+.gantt_cal_cover {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ z-index: 10000;
+ top: 0;
+ left: 0;
+ background-color: #000;
+ opacity: .1;
+ filter: alpha(opacity=10)
+}
+.gantt_custom_button {
+ padding: 0 3px;
+ font-family: Arial;
+ font-size: 13px;
+ font-weight: 400;
+ margin-right: 10px;
+ margin-top: -5px;
+ cursor: pointer;
+ float: right;
+ height: 21px;
+ width: 90px;
+ border: 1px solid #CECECE;
+ text-align: center;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ -ms-border-radius: 4px;
+ -o-border-radius: 4px;
+ border-radius: 4px
+}
+.gantt_custom_button div {
+ cursor: pointer;
+ float: none;
+ height: 21px;
+ line-height: 21px;
+ vertical-align: middle
+}
+.gantt_custom_button div:first-child {
+ display: none
+}
+.gantt_cal_light_wide {
+ width: 580px;
+ padding: 2px 4px
+}
+.gantt_cal_light_wide .gantt_cal_larea {
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ border: 1px solid #cecece
+}
+.gantt_cal_light_wide .gantt_cal_lsection {
+ border: 0;
+ float: left;
+ text-align: right;
+ width: 80px;
+ height: 20px;
+ padding: 5px 10px 0 0
+}
+.gantt_cal_light_wide .gantt_wrap_section {
+ position: relative;
+ padding: 10px 0;
+ overflow: hidden;
+ border-bottom: 1px solid #ebebeb
+}
+.gantt_cal_light_wide .gantt_section_time {
+ overflow: hidden;
+ padding-top: 2px!important;
+ padding-right: 0;
+ height: 20px!important
+}
+.gantt_cal_light_wide .gantt_cal_ltext {
+ padding-right: 0
+}
+.gantt_cal_light_wide .gantt_cal_larea {
+ padding: 0 10px;
+ width: 100%
+}
+.gantt_cal_light_wide .gantt_section_time {
+ background: 0 0
+}
+.gantt_cal_light_wide .gantt_cal_checkbox label {
+ padding-left: 0
+}
+.gantt_cal_light_wide .gantt_cal_lsection .gantt_fullday {
+ float: none;
+ margin-right: 0;
+ font-weight: 700;
+ cursor: pointer
+}
+.gantt_cal_light_wide .gantt_custom_button {
+ position: absolute;
+ top: 0;
+ right: 0;
+ margin-top: 2px
+}
+.gantt_cal_light_wide .gantt_repeat_right {
+ margin-right: 55px
+}
+.gantt_cal_light_wide.gantt_cal_light_full {
+ width: 738px
+}
+.gantt_cal_wide_checkbox input {
+ margin-top: 8px;
+ margin-left: 14px
+}
+.gantt_cal_light input {
+ font-size: 13px
+}
+.gantt_section_time {
+ background-color: #fff;
+ white-space: nowrap;
+ padding: 5px 10px;
+ padding-top: 2px!important
+}
+.gantt_section_time .gantt_time_selects {
+ float: left;
+ height: 25px
+}
+.gantt_section_time .gantt_time_selects select {
+ height: 23px;
+ padding: 2px;
+ border: 1px solid #cecece
+}
+.gantt_duration {
+ width: 100px;
+ height: 23px;
+ float: left;
+ white-space: nowrap;
+ margin-left: 20px;
+ line-height: 23px
+}
+.gantt_duration .gantt_duration_dec,
+.gantt_duration .gantt_duration_inc,
+.gantt_duration .gantt_duration_value {
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ text-align: center;
+ vertical-align: top;
+ height: 100%;
+ border: 1px solid #cecece
+}
+.gantt_duration .gantt_duration_value {
+ width: 40px;
+ padding: 3px 4px;
+ border-left-width: 0;
+ border-right-width: 0
+}
+.gantt_duration .gantt_duration_dec,
+.gantt_duration .gantt_duration_inc {
+ width: 20px;
+ padding: 1px 1px 3px;
+ background: #fff
+}
+.gantt_duration .gantt_duration_dec {
+ -moz-border-top-left-radius: 4px;
+ -moz-border-bottom-left-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+ -webkit-border-bottom-left-radius: 4px;
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px
+}
+.gantt_duration .gantt_duration_inc {
+ margin-right: 4px;
+ -moz-border-top-right-radius: 4px;
+ -moz-border-bottom-right-radius: 4px;
+ -webkit-border-top-right-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px
+}
+.gantt_cal_quick_info {
+ border: 1px solid #cecece;
+ border-radius: 6px;
+ position: absolute;
+ z-index: 300;
+ box-shadow: 3px 3px 3px rgba(0, 0, 0, .07);
+ background-color: #fff;
+ width: 300px;
+ transition: left .5s ease, right .5s;
+ -moz-transition: left .5s ease, right .5s;
+ -webkit-transition: left .5s ease, right .5s;
+ -o-transition: left .5s ease, right .5s
+}
+.gantt_no_animate {
+ transition: none;
+ -moz-transition: none;
+ -webkit-transition: none;
+ -o-transition: none
+}
+.gantt_cal_quick_info.gantt_qi_left .gantt_qi_big_icon {
+ float: right
+}
+.gantt_cal_qi_title {
+ -webkit-border-radius: 6px 6px 0 0;
+ -moz-border-radius-topleft: 6px;
+ -moz-border-radius-bottomleft: 0;
+ -moz-border-radius-topright: 6px;
+ -moz-border-radius-bottomright: 0;
+ border-radius: 6px 6px 0 0;
+ padding: 5px 0 8px 12px;
+ color: #454545;
+ background-color: #fff;
+ border-bottom: 1px solid #cecece
+}
+.gantt_cal_qi_tdate {
+ font-size: 14px;
+ font-weight: 700
+}
+.gantt_cal_qi_tcontent {
+ font-size: 13px
+}
+.gantt_cal_qi_content {
+ padding: 16px 8px;
+ font-size: 13px;
+ color: #454545;
+ overflow: hidden
+}
+.gantt_cal_qi_controls {
+ -webkit-border-radius: 0 0 6px 6px;
+ -moz-border-radius-topleft: 0;
+ -moz-border-radius-bottomleft: 6px;
+ -moz-border-radius-topright: 0;
+ -moz-border-radius-bottomright: 6px;
+ border-radius: 0 0 6px 6px;
+ padding-left: 7px
+}
+.gantt_cal_qi_controls .gantt_menu_icon {
+ margin-top: 6px;
+ background-repeat: no-repeat
+}
+.gantt_cal_qi_controls .gantt_menu_icon.icon_edit {
+ width: 20px;
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3QYFCjI5ZQj5bAAAAFNJREFUOMvt0zEOACAIA0DkwTymH8bJTRTKZGJXyaWEKPKTCQAH4Ls37cItcDUzsxHNDLZNhCq7Gt1wh9ErV7EjyGAhyGLphlnsClWuS32rn0czAV+vNGrM/LBtAAAAAElFTkSuQmCC)
+}
+.gantt_cal_qi_controls .gantt_menu_icon.icon_delete {
+ width: 20px;
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MjFENzI3NUNDMzA0MTFFMjhBNjJGQTc3MUIyQzYzNEYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MjFENzI3NURDMzA0MTFFMjhBNjJGQTc3MUIyQzYzNEYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyMUQ3Mjc1QUMzMDQxMUUyOEE2MkZBNzcxQjJDNjM0RiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyMUQ3Mjc1QkMzMDQxMUUyOEE2MkZBNzcxQjJDNjM0RiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PmUD0gAAAABvSURBVHjaYvz//z8DIyMjAxYQicReji4J0ofKQNP8HwmgGQbXB8IsWGwDSSwDuioKjY9uBthVjFAXYHUGAQA2kYmBUoAUBpGk0LAwgBvwH+YX4mkwptgLowYMRgOITUyYKRFIN/wnDjQgJySAAAMApryKzL8wjfUAAAAASUVORK5CYII=)
+}
+.gantt_qi_big_icon {
+ font-size: 13px;
+ border-radius: 4px;
+ font-weight: 700;
+ background: #fff;
+ margin: 5px 9px 8px 0;
+ min-width: 60px;
+ line-height: 32px;
+ vertical-align: middle;
+ padding: 0 10px 0 5px;
+ cursor: pointer;
+ border: 1px solid #cecece
+}
+.gantt_cal_qi_controls div {
+ float: left;
+ height: 32px;
+ text-align: center;
+ line-height: 32px
+}
+.gantt_tooltip {
+ box-shadow: 3px 3px 3px rgba(0, 0, 0, .07);
+ background-color: #fff;
+ border-left: 1px solid rgba(0, 0, 0, .07);
+ border-top: 1px solid rgba(0, 0, 0, .07);
+ font-family: Arial;
+ font-size: 8pt;
+ color: #454545;
+ padding: 10px;
+ position: absolute;
+ z-index: 50
+}
+.gantt_marker {
+ height: 100%;
+ width: 2px;
+ top: 0;
+ position: absolute;
+ text-align: center;
+ background-color: rgba(255, 0, 0, .4);
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box
+}
+.gantt_marker .gantt_marker_content {
+ padding: 5px;
+ background: inherit;
+ color: #fff;
+ position: absolute;
+ font-size: 12px;
+ line-height: 12px;
+ opacity: .8
+}
+.gantt_marker_area {
+ position: absolute;
+ top: 0;
+ left: 0
+}
+.gantt_noselect {
+ -moz-user-select: -moz-none;
+ -webkit-user-select: none;
+ -ms-user-select: none;
+ user-select: none
+}
+.gantt_drag_marker {
+ position: absolute;
+ font-family: Arial;
+ font-size: 13px
+}
+.gantt_drag_marker .gantt_tree_icon.gantt_blank,
+.gantt_drag_marker .gantt_tree_icon.gantt_close,
+.gantt_drag_marker .gantt_tree_icon.gantt_open,
+.gantt_drag_marker .gantt_tree_indent {
+ display: none
+}
+.gantt_drag_marker,
+.gantt_drag_marker .gantt_row.odd {
+ background-color: #fff
+}
+.gantt_drag_marker .gantt_row {
+ border-left: 1px solid #d2d2d2;
+ border-top: 1px solid #d2d2d2
+}
+.gantt_drag_marker .gantt_cell {
+ border-color: #d2d2d2
+}
+.gantt_row.gantt_over,
+.gantt_task_row.gantt_over {
+ background-color: #0070fe
+}
+.gantt_row.gantt_transparent .gantt_cell {
+ opacity: .7
+}
+.gantt_task_row.gantt_transparent {
+ background-color: #f8fdfd
+}
+.dhtmlx_popup_button.dhtmlx_delete_button {
+ background: #3db9d3;
+ text-shadow: 0 -1px 0 #248a9f;
+ color: #fff;
+ font-weight: 700;
+ border-width: 0
+}
\ No newline at end of file
diff --git a/plugins/easy_gantt/assets/stylesheets/easy_gantt/dhtmlxgantt_vanilla.css b/plugins/easy_gantt/assets/stylesheets/easy_gantt/dhtmlxgantt_vanilla.css
new file mode 100644
index 0000000..8a6ac93
--- /dev/null
+++ b/plugins/easy_gantt/assets/stylesheets/easy_gantt/dhtmlxgantt_vanilla.css
@@ -0,0 +1,9 @@
+/*
+@license
+
+dhtmlxGantt v.3.2.1 Stardard
+This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
+
+(c) Dinamenta, UAB.
+*/
+.gridHoverStyle,.gridSelection,.timelineSelection{background-color:#fff3a1}.gantt_grid_scale .gantt_grid_head_cell{color:#a6a6a6;border-top:none!important;border-right:none!important}.gantt_grid_data .gantt_cell{border-right:none;color:#454545}.gantt_task_link .gantt_link_arrow_right{border-width:6px;margin-top:-3px}.gantt_task_link .gantt_link_arrow_left{border-width:6px;margin-left:-6px;margin-top:-3px}.gantt_task_link .gantt_link_arrow_down,.gantt_task_link .gantt_link_arrow_top{border-width:6px}.gantt_task_line .gantt_task_progress_drag{bottom:-4px;height:16px;margin-left:-8px;width:16px}.chartHeaderBg{background-color:#fff}.gantt_task .gantt_task_scale .gantt_scale_cell{color:#a6a6a6;border-right:1px solid #ebebeb}.gantt_row.gantt_project,.gantt_row.odd.gantt_project{background-color:#edffef}.gantt_task_row.gantt_project,.gantt_task_row.odd.gantt_project{background-color:#f5fff6}.gantt_task_line.gantt_project{background-color:#65c16f;border:1px solid #3c9445}.gantt_task_line.gantt_project .gantt_task_progress{background-color:#46ad51}.buttonBg{background:#fff}.gantt_cal_light .gantt_btn_set{margin:5px 10px}.gantt_btn_set.gantt_cancel_btn_set{background:#fff;color:#454545;border:1px solid #cecece}.gantt_btn_set.gantt_save_btn_set{background:#3db9d3;text-shadow:0 -1px 0 #248a9f;color:#fff}.gantt_btn_set.gantt_delete_btn_set{background:#ec8e00;text-shadow:0 -1px 0 #a60;color:#fff}.gantt_cal_light_wide{padding-left:0!important;padding-right:0!important}.gantt_cal_light_wide .gantt_cal_larea{border-left:none!important;border-right:none!important}.dhtmlx_popup_button.dhtmlx_ok_button{background:#3db9d3;text-shadow:0 -1px 0 #248a9f;color:#fff;font-weight:700;border-width:0}.dhtmlx_popup_button.dhtmlx_cancel_button{font-weight:700;color:#454544}.gantt_qi_big_icon.icon_edit{color:#454545;background:#fff}.gantt_qi_big_icon.icon_delete{text-shadow:0 -1px 0 #a60;background:#ec8e00;color:#fff;border-width:0}.gantt_container{font-family:Arial;font-size:13px;border:1px solid #cecece;position:relative;white-space:nowrap}.gantt_grid{border-right:1px solid #cecece}.gantt_task_scroll{overflow-x:scroll}.gantt_task{position:relative}.gantt_grid,.gantt_task{overflow-x:hidden;overflow-y:hidden;display:inline-block;vertical-align:top}.gantt_grid_scale,.gantt_task_scale{color:#6b6b6b;font-size:12px;border-bottom:1px solid #cecece;background-color:#fff}.gantt_scale_line{box-sizing:border-box;-moz-box-sizing:border-box;border-top:1px solid #cecece}.gantt_scale_line:first-child{border-top:none}.gantt_grid_head_cell{display:inline-block;vertical-align:top;border-right:1px solid #cecece;text-align:center;position:relative;cursor:default;height:100%;-moz-user-select:-moz-none;-webkit-user-select:none;-user-select:none;overflow:hidden}.gantt_scale_line{clear:both}.gantt_grid_data{width:100%;overflow:hidden}.gantt_row{position:relative;-webkit-user-select:none;-moz-user-select:none;-moz-user-select:-moz-none}.gantt_add,.gantt_grid_head_add{width:100%;height:100%;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTQ3MjMyMENDNkI0MTFFMjk4MTI5QTg3MDhFNDVDQTkiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTQ3MjMyMERDNkI0MTFFMjk4MTI5QTg3MDhFNDVDQTkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1NDcyMzIwQUM2QjQxMUUyOTgxMjlBODcwOEU0NUNBOSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1NDcyMzIwQkM2QjQxMUUyOTgxMjlBODcwOEU0NUNBOSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PshZT8UAAABbSURBVHjaYrTdeZmBEsCER+4wEP+H4sPkGGCDg020ARR7gb4GIAcYDKMDdPnDyAbYkGG5DVW9cIQMvUdBBAuUY4vDz8iAcZinA2zgCHqAYQMseAywJcYFAAEGAM+UFGuohFczAAAAAElFTkSuQmCC);background-position:center center;background-repeat:no-repeat;cursor:pointer;position:relative;-moz-opacity:.3;opacity:.3}.gantt_grid_head_cell.gantt_grid_head_add{-moz-opacity:.6;opacity:.6;top:0}.gantt_grid_head_cell.gantt_grid_head_add:hover{-moz-opacity:1;opacity:1}.gantt_grid_data .gantt_row.odd:hover,.gantt_grid_data .gantt_row:hover{background-color:#fff3a1}.gantt_grid_data .gantt_row.odd:hover .gantt_add,.gantt_grid_data .gantt_row:hover .gantt_add{-moz-opacity:1;opacity:1}.gantt_row,.gantt_task_row{border-bottom:1px solid #ebebeb;background-color:#fff}.gantt_row.odd,.gantt_task_row.odd{background-color:#fff}.gantt_cell,.gantt_grid_head_cell,.gantt_row,.gantt_scale_cell,.gantt_task_cell,.gantt_task_row{box-sizing:border-box;-moz-box-sizing:border-box}.gantt_grid_head_cell,.gantt_scale_cell{line-height:inherit}.gantt_grid_scale .gantt_grid_column_resize_wrap{cursor:col-resize;position:absolute;width:13px}.gantt_grid_column_resize_wrap .gantt_grid_column_resize{background-color:#cecece;height:100%;width:1px;margin:0 auto}.gantt_grid .gantt_grid_resize_wrap{cursor:col-resize;position:absolute;width:13px;z-index:1}.gantt_grid_resize_wrap .gantt_grid_resize{background-color:#cecece;width:1px;margin:0 auto}.gantt_drag_marker.gantt_grid_resize_area{background-color:rgba(231,231,231,.5);border-left:1px solid #cecece;border-right:1px solid #cecece;height:100%;width:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.gantt_cell{display:inline-block;vertical-align:top;border-right:1px solid #ebebeb;padding-left:6px;padding-right:6px;height:100%;overflow:hidden;white-space:nowrap;font-size:13px}.gantt_grid_data .gantt_last_cell,.gantt_grid_scale .gantt_last_cell,.gantt_task_bg .gantt_last_cell,.gantt_task_scale .gantt_last_cell{border-right-width:0}.gantt_task_bg{overflow:hidden}.gantt_scale_cell{display:inline-block;white-space:nowrap;overflow:hidden;border-right:1px solid #cecece;text-align:center;height:100%}.gantt_task_cell{display:inline-block;height:100%;border-right:1px solid #ebebeb}.gantt_ver_scroll{width:0;background-color:transparent;height:1px;overflow-x:hidden;overflow-y:scroll;display:none;position:absolute;right:0}.gantt_ver_scroll>div{width:1px;height:1px}.gantt_hor_scroll{height:0;background-color:transparent;width:100%;clear:both;overflow-x:scroll;overflow-y:hidden;display:none}.gantt_hor_scroll>div{width:5000px;height:1px}.gantt_tree_indent{width:15px;height:100%;display:inline-block}.gantt_tree_content,.gantt_tree_icon{vertical-align:top}.gantt_tree_icon{width:28px;height:100%;display:inline-block;background-repeat:no-repeat;background-position:center center}.gantt_tree_content{height:100%;display:inline-block}.gantt_tree_icon.gantt_open{background-image:url(data:image/gif;base64,R0lGODlhEgASALMJAMrKyt3d3ejp6d7f3+/v75aWlvf39////wAAAP///wAAAAAAAAAAAAAAAAAAAAAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6M0I5RTczQjVDMDdBMTFFMTgxRjc4Mzk4M0Q3MjVFQzAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6M0I5RTczQjZDMDdBMTFFMTgxRjc4Mzk4M0Q3MjVFQzAiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDozQjlFNzNCM0MwN0ExMUUxODFGNzgzOTgzRDcyNUVDMCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDozQjlFNzNCNEMwN0ExMUUxODFGNzgzOTgzRDcyNUVDMCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAkALAAAAAASABIAAARJMMlJq704661B+SAIXAVhnKhBFKSZnmuLImhslXPN3ibi+6pdBXc4IIpB2YkGE1IKAoL0ICUInJNCYMDtDgJYiScUGnHO6LQkAgA7);width:18px;cursor:pointer}.gantt_tree_icon.gantt_close{background-image:url(data:image/gif;base64,R0lGODlhEgASALMJAMrKyt3d3ejp6d7f3+/v75aWlvf39wAAAP///////wAAAAAAAAAAAAAAAAAAAAAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MzY0QzNGM0VDMDdBMTFFMUE3MDlCNUM2QjU1NDA5RjgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MzY0QzNGM0ZDMDdBMTFFMUE3MDlCNUM2QjU1NDA5RjgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDozNjRDM0YzQ0MwN0ExMUUxQTcwOUI1QzZCNTU0MDlGOCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDozNjRDM0YzREMwN0ExMUUxQTcwOUI1QzZCNTU0MDlGOCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAkALAAAAAASABIAAARDMMlJq704661B+SAIXAVhnKhBFKSZnmv7wqxVzmpd3Uff5zKEUAi0uV4xm4DAbBIEOkohMKhaB4HoxBMKjTjgsFgSAQA7);width:18px;cursor:pointer}.gantt_tree_icon.gantt_blank{width:18px}.gantt_tree_icon.gantt_folder_open{background-image:url(data:image/gif;base64,R0lGODlhEgASAJECAJeXl7Gvrf///wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTdDRDM3QzVDMDZEMTFFMUJGMzhFMDhCN0RGRjBGQ0YiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTdDRDM3QzZDMDZEMTFFMUJGMzhFMDhCN0RGRjBGQ0YiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1N0NEMzdDM0MwNkQxMUUxQkYzOEUwOEI3REZGMEZDRiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1N0NEMzdDNEMwNkQxMUUxQkYzOEUwOEI3REZGMEZDRiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAIALAAAAAASABIAAAIzlI+pywcPm3mhWgkCsjBOvVkimElG9ZlCBlXd+2XjjLKg5GqoeZXqvsOQXK/ijUZTKVUFADs=)}.gantt_tree_icon.gantt_folder_closed{background-image:url(data:image/gif;base64,R0lGODlhEgASAJECAJeXl7Gvrf///wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTAyMTU1RTNDMDZEMTFFMUJGNzZCRThBRkFCRjg4MTIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTAyMTU1RTRDMDZEMTFFMUJGNzZCRThBRkFCRjg4MTIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1MDIxNTVFMUMwNkQxMUUxQkY3NkJFOEFGQUJGODgxMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1MDIxNTVFMkMwNkQxMUUxQkY3NkJFOEFGQUJGODgxMiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAIALAAAAAASABIAAAIwlI+pywcPm3mhWgkCsjBOvVkimElG9ZlCuYIY6TYs+6bmHDO4igfdD3GNhheV0VQAADs=)}.gantt_tree_icon.gantt_file{background-image:url(data:image/gif;base64,R0lGODlhEgASAJECAJeXl7Gvrf///wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzkxQzI4RjZDMDZEMTFFMTgwRjhBQURDQzI3NDU3QUEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzkxQzI4RjdDMDZEMTFFMTgwRjhBQURDQzI3NDU3QUEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3OTFDMjhGNEMwNkQxMUUxODBGOEFBRENDMjc0NTdBQSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3OTFDMjhGNUMwNkQxMUUxODBGOEFBRENDMjc0NTdBQSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAIALAAAAAASABIAAAIylI+pwN16QJiUQiFThRlJm3RRFYSlR5qXMKmXaMDuuMoyOi8n/e6xn8NMHETgh5RaKQsAOw==)}.gantt_grid_head_cell .gantt_sort{position:absolute;right:5px;top:8px;width:7px;height:13px;background-repeat:no-repeat;background-position:center center}.gantt_grid_head_cell .gantt_sort.gantt_asc{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAANCAYAAABlyXS1AAAARUlEQVR4nGNgQAKGxib/GbABkIS7b8B/DAUwCRiGK0CXwFBAb1DfP/U/LszwHwi2X7qFgUEArBtdAVwCBmAKMCSQFSDzAWXXaOHsXeqkAAAAAElFTkSuQmCC)}.gantt_grid_head_cell .gantt_sort.gantt_desc{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAANCAYAAABlyXS1AAAARUlEQVR42mNgQAL1/VP/M2ADIIntF2/9x1AAlrh0C47hCmA60DFYwX88gIFGwNDY5D8uDFbg7hvwHx2jmIBTAlkB0e4BAEjlaNtBWJPnAAAAAElFTkSuQmCC)}.gantt_inserted,.gantt_updated{font-weight:700}.gantt_deleted{text-decoration:line-through}.gantt_invalid{background-color:FFE0E0}.gantt_error{color:red}.gantt_status{right:1px;padding:5px 10px;background:rgba(155,155,155,.1);position:absolute;top:1px;-webkit-transition:opacity .2s;transition:opacity .2s;opacity:0}.gantt_status.gantt_status_visible{opacity:1}#gantt_ajax_dots span{-webkit-transition:opacity .2s;transition:opacity .2s;background-repeat:no-repeat;opacity:0}#gantt_ajax_dots span.gantt_dot_visible{opacity:1}.dhtmlx_message_area{position:fixed;right:5px;width:250px;z-index:1000}.dhtmlx-info{min-width:120px;font-family:Arial;z-index:10000;margin:5px 5px 10px;-webkit-transition:all .5s ease;-moz-transition:all .5s ease;-o-transition:all .5s ease;transition:all .5s ease}.dhtmlx-info.hidden{height:0;padding:0;border-width:0;margin:0;overflow:hidden}.dhtmlx_modal_box{overflow:hidden;display:inline-block;min-width:250px;width:250px;text-align:center;position:fixed;z-index:20000;box-shadow:3px 3px 3px rgba(0,0,0,.07);font-family:Arial;border-radius:6px;border:1px solid #cecece;background:#fff}.dhtmlx_popup_title{border-top-left-radius:6px;border-top-right-radius:6px;border-width:0}.dhtmlx_button,.dhtmlx_popup_button{border:1px solid #cecece;height:30px;line-height:30px;display:inline-block;margin:0 5px;border-radius:4px;background:#fff}.dhtmlx-info,.dhtmlx_button,.dhtmlx_popup_button{user-select:none;-webkit-user-select:none;-moz-user-select:-moz-none;cursor:pointer}.dhtmlx_popup_text{overflow:hidden}.dhtmlx_popup_controls{border-radius:6px;padding:10px}.dhtmlx_popup_button{min-width:100px}div.dhx_modal_cover{background-color:#000;cursor:default;filter:alpha(opacity=20);opacity:.2;position:fixed;z-index:19999;left:0;top:0;width:100%;height:100%;border:none;zoom:1}.dhtmlx-info img,.dhtmlx_modal_box img{float:left;margin-right:20px}.dhtmlx-alert-error,.dhtmlx-confirm-error{border:1px solid red}.dhtmlx_button input,.dhtmlx_popup_button div{border-radius:4px;font-size:14px;-moz-box-sizing:content-box;box-sizing:content-box;padding:0;margin:0;vertical-align:top}.dhtmlx_popup_title{color:#fff;text-shadow:1px 1px #000;height:40px;line-height:40px;font-size:20px}.dhtmlx_popup_text{margin:15px 15px 5px;font-size:14px;color:#000;min-height:30px;border-radius:6px}.dhtmlx-error,.dhtmlx-info{font-size:14px;color:#000;box-shadow:3px 3px 3px rgba(0,0,0,.07);padding:0;background-color:#FFF;border-radius:3px;border:1px solid #fff}.dhtmlx-info div{padding:5px 10px;background-color:#fff;border-radius:3px;border:1px solid #cecece}.dhtmlx-error{background-color:#d81b1b;border:1px solid #ff3c3c;box-shadow:3px 3px 3px rgba(0,0,0,.07)}.dhtmlx-error div{background-color:#d81b1b;border:1px solid #940000;color:#FFF}.gantt_data_area div,.gantt_grid div{-ms-touch-action:none;-webkit-tap-highlight-color:transparent}.gantt_data_area{position:relative;overflow-x:hidden;overflow-y:hidden;-moz-user-select:-moz-none;-webkit-user-select:none;-user-select:none}.gantt_links_area{position:absolute;left:0;top:0}.gantt_side_content,.gantt_task_content,.gantt_task_progress{line-height:inherit;overflow:hidden;height:100%}.gantt_task_content{font-size:12px;color:#fff;width:100%;top:0;position:absolute;white-space:nowrap;text-align:center}.gantt_task_progress{text-align:center;z-index:0;background:#299cb4}.gantt_task_line{-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;position:absolute;-moz-box-sizing:border-box;box-sizing:border-box;background-color:#3db9d3;border:1px solid #2898b0;-webkit-user-select:none;-moz-user-select:none;-moz-user-select:-moz-none}.gantt_task_line.gantt_drag_move div{cursor:move}.gantt_touch_move,.gantt_touch_progress .gantt_touch_resize{-moz-transform:scale(1.02,1.1);-o-transform:scale(1.02,1.1);-webkit-transform:scale(1.02,1.1);transform:scale(1.02,1.1);-moz-transform-origin:50%;-o-transform-origin:50%;-webkit-transform-origin:50%;transform-origin:50%}.gantt_touch_progress .gantt_task_progress_drag,.gantt_touch_resize .gantt_task_drag{-moz-transform:scaleY(1.3);-o-transform:scaleY(1.3);-webkit-transform:scaleY(1.3);transform:scaleY(1.3);-moz-transform-origin:50%;-o-transform-origin:50%;-webkit-transform-origin:50%;transform-origin:50%}.gantt_side_content{position:absolute;white-space:nowrap;color:#6e6e6e;bottom:7px;font-size:11px}.gantt_side_content.gantt_left{right:100%;padding-right:15px}.gantt_side_content.gantt_right{left:100%;padding-left:15px}.gantt_side_content.gantt_link_crossing{bottom:8.75px}.gantt_link_arrow,.gantt_task_link .gantt_line_wrapper{position:absolute;cursor:pointer}.gantt_line_wrapper div{background-color:#ffa011}.gantt_task_link:hover .gantt_line_wrapper div{box-shadow:0 0 5px 0 #ffa011}.gantt_task_link div.gantt_link_arrow{background-color:transparent;border-style:solid;width:0;height:0}.gantt_link_control{position:absolute;width:13px;top:0}.gantt_link_control div{display:none;cursor:pointer;box-sizing:border-box;position:relative;top:50%;margin-top:-7.5px;vertical-align:middle;border:1px solid #929292;-webkit-border-radius:6.5px;-moz-border-radius:6.5px;border-radius:6.5px;height:13px;width:13px;background-color:#f0f0f0}.gantt_link_control div:hover{background-color:#fff}.gantt_link_control.task_left{left:-13px}.gantt_link_control.task_right{right:-13px}.gantt_link_target .gantt_link_control div,.gantt_task_line.gantt_selected .gantt_link_control div,.gantt_task_line:hover .gantt_link_control div{display:block}.gantt_link_source,.gantt_link_target{box-shadow:0 0 3px #3db9d3}.gantt_link_target.link_finish_allow,.gantt_link_target.link_start_allow{box-shadow:0 0 3px #ffbf5e}.gantt_link_target.link_finish_deny,.gantt_link_target.link_start_deny{box-shadow:0 0 3px #e87e7b}.link_finish_allow .gantt_link_control.task_right div,.link_start_allow .gantt_link_control.task_left div{background-color:#ffbf5e;border-color:#ffa011}.link_finish_deny .gantt_link_control.task_right div,.link_start_deny .gantt_link_control.task_left div{background-color:#e87e7b;border-color:#dd3e3a}.gantt_link_arrow_right{border-width:4px 0 4px 6px;border-top-color:transparent!important;border-right-color:transparent!important;border-bottom-color:transparent!important;border-color:#ffa011;margin-top:-1px}.gantt_link_arrow_left{border-width:4px 6px 4px 0;margin-top:-1px;border-top-color:transparent!important;border-color:#ffa011;border-bottom-color:transparent!important;border-left-color:transparent!important}.gantt_link_arrow_top{border-width:0 4px 6px;border-color:#ffa011;border-top-color:transparent!important;border-right-color:transparent!important;border-left-color:transparent!important}.gantt_link_arrow_down{border-width:4px 6px 0 4px;border-color:#ffa011;border-right-color:transparent!important;border-bottom-color:transparent!important;border-left-color:transparent!important}.gantt_task_drag,.gantt_task_progress_drag{cursor:w-resize;height:100%;display:none;position:absolute}.gantt_task_line.gantt_selected .gantt_task_drag,.gantt_task_line.gantt_selected .gantt_task_progress_drag,.gantt_task_line:hover .gantt_task_drag,.gantt_task_line:hover .gantt_task_progress_drag{display:block}.gantt_task_drag{width:6px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAACCAYAAAB7Xa1eAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QYDDjkw3UJvAwAAABRJREFUCNdj/P//PwM2wASl/6PTAKrrBf4+lD8LAAAAAElFTkSuQmCC);z-index:1;top:0}.gantt_task_drag.task_left{left:0}.gantt_task_drag.task_right{right:0}.gantt_task_progress_drag{height:8px;width:8px;bottom:-4px;margin-left:-4px;background-position:bottom;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAALCAYAAAB24g05AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MkY3Rjk0RUVDMkYzMTFFMkI1OThEQTA3ODU0OTkzMEEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MkY3Rjk0RUZDMkYzMTFFMkI1OThEQTA3ODU0OTkzMEEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyRjdGOTRFQ0MyRjMxMUUyQjU5OERBMDc4NTQ5OTMwQSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyRjdGOTRFREMyRjMxMUUyQjU5OERBMDc4NTQ5OTMwQSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PobPBzIAAADkSURBVHjaYpk2bRoDDsAExL1QdjEQ/8OmiAWHZk4gXqymqhQM4ty6fU8OSMUA8XdiDBAB4k0a6iqWRga6EKcwMQXduHlnL5DpB8Rv0J2JDFSA+JiOtgZcMwiA2CAxkBxUDVYDLEAKgIpV9XQ0MZwFEgPJAZnHoWpRDAgC4n2W5saiQKfjClQGkBxQDciL+6B6wAbkA/EqJwdrTkUFOQZCAKQGpBbIXA3SCzJggo+XK7OEuBgDsQCkFqgHrBfsBT5eHgZSAUwP2IBfv36TbABMDygdtK1Zv6UESLORaAbIhG6AAAMAKN8wE24DXWcAAAAASUVORK5CYII=);background-repeat:no-repeat;z-index:2}.gantt_link_tooltip{box-shadow:3px 3px 3px #888;background-color:#fff;border-left:1px dotted #cecece;border-top:1px dotted #cecece;font-family:Tahoma;font-size:8pt;color:#444;padding:6px;line-height:20px}.gantt_link_direction{height:0;border:0 #ffa011;border-bottom-style:dashed;border-bottom-width:2px;transform-origin:0 0;-ms-transform-origin:0 0;-webkit-transform-origin:0 0;z-index:2;margin-left:1px;position:absolute}.gantt_grid_data .gantt_row.gantt_selected,.gantt_grid_data .gantt_row.odd.gantt_selected,.gantt_task_row.gantt_selected{background-color:#fff3a1}.gantt_task_row.gantt_selected .gantt_task_cell{border-right-color:#ffec6e}.gantt_task_line.gantt_selected{box-shadow:0 0 5px #299cb4}.gantt_task_line.gantt_project.gantt_selected{box-shadow:0 0 5px #46ad51}.gantt_task_line.gantt_milestone{visibility:hidden;background-color:#d33daf;border:0 solid #61164f;box-sizing:content-box;-moz-box-sizing:content-box}.gantt_task_line.gantt_milestone div{visibility:visible}.gantt_task_line.gantt_milestone .gantt_task_content{background:inherit;border:inherit;border-width:1px;border-radius:inherit;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.gantt_task_line.gantt_task_inline_color{border-color:#999}.gantt_task_line.gantt_task_inline_color .gantt_task_progress{background-color:#363636;opacity:.2}.gantt_task_line.gantt_task_inline_color.gantt_project.gantt_selected,.gantt_task_line.gantt_task_inline_color.gantt_selected{box-shadow:0 0 5px #999}.gantt_task_link.gantt_link_inline_color:hover .gantt_line_wrapper div{box-shadow:0 0 5px 0 #999}.gantt_critical_task{background-color:#e63030;border-color:#9d3a3a}.gantt_critical_task .gantt_task_progress{background-color:rgba(0,0,0,.4)}.gantt_critical_link .gantt_line_wrapper>div{background-color:#e63030}.gantt_critical_link .gantt_link_arrow{border-color:#e63030}.gantt_unselectable,.gantt_unselectable div{-webkit-user-select:none;-moz-user-select:none;-moz-user-select:-moz-none}.gantt_cal_light{-webkit-tap-highlight-color:transparent;background:#fff;border-radius:6px;font-family:Arial;border:1px solid #cecece;color:#6b6b6b;font-size:12px;position:absolute;z-index:10001;width:550px;height:250px;box-shadow:3px 3px 3px rgba(0,0,0,.07)}.gantt_cal_light select{font-family:Arial;border:1px solid #cecece;font-size:13px;padding:2px;margin:0}.gantt_cal_ltitle{padding:7px 10px;overflow:hidden;white-space:nowrap;-webkit-border-radius:6px 6px 0 0;-moz-border-radius-topleft:6px;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:0;border-radius:6px 6px 0 0}.gantt_cal_ltitle span{white-space:nowrap}.gantt_cal_lsection{color:#727272;font-weight:700;padding:12px 0 5px 10px}.gantt_cal_lsection .gantt_fullday{float:right;margin-right:5px;font-size:12px;font-weight:400;line-height:20px;vertical-align:top;cursor:pointer}.gantt_cal_lsection{font-size:13px}.gantt_cal_ltext{padding:2px 10px;overflow:hidden}.gantt_cal_ltext textarea{overflow:auto;font-family:Arial;font-size:13px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid #cecece;height:100%;width:100%;outline:0!important;resize:none}.gantt_time{font-weight:700}.gantt_cal_light .gantt_title{padding-left:10px}.gantt_cal_larea{border:1px solid #cecece;border-left:none;border-right:none;background-color:#fff;overflow:hidden;height:1px}.gantt_btn_set{margin:10px 7px 5px 10px;padding:5px 15px 5px 10px;float:left;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;border-width:0;border-color:#cecece;border-style:solid;height:32px;font-weight:700;background:#fff;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:pointer}.gantt_btn_set div{float:left;font-size:13px;height:22px;line-height:22px;background-repeat:no-repeat;vertical-align:middle}.gantt_save_btn{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTk1OUU5RDFDMzA0MTFFMkExMUZBQTdDNDAzOUE5RjMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTk1OUU5RDJDMzA0MTFFMkExMUZBQTdDNDAzOUE5RjMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoxOTU5RTlDRkMzMDQxMUUyQTExRkFBN0M0MDM5QTlGMyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoxOTU5RTlEMEMzMDQxMUUyQTExRkFBN0M0MDM5QTlGMyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PjDroXYAAAEXSURBVHjaYvz//z8DJYCRUgPIAUxAbAnEHiAHMIBcQCwGaRYXF3e6evXqoffv39/dv38/CymaGSUkJBzv3LlzCsj///fv3wdAihkkIQnEvkAshU8zLy+v7a1bt06ANP/79+87kDIAy505cybq06dPr3p7ezuwGQLTfOPGjWP/ESAZLg8kPKBO+g01RBJNszWyZqC6uSgWgIg/f/4shxnS2dnZBjMEqNkSFGBImi8CKTYMA4BYCGjIczRDHC5dunQQSfN7IKWI4UUkjjdMMdCwnw8ePLjwHxV4Yw1gZA5Q47z/2EELzhhCE+ABGvIQWSeQvwcU38QaAML2wHj+C/X3MyAlijeB4ZBoBOIPQGxJKIVSnBsBAgwABddBclWfcZUAAAAASUVORK5CYII=);margin-top:2px;width:21px}.gantt_cancel_btn{margin-top:2px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDkzMDA3MzlDMzA0MTFFMjg2QTVFMzFEQzgwRkJERDYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MDkzMDA3M0FDMzA0MTFFMjg2QTVFMzFEQzgwRkJERDYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowOTMwMDczN0MzMDQxMUUyODZBNUUzMURDODBGQkRENiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowOTMwMDczOEMzMDQxMUUyODZBNUUzMURDODBGQkRENiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PmYuYOUAAAEdSURBVHjaYvz//z8DJYAFXWDlypU8QKoIiD2A2AwqfAqIdwBxX3h4+Bdk9YzILgBqtgdS84FYEYeF94E4EWjIQZgAE5LmQCB1AKoZZKMPEAtAMYh9GSp3AKjWD8UFQAEhIPshEIOc3wHENUBb/qJ57SyQMoJyPwKxElDNO1gYFEE17wMKVmIJlzNQzeegrjaA6qmBecEbSvfh0GwMxGeBhoPoemQ9MAO0kEIbl2YTqPAFKK2IbMB3AjabYIkRZmQD7kNpMyI0G0PpO8gGbIUFJj7NQDk2INWIrIcJKfBAKcwJqvkcDs0TgFgXGo19KCkRmpDWQdWDEk0NUoCBoq0FqhkE/IEWbKJKUmZEz43QzFSKIzN1481M5ACAAAMAlfl/lCwRpagAAAAASUVORK5CYII=);width:20px}.gantt_delete_btn{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MjFENzI3NUNDMzA0MTFFMjhBNjJGQTc3MUIyQzYzNEYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MjFENzI3NURDMzA0MTFFMjhBNjJGQTc3MUIyQzYzNEYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyMUQ3Mjc1QUMzMDQxMUUyOEE2MkZBNzcxQjJDNjM0RiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyMUQ3Mjc1QkMzMDQxMUUyOEE2MkZBNzcxQjJDNjM0RiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PmUD0gAAAABvSURBVHjaYvz//z8DIyMjAxYQicReji4J0ofKQNP8HwmgGQbXB8IsWGwDSSwDuioKjY9uBthVjFAXYHUGAQA2kYmBUoAUBpGk0LAwgBvwH+YX4mkwptgLowYMRgOITUyYKRFIN/wnDjQgJySAAAMApryKzL8wjfUAAAAASUVORK5CYII=);margin-top:2px;width:20px}.gantt_cal_cover{width:100%;height:100%;position:absolute;z-index:10000;top:0;left:0;background-color:#000;opacity:.1;filter:alpha(opacity=10)}.gantt_custom_button{padding:0 3px;font-family:Arial;font-size:13px;font-weight:400;margin-right:10px;margin-top:-5px;cursor:pointer;float:right;height:21px;width:90px;border:1px solid #CECECE;text-align:center;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;-o-border-radius:4px;border-radius:4px}.gantt_custom_button div{cursor:pointer;float:none;height:21px;line-height:21px;vertical-align:middle}.gantt_custom_button div:first-child{display:none}.gantt_cal_light_wide{width:580px;padding:2px 4px}.gantt_cal_light_wide .gantt_cal_larea{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid #cecece}.gantt_cal_light_wide .gantt_cal_lsection{border:0;float:left;text-align:right;width:80px;height:20px;padding:5px 10px 0 0}.gantt_cal_light_wide .gantt_wrap_section{position:relative;padding:10px 0;overflow:hidden;border-bottom:1px solid #ebebeb}.gantt_cal_light_wide .gantt_section_time{overflow:hidden;padding-top:2px!important;padding-right:0;height:20px!important}.gantt_cal_light_wide .gantt_cal_ltext{padding-right:0}.gantt_cal_light_wide .gantt_cal_larea{padding:0 10px;width:100%}.gantt_cal_light_wide .gantt_section_time{background:0 0}.gantt_cal_light_wide .gantt_cal_checkbox label{padding-left:0}.gantt_cal_light_wide .gantt_cal_lsection .gantt_fullday{float:none;margin-right:0;font-weight:700;cursor:pointer}.gantt_cal_light_wide .gantt_custom_button{position:absolute;top:0;right:0;margin-top:2px}.gantt_cal_light_wide .gantt_repeat_right{margin-right:55px}.gantt_cal_light_wide.gantt_cal_light_full{width:738px}.gantt_cal_wide_checkbox input{margin-top:8px;margin-left:14px}.gantt_cal_light input{font-size:13px}.gantt_section_time{background-color:#fff;white-space:nowrap;padding:5px 10px;padding-top:2px!important}.gantt_section_time .gantt_time_selects{float:left;height:25px}.gantt_section_time .gantt_time_selects select{height:23px;padding:2px;border:1px solid #cecece}.gantt_duration{width:100px;height:23px;float:left;white-space:nowrap;margin-left:20px;line-height:23px}.gantt_duration .gantt_duration_dec,.gantt_duration .gantt_duration_inc,.gantt_duration .gantt_duration_value{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center;vertical-align:top;height:100%;border:1px solid #cecece}.gantt_duration .gantt_duration_value{width:40px;padding:3px 4px;border-left-width:0;border-right-width:0}.gantt_duration .gantt_duration_dec,.gantt_duration .gantt_duration_inc{width:20px;padding:1px 1px 3px;background:#fff}.gantt_duration .gantt_duration_dec{-moz-border-top-left-radius:4px;-moz-border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;border-top-left-radius:4px;border-bottom-left-radius:4px}.gantt_duration .gantt_duration_inc{margin-right:4px;-moz-border-top-right-radius:4px;-moz-border-bottom-right-radius:4px;-webkit-border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:4px}.gantt_cal_quick_info{border:1px solid #cecece;border-radius:6px;position:absolute;z-index:300;box-shadow:3px 3px 3px rgba(0,0,0,.07);background-color:#fff;width:300px;transition:left .5s ease,right .5s;-moz-transition:left .5s ease,right .5s;-webkit-transition:left .5s ease,right .5s;-o-transition:left .5s ease,right .5s}.gantt_no_animate{transition:none;-moz-transition:none;-webkit-transition:none;-o-transition:none}.gantt_cal_quick_info.gantt_qi_left .gantt_qi_big_icon{float:right}.gantt_cal_qi_title{-webkit-border-radius:6px 6px 0 0;-moz-border-radius-topleft:6px;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:0;border-radius:6px 6px 0 0;padding:5px 0 8px 12px;color:#454545;background-color:#fff;border-bottom:1px solid #cecece}.gantt_cal_qi_tdate{font-size:14px;font-weight:700}.gantt_cal_qi_tcontent{font-size:13px}.gantt_cal_qi_content{padding:16px 8px;font-size:13px;color:#454545;overflow:hidden}.gantt_cal_qi_controls{-webkit-border-radius:0 0 6px 6px;-moz-border-radius-topleft:0;-moz-border-radius-bottomleft:6px;-moz-border-radius-topright:0;-moz-border-radius-bottomright:6px;border-radius:0 0 6px 6px;padding-left:7px}.gantt_cal_qi_controls .gantt_menu_icon{margin-top:6px;background-repeat:no-repeat}.gantt_cal_qi_controls .gantt_menu_icon.icon_edit{width:20px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3QYFCjI5ZQj5bAAAAFNJREFUOMvt0zEOACAIA0DkwTymH8bJTRTKZGJXyaWEKPKTCQAH4Ls37cItcDUzsxHNDLZNhCq7Gt1wh9ErV7EjyGAhyGLphlnsClWuS32rn0czAV+vNGrM/LBtAAAAAElFTkSuQmCC)}.gantt_cal_qi_controls .gantt_menu_icon.icon_delete{width:20px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MjFENzI3NUNDMzA0MTFFMjhBNjJGQTc3MUIyQzYzNEYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MjFENzI3NURDMzA0MTFFMjhBNjJGQTc3MUIyQzYzNEYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyMUQ3Mjc1QUMzMDQxMUUyOEE2MkZBNzcxQjJDNjM0RiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyMUQ3Mjc1QkMzMDQxMUUyOEE2MkZBNzcxQjJDNjM0RiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PmUD0gAAAABvSURBVHjaYvz//z8DIyMjAxYQicReji4J0ofKQNP8HwmgGQbXB8IsWGwDSSwDuioKjY9uBthVjFAXYHUGAQA2kYmBUoAUBpGk0LAwgBvwH+YX4mkwptgLowYMRgOITUyYKRFIN/wnDjQgJySAAAMApryKzL8wjfUAAAAASUVORK5CYII=)}.gantt_qi_big_icon{font-size:13px;border-radius:4px;font-weight:700;background:#fff;margin:5px 9px 8px 0;min-width:60px;line-height:32px;vertical-align:middle;padding:0 10px 0 5px;cursor:pointer;border:1px solid #cecece}.gantt_cal_qi_controls div{float:left;height:32px;text-align:center;line-height:32px}.gantt_tooltip{box-shadow:3px 3px 3px rgba(0,0,0,.07);background-color:#fff;border-left:1px solid rgba(0,0,0,.07);border-top:1px solid rgba(0,0,0,.07);font-family:Arial;font-size:8pt;color:#454545;padding:10px;position:absolute;z-index:50}.gantt_marker{height:100%;width:2px;top:0;position:absolute;text-align:center;background-color:rgba(255,0,0,.4);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.gantt_marker .gantt_marker_content{padding:5px;background:inherit;color:#fff;position:absolute;font-size:12px;line-height:12px;opacity:.8}.gantt_marker_area{position:absolute;top:0;left:0}.gantt_noselect{-moz-user-select:-moz-none;-webkit-user-select:none;-user-select:none}.gantt_drag_marker{position:absolute;font-family:Arial;font-size:13px}.gantt_drag_marker .gantt_tree_icon.gantt_blank,.gantt_drag_marker .gantt_tree_icon.gantt_close,.gantt_drag_marker .gantt_tree_icon.gantt_open,.gantt_drag_marker .gantt_tree_indent{display:none}.gantt_drag_marker,.gantt_drag_marker .gantt_row.odd{background-color:#fff}.gantt_drag_marker .gantt_row{border-left:1px solid #d2d2d2;border-top:1px solid #d2d2d2}.gantt_drag_marker .gantt_cell{border-color:#d2d2d2}.gantt_row.gantt_over,.gantt_task_row.gantt_over{background-color:#0070fe}.gantt_row.gantt_transparent .gantt_cell{opacity:.7}.gantt_task_row.gantt_transparent{background-color:#f8fdfd}.dhtmlx_popup_button.dhtmlx_delete_button{background:#3db9d3;text-shadow:0 -1px 0 #248a9f;color:#fff;font-weight:700;border-width:0}
\ No newline at end of file
diff --git a/plugins/easy_gantt/assets/stylesheets/easy_gantt/easy_gantt.css b/plugins/easy_gantt/assets/stylesheets/easy_gantt/easy_gantt.css
new file mode 100644
index 0000000..2ba9d39
--- /dev/null
+++ b/plugins/easy_gantt/assets/stylesheets/easy_gantt/easy_gantt.css
@@ -0,0 +1,661 @@
+/*
+* = require easy_gantt/dhtmlxgantt
+* = require_self
+* = require easy_gantt/sass/easy_gantt_sass.scss
+*/
+@media print {
+ .content-title {
+ display: none;
+ }
+
+ @page {
+ size: landscape
+ }
+
+ .gantt-grid-checkbox-cont {
+ display: none;
+ }
+}
+
+body {
+ -webkit-print-color-adjust: exact !important;
+}
+
+.gantt_container {
+ display: inline-block;
+}
+
+#gantt_cont {
+ position: relative;
+ z-index: 0;
+}
+
+#easy_gantt .weekend {
+ background-color: #F7F7F7;
+}
+
+#easy_gantt .first-date {
+ position: relative;
+}
+
+#easy_gantt .first-date:after {
+ content: "";
+ position: absolute;
+ display: block;
+ left: -1px;
+ top: 0;
+ bottom: 0;
+ border-left: 1px solid #628DB6;
+}
+
+#easy_gantt {
+ position: relative;
+}
+
+.gantt_task_content {
+ overflow: visible;
+ /*color:black;*/
+}
+
+.no_task_controls .gantt_link_control div {
+ display: none !important;
+}
+
+.gantt-fresh .gantt_link_control div {
+ display: none !important;
+}
+
+.no_task_controls .gantt_task_drag, .no_task_controls .gantt_task_progress_drag {
+ display: none !important;
+}
+
+#gantt_link_dialog {
+ border: 1px #000 solid;
+ background-color: #fff;
+ width: 200px;
+ position: absolute;
+ padding: 10px;
+ z-index: 2;
+}
+
+#gantt_link_dialog input[type="number"] {
+ width: 38px;
+}
+
+.gantt-tooltip {
+ position: absolute;
+ display: none;
+ background-color: white;
+ -webkit-box-shadow: 0 0 4px 2px rgba(232, 232, 232, 1);
+ -moz-box-shadow: 0 0 4px 2px rgba(232, 232, 232, 1);
+ box-shadow: 0 0 4px 2px rgba(232, 232, 232, 1);
+ padding: 20px;
+ z-index: 10;
+}
+
+.gantt-tooltip-header {
+ font-size: 1em;
+ padding-bottom: 10px;
+ border-bottom: 1px solid rgba(0, 0, 0, 0.2);
+ margin: 0 0 10px;
+}
+
+.gantt-tooltip-label {
+ font-size: 0.89em;
+ color: #a0a0a0;
+}
+
+.gantt-tooltip-problem {
+ color: #d94838;
+ font-size: smaller;
+}
+
+#easy_gantt.gantt .gantt_task_line.overdue {
+ background-color: #d94838;
+}
+
+#easy_gantt.easy .gantt_task_line, #easy_gantt.easy .gantt_row {
+ padding: 0;
+ border-width: 0 0 1px 0;
+}
+
+.gantt_task_progress {
+ /*background-color: rgba(0, 0, 0, 0.3);*/
+ margin-left: 1px;
+}
+
+#link_popup_button_cont {
+ margin-top: 35px;
+}
+
+#easy_gantt a.disabled:hover {
+ text-decoration: none;
+ cursor: not-allowed;
+}
+
+.milestone-type .gantt_cell {
+ border-right: 0;
+}
+
+.gantt-legend-color-square {
+ border: 1px solid transparent;
+ margin-left: 10px;
+}
+
+.gantt-color-square, .gantt-legend-color-square {
+ width: 15px;
+ height: 15px;
+ display: inline-block;
+ vertical-align: middle;
+ border: 1px solid transparent;
+}
+
+.easy-gantt-legend-symbol {
+ margin-left: 10px;
+}
+
+.gantt_cell {
+ padding: 0;
+}
+
+.gantt_grid {
+ border-right-width: 2px;
+}
+
+.gantt_row .gantt_drag_handle:before {
+ width: 18px;
+ height: 100%;
+ font-size: 20px;
+ font-weight: bold;
+}
+
+.gantt_row:hover .gantt_drag_handle:before {
+ content: '\21F5';
+ opacity: 0.5;
+}
+
+.gantt_row .gantt_drag_handle:hover:before {
+ opacity: 1;
+ content: '\21F5';
+}
+
+.gantt_row.gantt_drag_to_allowed {
+ background-color: #FFEB59;
+}
+
+.gantt_row.gantt_drag_hover {
+ background-color: #eeeeee;
+}
+
+.gantt_row.gantt_drag_to_allowed.gantt_drag_hover {
+ background-color: #FBCF00;
+}
+
+/*#sample_cont.flash {*/
+/*background-image: none;*/
+/*}*/
+.gantt-supertop-panel {
+ position: relative;
+}
+
+#easy_gantt .gantt-sample-flash {
+ font-size: 14px;
+}
+
+.gantt-menu {
+ z-index: 1;
+ position: relative;
+ background-color: #ffffff;
+ padding: 5px 0;
+}
+
+.gantt-footer-menu {
+ padding: 5px 0;
+}
+
+/*.easy-gantt-menu .action-buttons-with-submenu {*/
+/*display: inline;*/
+/*}*/
+.gantt-modal-video {
+ margin-left: 10px;
+ margin-top: 5px;
+}
+
+.gantt_drag_marker {
+ z-index: 1;
+ pointer-events: none;
+}
+
+.gantt_grid_column_resize_wrap, .gantt_grid_columns_resize_wrap {
+ top: 0;
+ height: 100%;
+ cursor: col-resize;
+ position: absolute;
+ /*background-color: red;*/
+ width: 12px
+}
+
+/*.gantt_task_line.parent{*/
+/*background-color: yellow;*/
+/*}*/
+.gantt-sample-close-button {
+ background-color: #cd0a0a;
+ color: white;
+ width: auto;
+ height: auto;
+ float: none;
+ display: inline;
+ margin-left: 25px;
+ padding: 8px 10px 8px 25px;
+ background-position-x: 5px;
+}
+
+/* Easy Redmine < 2016 */
+#easy_gantt.easy .push-left {
+ float: left;
+}
+
+#easy_gantt.easy .push-right {
+ float: right;
+ text-align: right
+}
+
+/*#easy_gantt.easy .gantt-menu p[id^="button_"], #easy_gantt.easy .gantt-menu div[id^="button_"] {*/
+/*display: inline-block;*/
+/*}*/
+.gantt_grid_data div.empty-type div {
+ display: none;
+}
+
+.gantt_bars_area div.empty-type {
+ display: none;
+}
+
+.gantt_task_line.planned {
+ z-index: 1;
+}
+
+.gantt_link_tooltip.gantt_link_deny {
+ background-color: #ff6666;
+}
+
+@media print {
+ #easy_servicebar {
+ display: none;
+ }
+
+ #easy_gantt_menu {
+ display: none;
+ }
+
+ #easy_gantt_footer {
+ display: none;
+ }
+
+ .flash {
+ display: none;
+ }
+}
+
+.gantt_grid_superitem {
+ font-weight: bold;
+ /*font-style: italic;*/
+ height: 100%;
+ width: 100%;
+ vertical-align: top;
+}
+
+.gantt_grid_scale, .gantt_task_scale {
+ background-color: #ffffff;
+ z-index: 1;
+ position: relative;
+ border-top: 1px solid #cecece;
+ transform: translate(0, -1px);
+}
+
+.gantt_grid_scale .gantt_grid_head_cell, .gantt_task .gantt_task_scale .gantt_scale_cell {
+ color: rgba(72, 72, 72, 0.8);
+}
+
+/*.gantt_scale_cell{*/
+/*overflow: visible;*/
+/*}*/
+
+.gantt-footer-legend {
+ display: inline-block;
+ float: right;
+ margin-top: 20px;
+}
+
+.gantt-legend-symbol {
+ font-size: 15px;
+}
+
+#easy_gantt input.wrong {
+ background-color: #cd0a0a;
+}
+
+.gantt-reload-model-error {
+ color: #cd0a0a;
+}
+
+.gantt_task_line {
+ background-color: inherit !important;
+ border: none !important;
+ box-shadow: none !important;
+}
+
+.gantt_task_line.gantt_selected .gantt_task_content {
+ box-shadow: none !important;
+}
+
+.gantt_task_line.closed .gantt_task_ticks,
+.gantt_task_line.closed .gantt_task_content {
+ background-color: rgba(200, 200, 200, 0.2);
+ border-color: rgba(200, 200, 200, 1);
+}
+
+.gantt_link_point {
+ border-color: rgba(217, 72, 56, 1) !important;
+ background-color: rgba(217, 72, 56, 1) !important;
+}
+
+.gantt_task_drag {
+ background: radial-gradient(rgba(217, 72, 56, 1) 25%, transparent 10%) 1px 1px;
+ background-size: 4px 4px;
+}
+
+.gantt_task_progress_drag {
+ border-bottom: 10px solid rgba(217, 72, 56, 1);
+}
+
+.gantt_line_wrapper div, .gantt_link_arrow {
+ border-color: rgba(255, 125, 30, 1);
+}
+
+.gantt-relation-simple > .gantt_line_wrapper div, .gantt-relation-simple > .gantt_link_arrow {
+ border-color: rgba(30, 120, 255, 1);
+}
+
+.gantt-relation-simple:hover > .gantt_line_wrapper div {
+ box-shadow: 0 0 5px 0 rgba(30, 120, 255, 1);
+}
+.gantt-relation-unlocked > .gantt_line_wrapper div, .gantt-relation-unlocked > .gantt_link_arrow {
+ border-color: rgba(51, 141, 71, 1);
+}
+
+.gantt-relation-unlocked:hover > .gantt_line_wrapper div {
+ box-shadow: 0 0 5px 0 rgba(255, 125, 30, 1);
+}
+
+#easy_gantt .wrong .gantt_line_wrapper div {
+ border-color: rgba(217, 72, 56, 1) !important;
+}
+
+#easy_gantt .wrong .gantt_link_arrow {
+ border-color: rgba(217, 72, 56, 1) !important;
+ border-top-color: transparent !important;
+ border-right-color: transparent !important;
+ border-bottom-color: transparent !important;
+}
+
+.gantt_task_progress_drag {
+ border-bottom: 10px solid rgba(217, 72, 56, 1);
+}
+
+#easy_gantt .gantt_link_arrow_right {
+ border-top-color: transparent !important;
+ border-right-color: transparent !important;
+ border-bottom-color: transparent !important;
+}
+
+.gantt_task_progress_drag {
+ width: 0 !important;
+ height: 0 !important;
+ background: none !important;
+ border-left: 6.5px solid transparent;
+ border-right: 6.5px solid transparent;
+ border-bottom-width: 10px;
+ border-bottom-style: solid;
+ margin-left: -6.5px !important;
+}
+
+.gantt_task_drag {
+ background-size: 4px 4px;
+}
+
+.gantt_link_control.task_left {
+ left: -6.5px;
+ width: 6.5px;
+ border-radius: 6.5px 0 0 6.5px;
+}
+
+.gantt_link_control.task_right {
+ right: -6.5px;
+ width: 6.5px;
+ border-radius: 0 6.5px 6.5px 0;
+}
+
+.gantt_link_control.task_left .gantt_link_point {
+ width: 6.5px;
+ border-radius: 6.5px 0 0 6.5px;
+}
+
+.gantt_link_control.task_right .gantt_link_point {
+ width: 6.5px;
+ border-radius: 0 6.5px 6.5px 0;
+}
+
+@media print {
+ body {
+ margin: 0;
+ }
+
+ .gantt_sort {
+ display: none;
+ }
+}
+
+.gantt-grid-header-collapse-buttons {
+ position: absolute;
+ left: 5px;
+ bottom: 2px;
+}
+
+.gantt-grid-header-collapse-buttons a {
+ font-size: 18px;
+ color: #a6a6a6;
+ font-weight: bold;
+ font-family: monospace;
+ display: inline-block;
+}
+
+.gantt-grid-header-collapse-buttons a.active {
+ font-size: 18px;
+ color: #d94838 !important;
+ background-color: transparent !important;
+ border: none !important;
+}
+
+.gantt-grid-header-collapse-buttons a:hover {
+ font-size: 18px;
+ color: rgba(72, 72, 72, 1);
+ text-decoration: none;
+ background-color: #eeeeee !important;
+ box-shadow: 0 0 15px 5px #eeeeee;
+ border-radius: 11px;
+}
+
+.gantt-grid-checkbox-cont br {
+ display: none;
+}
+
+@media screen {
+ .gantt-icon-parent-issue:before {
+ content: '⥐'
+ }
+
+ .gantt-icon-milestone:before {
+ content: '♦';
+ }
+}
+
+.gantt_task_line.gantt_parent_task-subtype .gantt_task_content {
+ height: 50%;
+ -moz-border-radius-bottomleft: 0;
+ -moz-border-radius-bottomright: 0;
+}
+
+.gantt_task_line.gantt_parent_task-subtype .gantt_task_progress {
+ height: 50%;
+}
+
+.gantt_task_ticks {
+ height: 0;
+ margin-top: -1px;
+ border: 10px solid rgba(51, 141, 71, 1);
+ border-top-width: 0;
+ border-bottom-color: transparent !important;
+ background-color: transparent !important;
+}
+
+.gantt-milestone-icon {
+ transform: scale(0.65) rotate(45deg);
+ width: 16px !important;
+ height: 16px !important;
+ background-color: rgba(62, 91, 118, 1);
+ border: 2px solid rgba(62, 91, 118, 1);
+}
+
+.gantt_row:hover .gantt-bullet-hover-hide {
+ display: none;
+}
+
+.gantt-sum-row-small {
+ font-size: 8px;
+}
+
+.gantt-sum-row-negative {
+ color: red;
+}
+
+#easy_gantt.easy #easy_gantt_menu {
+ z-index: 2;
+ overflow: visible;
+}
+
+#easy_gantt .contextual.settings a {
+ z-index: 1;
+ border: none;
+ padding-right: 0;
+ opacity: 0.6;
+}
+
+#easy_gantt.easy .contextual.settings a {
+ background: none;
+}
+
+#easy_gantt .contextual.settings a:hover {
+ opacity: 1;
+}
+
+#easy_gantt.easy .contextual.settings a:hover {
+ background: none;
+}
+
+.gantt-grid-header-multi {
+ line-height: normal;
+ display: inline-block;
+ white-space: normal;
+}
+
+.gantt_task_relation_stop {
+ position: absolute;
+ width: 8px;
+ top: 0;
+ height: 100%;
+ border: 2px solid rgba(255, 120, 0, 0.5);
+ box-sizing: border-box;
+}
+
+.gantt_task_relation_stop_left {
+ border-right-color: transparent;
+}
+
+.gantt_task_relation_stop_right {
+ border-left-color: transparent;
+ -webkit-transform: translate(-100%);
+ -moz-transform: translate(-100%);
+ -ms-transform: translate(-100%);
+ -o-transform: translate(-100%);
+ transform: translate(-100%);
+}
+
+.gantt-menu-sub-panel {
+ margin-top: 3px;
+}
+
+.gantt_task .gantt-sum-row .gantt_scale_cell {
+ font-weight: bold;
+ color: #260080;
+}
+
+.gantt-menu-problems-count.gantt-with-problems {
+ background-color: red;
+ padding: 1px;
+ border: 1px solid #b0b0b0;
+ border-radius: 4px;
+}
+
+.gantt-menu-problems-list {
+ overflow: auto;
+ position: absolute;
+ z-index: 2;
+ max-width: 600px;
+ margin-top: 5px;
+ border: 2px solid #cecece;
+ background-color: white;
+ right: 0;
+ text-align: left;
+}
+
+.gantt-menu-problems-list ol {
+ margin: 5px 5px 5px -5px;
+}
+
+.gantt-menu-problems-list li {
+ border-bottom: 1px solid #d9d9d9;
+ white-space: nowrap;
+ padding: 5px 25px 5px 5px;
+}
+
+.gantt-menu-problems-list ol,
+.gantt-menu-problems-list a {
+ color: #4b5561;
+}
+
+.gantt-menu-problems-reason {
+ color: red;
+}
+
+.gantt-task-bar-line {
+ position: absolute;
+ left: 0;
+ top: 0;
+ overflow: hidden
+}
+
+@media print {
+ /* Because of gaps between cells in header */
+ .gantt_scale_line.gantt-print__scale-line{
+ font-size: 0;
+ }
+ .gantt_scale_line.gantt-print__scale-line .gantt_scale_cell{
+ font-size: 12px;
+ }
+
+ .gantt_task_line.milestone-type > gantt_task_content{
+ background: black;
+
+ }
+}
diff --git a/plugins/easy_gantt/assets/stylesheets/easy_gantt/generated/easy_gantt.css b/plugins/easy_gantt/assets/stylesheets/easy_gantt/generated/easy_gantt.css
new file mode 100644
index 0000000..1fd11a2
--- /dev/null
+++ b/plugins/easy_gantt/assets/stylesheets/easy_gantt/generated/easy_gantt.css
@@ -0,0 +1,3369 @@
+/*
+@license
+
+dhtmlxGantt v.3.2.1 Stardard
+This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
+
+(c) Dinamenta, UAB.
+*/
+
+body {
+ -webkit-print-color-adjust: exact !important;
+}
+.gridHoverStyle,
+.gridSelection,
+.timelineSelection {
+ background-color: #fff3a1
+}
+.gantt_grid_scale .gantt_grid_head_cell {
+ color: #a6a6a6;
+ border-top: none!important;
+ /*border-right: none!important*/
+}
+/*.gantt_grid_data .gantt_cell {
+ border-right: none;
+ color: #454545
+}*/
+.gantt_task_link .gantt_link_arrow_right {
+ border-width: 6px;
+ margin-top: -3px
+}
+.gantt_task_link .gantt_link_arrow_left {
+ border-width: 6px;
+ margin-left: -6px;
+ margin-top: -3px
+}
+.gantt_task_link .gantt_link_arrow_down,
+.gantt_task_link .gantt_link_arrow_top {
+ border-width: 6px
+}
+.gantt_task_line .gantt_task_progress_drag {
+ bottom: -4px;
+ height: 16px;
+ margin-left: -8px;
+ width: 16px
+}
+.chartHeaderBg {
+ background-color: #fff
+}
+.gantt_task .gantt_task_scale .gantt_scale_cell {
+ color: #a6a6a6;
+ border-right: 1px solid #ebebeb
+}
+
+/*.gantt_row.gantt_project-type,*/
+/*.gantt_row.odd.gantt_project-type {*/
+/*background-color: #edffef*/
+/*}*/
+.gantt_task_row.gantt_project-type,
+.gantt_task_row.odd.gantt_project-type {
+ background-color: #f5fff6
+}
+.gantt_task_line.gantt_project-type {
+ background-color: #65c16f;
+ border: 1px solid #3c9445
+}
+.gantt_task_line.gantt_project-type .gantt_task_progress {
+ background-color: #46ad51
+}
+.buttonBg {
+ background: #fff
+}
+.gantt_cal_light .gantt_btn_set {
+ margin: 5px 10px
+}
+.gantt_btn_set.gantt_cancel_btn_set {
+ background: #fff;
+ color: #454545;
+ border: 1px solid #cecece
+}
+.gantt_btn_set.gantt_save_btn_set {
+ background: #3db9d3;
+ text-shadow: 0 -1px 0 #248a9f;
+ color: #fff
+}
+.gantt_btn_set.gantt_delete_btn_set {
+ background: #ec8e00;
+ text-shadow: 0 -1px 0 #a60;
+ color: #fff
+}
+.gantt_cal_light_wide {
+ padding-left: 0!important;
+ padding-right: 0!important
+}
+.gantt_cal_light_wide .gantt_cal_larea {
+ border-left: none!important;
+ border-right: none!important
+}
+.dhtmlx_popup_button.dhtmlx_ok_button {
+ background: #3db9d3;
+ text-shadow: 0 -1px 0 #248a9f;
+ color: #fff;
+ font-weight: 700;
+ border-width: 0
+}
+.dhtmlx_popup_button.dhtmlx_cancel_button {
+ font-weight: 700;
+ color: #454544
+}
+.gantt_qi_big_icon.icon_edit {
+ color: #454545;
+ background: #fff
+}
+.gantt_qi_big_icon.icon_delete {
+ text-shadow: 0 -1px 0 #a60;
+ background: #ec8e00;
+ color: #fff;
+ border-width: 0
+}
+.gantt_container {
+ font-family: Arial;
+ font-size: 13px;
+ border: 1px solid #cecece;
+ position: relative;
+ white-space: nowrap
+}
+.gantt_grid {
+ border-right: 1px solid #cecece
+}
+.gantt_task_scroll {
+ overflow-x: scroll
+}
+.gantt_task {
+ position: relative
+}
+.gantt_grid,
+.gantt_task {
+ overflow-x: hidden;
+ overflow-y: hidden;
+ display: inline-block;
+ vertical-align: top
+}
+.gantt_grid_scale,
+.gantt_task_scale {
+ color: #6b6b6b;
+ font-size: 12px;
+ border-bottom: 1px solid #cecece;
+ background-color: #fff
+}
+.gantt_scale_line {
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ border-top: 1px solid #cecece
+}
+.gantt_scale_line:first-child {
+ border-top: none
+}
+.gantt_grid_head_cell {
+ display: inline-block;
+ vertical-align: top;
+ border-right: 1px solid #cecece;
+ text-align: center;
+ position: relative;
+ cursor: default;
+ height: 100%;
+ -moz-user-select: -moz-none;
+ -webkit-user-select: none;
+ -user-select: none;
+ -ms-user-select: none;
+ overflow: hidden
+}
+.gantt_scale_line {
+ clear: both
+}
+.gantt_grid_data {
+ width: 100%;
+ overflow: hidden
+}
+.gantt_row {
+ position: relative;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -moz-user-select: -moz-none
+}
+.gantt_add,
+.gantt_grid_head_add {
+ width: 100%;
+ height: 100%;
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTQ3MjMyMENDNkI0MTFFMjk4MTI5QTg3MDhFNDVDQTkiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTQ3MjMyMERDNkI0MTFFMjk4MTI5QTg3MDhFNDVDQTkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1NDcyMzIwQUM2QjQxMUUyOTgxMjlBODcwOEU0NUNBOSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1NDcyMzIwQkM2QjQxMUUyOTgxMjlBODcwOEU0NUNBOSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PshZT8UAAABbSURBVHjaYrTdeZmBEsCER+4wEP+H4sPkGGCDg020ARR7gb4GIAcYDKMDdPnDyAbYkGG5DVW9cIQMvUdBBAuUY4vDz8iAcZinA2zgCHqAYQMseAywJcYFAAEGAM+UFGuohFczAAAAAElFTkSuQmCC);
+ background-position: center center;
+ background-repeat: no-repeat;
+ cursor: pointer;
+ position: relative;
+ -moz-opacity: .3;
+ opacity: .3
+}
+.gantt_grid_head_cell.gantt_grid_head_add {
+ -moz-opacity: .6;
+ opacity: .6;
+ top: 0
+}
+.gantt_grid_head_cell.gantt_grid_head_add:hover {
+ -moz-opacity: 1;
+ opacity: 1
+}
+@media screen {
+ .gantt_grid_data .gantt_row.odd:hover,
+ .gantt_grid_data .gantt_row:hover {
+ background-color: #fff3a1
+ }
+}
+.gantt_grid_data .gantt_row.odd:hover .gantt_add,
+.gantt_grid_data .gantt_row:hover .gantt_add {
+ -moz-opacity: 1;
+ opacity: 1
+}
+.gantt_row,
+.gantt_task_row {
+ border-bottom: 1px solid #ebebeb;
+ /*background-color: #fff*/
+}
+.gantt_row.odd,
+.gantt_task_row.odd {
+ /*background-color: #fff*/
+}
+.gantt_cell,
+.gantt_grid_head_cell,
+.gantt_row,
+.gantt_scale_cell,
+.gantt_task_cell,
+.gantt_task_row {
+ box-sizing: border-box;
+ -moz-box-sizing: border-box
+}
+.gantt_grid_head_cell,
+.gantt_scale_cell {
+ line-height: inherit
+}
+.gantt_grid .gantt_grid_resize_wrap {
+ cursor: col-resize;
+ position: absolute;
+ width: 13px;
+ z-index: 1
+}
+.gantt_grid_resize_wrap .gantt_grid_resize {
+ background-color: #cecece;
+ width: 1px;
+ margin: 0 auto
+}
+.gantt_drag_marker.gantt_grid_resize_area {
+ background-color: rgba(231, 231, 231, .5);
+ border-left: 1px solid #cecece;
+ border-right: 1px solid #cecece;
+ height: 100%;
+ width: 100%;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box
+}
+.gantt_cell {
+ display: inline-block;
+ vertical-align: top;
+ border-right: 1px solid #ebebeb;
+ padding-left: 6px;
+ padding-right: 6px;
+ height: 100%;
+ overflow: hidden;
+ white-space: nowrap;
+ font-size: 13px
+}
+.gantt_grid_data .gantt_last_cell,
+.gantt_grid_scale .gantt_last_cell,
+.gantt_task_bg .gantt_last_cell,
+.gantt_task_scale .gantt_last_cell {
+ border-right-width: 0
+}
+.gantt_task_bg {
+ overflow: hidden
+}
+.gantt_scale_cell {
+ display: inline-block;
+ white-space: nowrap;
+ overflow: hidden;
+ border-right: 1px solid #cecece;
+ text-align: center;
+ height: 100%
+}
+.gantt_task_cell {
+ display: inline-block;
+ height: 100%;
+ border-right: 1px solid #ebebeb
+}
+.gantt_ver_scroll {
+ width: 0;
+ background-color: transparent;
+ height: 1px;
+ overflow-x: hidden;
+ overflow-y: scroll;
+ display: none;
+ position: absolute;
+ right: 0
+}
+.gantt_ver_scroll>div {
+ width: 1px;
+ height: 1px
+}
+.gantt_hor_scroll {
+ height: 0;
+ background-color: transparent;
+ width: 100%;
+ clear: both;
+ overflow-x: scroll;
+ overflow-y: hidden;
+ display: none
+}
+.gantt_hor_scroll>div {
+ width: 5000px;
+ height: 1px
+}
+.gantt_tree_indent {
+ width: 15px;
+ /*height: 100%;*/
+ display: inline-block
+}
+.gantt_tree_content,
+.gantt_tree_icon {
+ vertical-align: top
+}
+.gantt_tree_icon {
+ width: 28px;
+ height: 100%;
+ display: inline-block;
+ background-repeat: no-repeat;
+ background-position: center center
+}
+.gantt_tree_content {
+ height: 100%;
+ display: inline-block
+}
+.gantt_tree_icon.gantt_open {
+ background-image: url(data:image/gif;base64,R0lGODlhEgASALMJAMrKyt3d3ejp6d7f3+/v75aWlvf39////wAAAP///wAAAAAAAAAAAAAAAAAAAAAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6M0I5RTczQjVDMDdBMTFFMTgxRjc4Mzk4M0Q3MjVFQzAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6M0I5RTczQjZDMDdBMTFFMTgxRjc4Mzk4M0Q3MjVFQzAiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDozQjlFNzNCM0MwN0ExMUUxODFGNzgzOTgzRDcyNUVDMCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDozQjlFNzNCNEMwN0ExMUUxODFGNzgzOTgzRDcyNUVDMCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAkALAAAAAASABIAAARJMMlJq704661B+SAIXAVhnKhBFKSZnmuLImhslXPN3ibi+6pdBXc4IIpB2YkGE1IKAoL0ICUInJNCYMDtDgJYiScUGnHO6LQkAgA7);
+ width: 18px;
+ cursor: pointer
+}
+.gantt_tree_icon.gantt_close {
+ background-image: url(data:image/gif;base64,R0lGODlhEgASALMJAMrKyt3d3ejp6d7f3+/v75aWlvf39wAAAP///////wAAAAAAAAAAAAAAAAAAAAAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MzY0QzNGM0VDMDdBMTFFMUE3MDlCNUM2QjU1NDA5RjgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MzY0QzNGM0ZDMDdBMTFFMUE3MDlCNUM2QjU1NDA5RjgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDozNjRDM0YzQ0MwN0ExMUUxQTcwOUI1QzZCNTU0MDlGOCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDozNjRDM0YzREMwN0ExMUUxQTcwOUI1QzZCNTU0MDlGOCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAkALAAAAAASABIAAARDMMlJq704661B+SAIXAVhnKhBFKSZnmv7wqxVzmpd3Uff5zKEUAi0uV4xm4DAbBIEOkohMKhaB4HoxBMKjTjgsFgSAQA7);
+ width: 18px;
+ cursor: pointer
+}
+.gantt_tree_icon.gantt_blank {
+ width: 18px
+}
+.gantt_tree_icon.gantt_folder_open {
+ background-image: url(data:image/gif;base64,R0lGODlhEgASAJECAJeXl7Gvrf///wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTdDRDM3QzVDMDZEMTFFMUJGMzhFMDhCN0RGRjBGQ0YiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTdDRDM3QzZDMDZEMTFFMUJGMzhFMDhCN0RGRjBGQ0YiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1N0NEMzdDM0MwNkQxMUUxQkYzOEUwOEI3REZGMEZDRiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1N0NEMzdDNEMwNkQxMUUxQkYzOEUwOEI3REZGMEZDRiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAIALAAAAAASABIAAAIzlI+pywcPm3mhWgkCsjBOvVkimElG9ZlCBlXd+2XjjLKg5GqoeZXqvsOQXK/ijUZTKVUFADs=)
+}
+.gantt_tree_icon.gantt_folder_closed {
+ background-image: url(data:image/gif;base64,R0lGODlhEgASAJECAJeXl7Gvrf///wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTAyMTU1RTNDMDZEMTFFMUJGNzZCRThBRkFCRjg4MTIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTAyMTU1RTRDMDZEMTFFMUJGNzZCRThBRkFCRjg4MTIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1MDIxNTVFMUMwNkQxMUUxQkY3NkJFOEFGQUJGODgxMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1MDIxNTVFMkMwNkQxMUUxQkY3NkJFOEFGQUJGODgxMiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAIALAAAAAASABIAAAIwlI+pywcPm3mhWgkCsjBOvVkimElG9ZlCuYIY6TYs+6bmHDO4igfdD3GNhheV0VQAADs=)
+}
+.gantt_tree_icon.gantt_file {
+ background-image: url(data:image/gif;base64,R0lGODlhEgASAJECAJeXl7Gvrf///wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzkxQzI4RjZDMDZEMTFFMTgwRjhBQURDQzI3NDU3QUEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzkxQzI4RjdDMDZEMTFFMTgwRjhBQURDQzI3NDU3QUEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3OTFDMjhGNEMwNkQxMUUxODBGOEFBRENDMjc0NTdBQSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3OTFDMjhGNUMwNkQxMUUxODBGOEFBRENDMjc0NTdBQSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAIALAAAAAASABIAAAIylI+pwN16QJiUQiFThRlJm3RRFYSlR5qXMKmXaMDuuMoyOi8n/e6xn8NMHETgh5RaKQsAOw==)
+}
+.gantt_grid_head_cell .gantt_sort {
+ position: absolute;
+ right: 5px;
+ top: 8px;
+ width: 7px;
+ height: 13px;
+ background-repeat: no-repeat;
+ background-position: center center
+}
+.gantt_grid_head_cell .gantt_sort.gantt_asc {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAANCAYAAABlyXS1AAAARUlEQVR4nGNgQAKGxib/GbABkIS7b8B/DAUwCRiGK0CXwFBAb1DfP/U/LszwHwi2X7qFgUEArBtdAVwCBmAKMCSQFSDzAWXXaOHsXeqkAAAAAElFTkSuQmCC)
+}
+.gantt_grid_head_cell .gantt_sort.gantt_desc {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAANCAYAAABlyXS1AAAARUlEQVR42mNgQAL1/VP/M2ADIIntF2/9x1AAlrh0C47hCmA60DFYwX88gIFGwNDY5D8uDFbg7hvwHx2jmIBTAlkB0e4BAEjlaNtBWJPnAAAAAElFTkSuQmCC)
+}
+.gantt_inserted,
+.gantt_updated {
+ font-weight: 700
+}
+.gantt_deleted {
+ text-decoration: line-through
+}
+.gantt_invalid {
+ background-color: #FFE0E0
+}
+.gantt_error {
+ color: red
+}
+.gantt_status {
+ right: 1px;
+ padding: 5px 10px;
+ background: rgba(155, 155, 155, .1);
+ position: absolute;
+ top: 1px;
+ -webkit-transition: opacity .2s;
+ transition: opacity .2s;
+ opacity: 0
+}
+.gantt_status.gantt_status_visible {
+ opacity: 1
+}
+#gantt_ajax_dots span {
+ -webkit-transition: opacity .2s;
+ transition: opacity .2s;
+ background-repeat: no-repeat;
+ opacity: 0
+}
+#gantt_ajax_dots span.gantt_dot_visible {
+ opacity: 1
+}
+.dhtmlx_message_area {
+ position: fixed;
+ right: 5px;
+ width: 250px;
+ z-index: 1000
+}
+.dhtmlx-message { // HOSEK
+min-width: 120px;
+ font-family: Arial;
+ z-index: 10000;
+ margin: 5px 5px 10px;
+ -webkit-transition: all .5s ease;
+ -moz-transition: all .5s ease;
+ -o-transition: all .5s ease;
+ transition: all .5s ease;
+ font-size: 14px;
+ color: #000;
+ box-shadow: 3px 3px 3px rgba(0, 0, 0, .07);
+ padding: 0;
+ background-color: #FFF;
+ border-radius: 3px;
+ border: 1px solid #fff
+}
+.dhtmlx-message.hidden { // HOSEK
+height: 0;
+ padding: 0;
+ border-width: 0;
+ margin: 0;
+ overflow: hidden
+}
+.dhtmlx_modal_box {
+ overflow: hidden;
+ display: inline-block;
+ min-width: 250px;
+ width: 250px;
+ text-align: center;
+ position: fixed;
+ z-index: 20000;
+ box-shadow: 3px 3px 3px rgba(0, 0, 0, .07);
+ font-family: Arial;
+ border-radius: 6px;
+ border: 1px solid #cecece;
+ background: #fff
+}
+.dhtmlx_popup_title {
+ border-top-left-radius: 6px;
+ border-top-right-radius: 6px;
+ border-width: 0
+}
+.dhtmlx_button,
+.dhtmlx_popup_button {
+ border: 1px solid #cecece;
+ height: 30px;
+ line-height: 30px;
+ display: inline-block;
+ margin: 0 5px;
+ border-radius: 4px;
+ background: #fff
+}
+.dhtmlx-message, /* HOSEK*/
+.dhtmlx_button,
+.dhtmlx_popup_button {
+ user-select: none;
+ -webkit-user-select: none;
+ -moz-user-select: -moz-none;
+ -ms-user-select: none;
+ cursor: pointer
+}
+.dhtmlx_popup_text {
+ overflow: hidden
+}
+.dhtmlx_popup_controls {
+ border-radius: 6px;
+ padding: 10px
+}
+.dhtmlx_popup_button {
+ min-width: 100px
+}
+div.dhx_modal_cover {
+ background-color: #000;
+ cursor: default;
+ filter: alpha(opacity=20);
+ opacity: .2;
+ position: fixed;
+ z-index: 19999;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ border: none;
+ zoom: 1
+}
+.dhtmlx-message img, /* HOSEK */
+.dhtmlx_modal_box img {
+ float: left;
+ margin-right: 20px
+}
+.dhtmlx-alert-error,
+.dhtmlx-confirm-error {
+ border: 1px solid red
+}
+.dhtmlx_button input,
+.dhtmlx_popup_button div {
+ border-radius: 4px;
+ font-size: 14px;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ padding: 0;
+ margin: 0;
+ vertical-align: top
+}
+.dhtmlx_popup_title {
+ color: #fff;
+ text-shadow: 1px 1px #000;
+ height: 40px;
+ line-height: 40px;
+ font-size: 20px
+}
+.dhtmlx_popup_text {
+ margin: 15px 15px 5px;
+ font-size: 14px;
+ color: #000;
+ min-height: 30px;
+ border-radius: 6px
+}
+
+/* HOSEK V */
+/*.dhtmlx-error,
+.dhtmlx-info {
+ font-size: 14px;
+ color: #000;
+ box-shadow: 3px 3px 3px rgba(0, 0, 0, .07);
+ padding: 0;
+ background-color: #FFF;
+ border-radius: 3px;
+ border: 1px solid #fff
+}*/
+.dhtmlx-message div {
+ padding: 5px 10px;
+ border-radius: 3px;
+}
+.dhtmlx-info div {
+ background-color: #fff;
+ border: 1px solid #cecece;
+}
+.dhtmlx-error {
+ background-color: #d81b1b;
+ border: 1px solid #ff3c3c;
+}
+.dhtmlx-error div {
+ background-color: #d81b1b;
+ border: 1px solid #940000;
+ color: #FFF;
+}
+.dhtmlx-success {
+ background-color: #2dff2d;
+ border: 1px solid #6CFF6C;
+}
+.dhtmlx-success div {
+ background-color: #2dff2d;
+ border: 1px solid #1B991B;
+ /*color: #FFF*/
+}
+/* HOSEK A */
+.gantt_data_area div,
+.gantt_grid div {
+ -ms-touch-action: none;
+ -webkit-tap-highlight-color: transparent
+}
+.gantt_data_area {
+ position: relative;
+ overflow-x: hidden;
+ overflow-y: hidden;
+ -moz-user-select: -moz-none;
+ -webkit-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.gantt_links_area {
+ position: absolute;
+ left: 0;
+ top: 0
+}
+.gantt_side_content,
+.gantt_task_content,
+.gantt_task_progress {
+ line-height: inherit;
+ overflow: hidden;
+ height: 100%
+}
+.gantt_task_content {
+ font-size: 12px;
+ /*color: #fff;*/
+ width: 100%;
+ top: 0;
+ position: absolute;
+ white-space: nowrap;
+ text-align: center
+}
+.gantt_task_progress {
+ text-align: center;
+ z-index: 0;
+ background: #299cb4
+}
+.gantt_task_line {
+ -webkit-border-radius: 2px;
+ -moz-border-radius: 2px;
+ border-radius: 2px;
+ position: absolute;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ background-color: #3db9d3;
+ border: 1px solid #2898b0;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -moz-user-select: -moz-none
+}
+.gantt_task_line.gantt_drag_move div {
+ cursor: move
+}
+.gantt_touch_move,
+.gantt_touch_progress .gantt_touch_resize {
+ -moz-transform: scale(1.02, 1.1);
+ -o-transform: scale(1.02, 1.1);
+ -webkit-transform: scale(1.02, 1.1);
+ transform: scale(1.02, 1.1);
+ -moz-transform-origin: 50%;
+ -o-transform-origin: 50%;
+ -webkit-transform-origin: 50%;
+ transform-origin: 50%
+}
+.gantt_touch_progress .gantt_task_progress_drag,
+.gantt_touch_resize .gantt_task_drag {
+ -moz-transform: scaleY(1.3);
+ -o-transform: scaleY(1.3);
+ -webkit-transform: scaleY(1.3);
+ transform: scaleY(1.3);
+ -moz-transform-origin: 50%;
+ -o-transform-origin: 50%;
+ -webkit-transform-origin: 50%;
+ transform-origin: 50%
+}
+.gantt_side_content {
+ position: absolute;
+ white-space: nowrap;
+ /*color: #6e6e6e;*/
+ bottom: 1px;
+ /*font-size: 14px*/
+}
+.gantt_side_content.gantt_left {
+ right: 100%;
+ padding-right: 15px
+}
+.gantt_side_content.gantt_right {
+ left: 100%;
+ padding-left: 15px
+}
+.gantt_side_content.gantt_link_crossing {
+ /*bottom: 8.75px*/
+}
+.gantt_link_arrow,
+.gantt_task_link .gantt_line_wrapper {
+ position: absolute;
+ cursor: pointer
+}
+.gantt_line_wrapper div {
+ /*background-color: #ffa011;*/
+ border: 1px solid #ffa011;
+}
+.gantt_task_link:hover .gantt_line_wrapper div {
+ box-shadow: 0 0 5px 0 #ffa011
+}
+.gantt_task_link div.gantt_link_arrow {
+ background-color: transparent;
+ border-style: solid;
+ width: 0;
+ height: 0
+}
+.gantt_link_control {
+ position: absolute;
+ width: 13px;
+ top: 0
+}
+.gantt_link_control div {
+ display: none;
+ cursor: pointer;
+ box-sizing: border-box;
+ position: relative;
+ top: 50%;
+ margin-top: -7.5px;
+ vertical-align: middle;
+ border: 1px solid #929292;
+ -webkit-border-radius: 6.5px;
+ -moz-border-radius: 6.5px;
+ border-radius: 6.5px;
+ height: 13px;
+ width: 13px;
+ background-color: #f0f0f0
+}
+.gantt_link_control div:hover {
+ background-color: #fff
+}
+.gantt_link_control.task_left {
+ left: -13px
+}
+.gantt_link_control.task_right {
+ right: -13px
+}
+.gantt_link_target .gantt_link_control div,
+.gantt_task_line.gantt_selected .gantt_link_control div,
+.gantt_task_line:hover .gantt_link_control div {
+ display: block
+}
+.gantt_link_source,
+.gantt_link_target {
+ box-shadow: 0 0 3px #3db9d3
+}
+.gantt_link_target.link_finish_allow,
+.gantt_link_target.link_start_allow {
+ box-shadow: 0 0 3px #ffbf5e
+}
+.gantt_link_target.link_finish_deny,
+.gantt_link_target.link_start_deny {
+ box-shadow: 0 0 3px #e87e7b
+}
+.link_finish_allow .gantt_link_control.task_right div,
+.link_start_allow .gantt_link_control.task_left div {
+ background-color: #ffbf5e;
+ border-color: #ffa011
+}
+.link_finish_deny .gantt_link_control.task_right div,
+.link_start_deny .gantt_link_control.task_left div {
+ background-color: #e87e7b;
+ border-color: #dd3e3a
+}
+.gantt_link_arrow_right {
+ border-width: 4px 0 4px 6px;
+ border-top-color: transparent!important;
+ border-right-color: transparent!important;
+ border-bottom-color: transparent!important;
+ border-color: #ffa011;
+ margin-top: -1px
+}
+.gantt_link_arrow_left {
+ border-width: 4px 6px 4px 0;
+ margin-top: -1px;
+ border-top-color: transparent!important;
+ border-color: #ffa011;
+ border-bottom-color: transparent!important;
+ border-left-color: transparent!important
+}
+.gantt_link_arrow_top {
+ border-width: 0 4px 6px;
+ border-color: #ffa011;
+ border-top-color: transparent!important;
+ border-right-color: transparent!important;
+ border-left-color: transparent!important
+}
+.gantt_link_arrow_down {
+ border-width: 4px 6px 0 4px;
+ border-color: #ffa011;
+ border-right-color: transparent!important;
+ border-bottom-color: transparent!important;
+ border-left-color: transparent!important
+}
+.gantt_task_drag,
+.gantt_task_progress_drag {
+ cursor: w-resize;
+ height: 100%;
+ display: none;
+ position: absolute
+}
+.gantt_task_line.gantt_selected .gantt_task_drag,
+.gantt_task_line.gantt_selected .gantt_task_progress_drag,
+.gantt_task_line:hover .gantt_task_drag,
+.gantt_task_line:hover .gantt_task_progress_drag {
+ display: block
+}
+.gantt_task_drag {
+ width: 6px;
+ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAACCAYAAAB7Xa1eAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QYDDjkw3UJvAwAAABRJREFUCNdj/P//PwM2wASl/6PTAKrrBf4+lD8LAAAAAElFTkSuQmCC);
+ z-index: 1;
+ top: 0
+}
+.gantt_task_drag.task_left {
+ left: 0
+}
+.gantt_task_drag.task_right {
+ right: 0
+}
+.gantt_task_progress_drag {
+ height: 8px;
+ width: 8px;
+ bottom: -4px;
+ margin-left: -4px;
+ background-position: bottom;
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAALCAYAAAB24g05AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MkY3Rjk0RUVDMkYzMTFFMkI1OThEQTA3ODU0OTkzMEEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MkY3Rjk0RUZDMkYzMTFFMkI1OThEQTA3ODU0OTkzMEEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyRjdGOTRFQ0MyRjMxMUUyQjU5OERBMDc4NTQ5OTMwQSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyRjdGOTRFREMyRjMxMUUyQjU5OERBMDc4NTQ5OTMwQSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PobPBzIAAADkSURBVHjaYpk2bRoDDsAExL1QdjEQ/8OmiAWHZk4gXqymqhQM4ty6fU8OSMUA8XdiDBAB4k0a6iqWRga6EKcwMQXduHlnL5DpB8Rv0J2JDFSA+JiOtgZcMwiA2CAxkBxUDVYDLEAKgIpV9XQ0MZwFEgPJAZnHoWpRDAgC4n2W5saiQKfjClQGkBxQDciL+6B6wAbkA/EqJwdrTkUFOQZCAKQGpBbIXA3SCzJggo+XK7OEuBgDsQCkFqgHrBfsBT5eHgZSAUwP2IBfv36TbABMDygdtK1Zv6UESLORaAbIhG6AAAMAKN8wE24DXWcAAAAASUVORK5CYII=);
+ background-repeat: no-repeat;
+ z-index: 2
+}
+.gantt_link_tooltip {
+ box-shadow: 3px 3px 3px #888;
+ background-color: #fff;
+ border-left: 1px dotted #cecece;
+ border-top: 1px dotted #cecece;
+ font-family: Tahoma;
+ font-size: 8pt;
+ color: #444;
+ padding: 6px;
+ line-height: 20px
+}
+.gantt_link_direction {
+ height: 0;
+ border: 0 #ffa011;
+ border-bottom-style: dashed;
+ border-bottom-width: 2px;
+ transform-origin: 0 0;
+ -ms-transform-origin: 0 0;
+ -webkit-transform-origin: 0 0;
+ z-index: 2;
+ margin-left: 1px;
+ position: absolute
+}
+.gantt_grid_data .gantt_row.gantt_selected,
+.gantt_grid_data .gantt_row.odd.gantt_selected,
+.gantt_task_row.gantt_selected {
+ background-color: #fff3a1
+}
+.gantt_task_row.gantt_selected .gantt_task_cell {
+ border-right-color: #ffec6e
+}
+.gantt_task_line.gantt_selected {
+ box-shadow: 0 0 5px #299cb4
+}
+.gantt_task_line.gantt_project-type.gantt_selected {
+ box-shadow: 0 0 5px #46ad51
+}
+.gantt_task_line.gantt_milestone-type {
+ visibility: hidden;
+ background-color: #d33daf;
+ border: 0 solid #61164f;
+ box-sizing: content-box;
+ -moz-box-sizing: content-box
+}
+.gantt_task_line.gantt_milestone-type div {
+ visibility: visible
+}
+.gantt_task_line.gantt_milestone-type .gantt_task_content {
+ background: inherit;
+ border: inherit;
+ border-width: 1px;
+ border-radius: inherit;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-transform: rotate(45deg);
+ -moz-transform: rotate(45deg);
+ -ms-transform: rotate(45deg);
+ -o-transform: rotate(45deg);
+ transform: rotate(45deg)
+}
+.gantt_task_line.gantt_task_inline_color {
+ border-color: #999
+}
+.gantt_task_line.gantt_task_inline_color .gantt_task_progress {
+ background-color: #363636;
+ opacity: .2
+}
+.gantt_task_line.gantt_task_inline_color.gantt_project-type.gantt_selected,
+.gantt_task_line.gantt_task_inline_color.gantt_selected {
+ box-shadow: 0 0 5px #999
+}
+.gantt_task_link.gantt_link_inline_color:hover .gantt_line_wrapper div {
+ box-shadow: 0 0 5px 0 #999
+}
+.gantt_critical_task {
+ background-color: #e63030;
+ border-color: #9d3a3a
+}
+.gantt_critical_task .gantt_task_progress {
+ background-color: rgba(0, 0, 0, .4)
+}
+.gantt_critical_link .gantt_line_wrapper>div {
+ background-color: #e63030
+}
+.gantt_critical_link .gantt_link_arrow {
+ border-color: #e63030
+}
+.gantt_unselectable,
+.gantt_unselectable div {
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -moz-user-select: -moz-none;
+ -ms-user-select: none;
+}
+.gantt_cal_light {
+ -webkit-tap-highlight-color: transparent;
+ background: #fff;
+ border-radius: 6px;
+ font-family: Arial;
+ border: 1px solid #cecece;
+ color: #6b6b6b;
+ font-size: 12px;
+ position: absolute;
+ z-index: 10001;
+ width: 550px;
+ height: 250px;
+ box-shadow: 3px 3px 3px rgba(0, 0, 0, .07)
+}
+.gantt_cal_light select {
+ font-family: Arial;
+ border: 1px solid #cecece;
+ font-size: 13px;
+ padding: 2px;
+ margin: 0
+}
+.gantt_cal_ltitle {
+ padding: 7px 10px;
+ overflow: hidden;
+ white-space: nowrap;
+ -webkit-border-radius: 6px 6px 0 0;
+ -moz-border-radius-topleft: 6px;
+ -moz-border-radius-bottomleft: 0;
+ -moz-border-radius-topright: 6px;
+ -moz-border-radius-bottomright: 0;
+ border-radius: 6px 6px 0 0
+}
+.gantt_cal_ltitle span {
+ white-space: nowrap
+}
+.gantt_cal_lsection {
+ color: #727272;
+ font-weight: 700;
+ padding: 12px 0 5px 10px
+}
+.gantt_cal_lsection .gantt_fullday {
+ float: right;
+ margin-right: 5px;
+ font-size: 12px;
+ font-weight: 400;
+ line-height: 20px;
+ vertical-align: top;
+ cursor: pointer
+}
+.gantt_cal_lsection {
+ font-size: 13px
+}
+.gantt_cal_ltext {
+ padding: 2px 10px;
+ overflow: hidden
+}
+.gantt_cal_ltext textarea {
+ overflow: auto;
+ font-family: Arial;
+ font-size: 13px;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ border: 1px solid #cecece;
+ height: 100%;
+ width: 100%;
+ outline: 0!important;
+ resize: none
+}
+.gantt_time {
+ font-weight: 700
+}
+.gantt_cal_light .gantt_title {
+ padding-left: 10px
+}
+.gantt_cal_larea {
+ border: 1px solid #cecece;
+ border-left: none;
+ border-right: none;
+ background-color: #fff;
+ overflow: hidden;
+ height: 1px
+}
+.gantt_btn_set {
+ margin: 10px 7px 5px 10px;
+ padding: 5px 15px 5px 10px;
+ float: left;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ border-width: 0;
+ border-color: #cecece;
+ border-style: solid;
+ height: 32px;
+ font-weight: 700;
+ background: #fff;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ cursor: pointer
+}
+.gantt_btn_set div {
+ float: left;
+ font-size: 13px;
+ height: 22px;
+ line-height: 22px;
+ background-repeat: no-repeat;
+ vertical-align: middle
+}
+.gantt_save_btn {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTk1OUU5RDFDMzA0MTFFMkExMUZBQTdDNDAzOUE5RjMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTk1OUU5RDJDMzA0MTFFMkExMUZBQTdDNDAzOUE5RjMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoxOTU5RTlDRkMzMDQxMUUyQTExRkFBN0M0MDM5QTlGMyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoxOTU5RTlEMEMzMDQxMUUyQTExRkFBN0M0MDM5QTlGMyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PjDroXYAAAEXSURBVHjaYvz//z8DJYCRUgPIAUxAbAnEHiAHMIBcQCwGaRYXF3e6evXqoffv39/dv38/CymaGSUkJBzv3LlzCsj///fv3wdAihkkIQnEvkAshU8zLy+v7a1bt06ANP/79+87kDIAy505cybq06dPr3p7ezuwGQLTfOPGjWP/ESAZLg8kPKBO+g01RBJNszWyZqC6uSgWgIg/f/4shxnS2dnZBjMEqNkSFGBImi8CKTYMA4BYCGjIczRDHC5dunQQSfN7IKWI4UUkjjdMMdCwnw8ePLjwHxV4Yw1gZA5Q47z/2EELzhhCE+ABGvIQWSeQvwcU38QaAML2wHj+C/X3MyAlijeB4ZBoBOIPQGxJKIVSnBsBAgwABddBclWfcZUAAAAASUVORK5CYII=);
+ margin-top: 2px;
+ width: 21px
+}
+.gantt_cancel_btn {
+ margin-top: 2px;
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDkzMDA3MzlDMzA0MTFFMjg2QTVFMzFEQzgwRkJERDYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MDkzMDA3M0FDMzA0MTFFMjg2QTVFMzFEQzgwRkJERDYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowOTMwMDczN0MzMDQxMUUyODZBNUUzMURDODBGQkRENiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowOTMwMDczOEMzMDQxMUUyODZBNUUzMURDODBGQkRENiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PmYuYOUAAAEdSURBVHjaYvz//z8DJYAFXWDlypU8QKoIiD2A2AwqfAqIdwBxX3h4+Bdk9YzILgBqtgdS84FYEYeF94E4EWjIQZgAE5LmQCB1AKoZZKMPEAtAMYh9GSp3AKjWD8UFQAEhIPshEIOc3wHENUBb/qJ57SyQMoJyPwKxElDNO1gYFEE17wMKVmIJlzNQzeegrjaA6qmBecEbSvfh0GwMxGeBhoPoemQ9MAO0kEIbl2YTqPAFKK2IbMB3AjabYIkRZmQD7kNpMyI0G0PpO8gGbIUFJj7NQDk2INWIrIcJKfBAKcwJqvkcDs0TgFgXGo19KCkRmpDWQdWDEk0NUoCBoq0FqhkE/IEWbKJKUmZEz43QzFSKIzN1481M5ACAAAMAlfl/lCwRpagAAAAASUVORK5CYII=);
+ width: 20px
+}
+.gantt_delete_btn {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MjFENzI3NUNDMzA0MTFFMjhBNjJGQTc3MUIyQzYzNEYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MjFENzI3NURDMzA0MTFFMjhBNjJGQTc3MUIyQzYzNEYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyMUQ3Mjc1QUMzMDQxMUUyOEE2MkZBNzcxQjJDNjM0RiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyMUQ3Mjc1QkMzMDQxMUUyOEE2MkZBNzcxQjJDNjM0RiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PmUD0gAAAABvSURBVHjaYvz//z8DIyMjAxYQicReji4J0ofKQNP8HwmgGQbXB8IsWGwDSSwDuioKjY9uBthVjFAXYHUGAQA2kYmBUoAUBpGk0LAwgBvwH+YX4mkwptgLowYMRgOITUyYKRFIN/wnDjQgJySAAAMApryKzL8wjfUAAAAASUVORK5CYII=);
+ margin-top: 2px;
+ width: 20px
+}
+.gantt_cal_cover {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ z-index: 10000;
+ top: 0;
+ left: 0;
+ background-color: #000;
+ opacity: .1;
+ filter: alpha(opacity=10)
+}
+.gantt_custom_button {
+ padding: 0 3px;
+ font-family: Arial;
+ font-size: 13px;
+ font-weight: 400;
+ margin-right: 10px;
+ margin-top: -5px;
+ cursor: pointer;
+ float: right;
+ height: 21px;
+ width: 90px;
+ border: 1px solid #CECECE;
+ text-align: center;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ -ms-border-radius: 4px;
+ -o-border-radius: 4px;
+ border-radius: 4px
+}
+.gantt_custom_button div {
+ cursor: pointer;
+ float: none;
+ height: 21px;
+ line-height: 21px;
+ vertical-align: middle
+}
+.gantt_custom_button div:first-child {
+ display: none
+}
+.gantt_cal_light_wide {
+ width: 580px;
+ padding: 2px 4px
+}
+.gantt_cal_light_wide .gantt_cal_larea {
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ border: 1px solid #cecece
+}
+.gantt_cal_light_wide .gantt_cal_lsection {
+ border: 0;
+ float: left;
+ text-align: right;
+ width: 80px;
+ height: 20px;
+ padding: 5px 10px 0 0
+}
+.gantt_cal_light_wide .gantt_wrap_section {
+ position: relative;
+ padding: 10px 0;
+ overflow: hidden;
+ border-bottom: 1px solid #ebebeb
+}
+.gantt_cal_light_wide .gantt_section_time {
+ overflow: hidden;
+ padding-top: 2px!important;
+ padding-right: 0;
+ height: 20px!important
+}
+.gantt_cal_light_wide .gantt_cal_ltext {
+ padding-right: 0
+}
+.gantt_cal_light_wide .gantt_cal_larea {
+ padding: 0 10px;
+ width: 100%
+}
+.gantt_cal_light_wide .gantt_section_time {
+ background: 0 0
+}
+.gantt_cal_light_wide .gantt_cal_checkbox label {
+ padding-left: 0
+}
+.gantt_cal_light_wide .gantt_cal_lsection .gantt_fullday {
+ float: none;
+ margin-right: 0;
+ font-weight: 700;
+ cursor: pointer
+}
+.gantt_cal_light_wide .gantt_custom_button {
+ position: absolute;
+ top: 0;
+ right: 0;
+ margin-top: 2px
+}
+.gantt_cal_light_wide .gantt_repeat_right {
+ margin-right: 55px
+}
+.gantt_cal_light_wide.gantt_cal_light_full {
+ width: 738px
+}
+.gantt_cal_wide_checkbox input {
+ margin-top: 8px;
+ margin-left: 14px
+}
+.gantt_cal_light input {
+ font-size: 13px
+}
+.gantt_section_time {
+ background-color: #fff;
+ white-space: nowrap;
+ padding: 5px 10px;
+ padding-top: 2px!important
+}
+.gantt_section_time .gantt_time_selects {
+ float: left;
+ height: 25px
+}
+.gantt_section_time .gantt_time_selects select {
+ height: 23px;
+ padding: 2px;
+ border: 1px solid #cecece
+}
+.gantt_duration {
+ width: 100px;
+ height: 23px;
+ float: left;
+ white-space: nowrap;
+ margin-left: 20px;
+ line-height: 23px
+}
+.gantt_duration .gantt_duration_dec,
+.gantt_duration .gantt_duration_inc,
+.gantt_duration .gantt_duration_value {
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ text-align: center;
+ vertical-align: top;
+ height: 100%;
+ border: 1px solid #cecece
+}
+.gantt_duration .gantt_duration_value {
+ width: 40px;
+ padding: 3px 4px;
+ border-left-width: 0;
+ border-right-width: 0
+}
+.gantt_duration .gantt_duration_dec,
+.gantt_duration .gantt_duration_inc {
+ width: 20px;
+ padding: 1px 1px 3px;
+ background: #fff
+}
+.gantt_duration .gantt_duration_dec {
+ -moz-border-top-left-radius: 4px;
+ -moz-border-bottom-left-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+ -webkit-border-bottom-left-radius: 4px;
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px
+}
+.gantt_duration .gantt_duration_inc {
+ margin-right: 4px;
+ -moz-border-top-right-radius: 4px;
+ -moz-border-bottom-right-radius: 4px;
+ -webkit-border-top-right-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px
+}
+.gantt_cal_quick_info {
+ border: 1px solid #cecece;
+ border-radius: 6px;
+ position: absolute;
+ z-index: 300;
+ box-shadow: 3px 3px 3px rgba(0, 0, 0, .07);
+ background-color: #fff;
+ width: 300px;
+ transition: left .5s ease, right .5s;
+ -moz-transition: left .5s ease, right .5s;
+ -webkit-transition: left .5s ease, right .5s;
+ -o-transition: left .5s ease, right .5s
+}
+.gantt_no_animate {
+ transition: none;
+ -moz-transition: none;
+ -webkit-transition: none;
+ -o-transition: none
+}
+.gantt_cal_quick_info.gantt_qi_left .gantt_qi_big_icon {
+ float: right
+}
+.gantt_cal_qi_title {
+ -webkit-border-radius: 6px 6px 0 0;
+ -moz-border-radius-topleft: 6px;
+ -moz-border-radius-bottomleft: 0;
+ -moz-border-radius-topright: 6px;
+ -moz-border-radius-bottomright: 0;
+ border-radius: 6px 6px 0 0;
+ padding: 5px 0 8px 12px;
+ color: #454545;
+ background-color: #fff;
+ border-bottom: 1px solid #cecece
+}
+.gantt_cal_qi_tdate {
+ font-size: 14px;
+ font-weight: 700
+}
+.gantt_cal_qi_tcontent {
+ font-size: 13px
+}
+.gantt_cal_qi_content {
+ padding: 16px 8px;
+ font-size: 13px;
+ color: #454545;
+ overflow: hidden
+}
+.gantt_cal_qi_controls {
+ -webkit-border-radius: 0 0 6px 6px;
+ -moz-border-radius-topleft: 0;
+ -moz-border-radius-bottomleft: 6px;
+ -moz-border-radius-topright: 0;
+ -moz-border-radius-bottomright: 6px;
+ border-radius: 0 0 6px 6px;
+ padding-left: 7px
+}
+.gantt_cal_qi_controls .gantt_menu_icon {
+ margin-top: 6px;
+ background-repeat: no-repeat
+}
+.gantt_cal_qi_controls .gantt_menu_icon.icon_edit {
+ width: 20px;
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3QYFCjI5ZQj5bAAAAFNJREFUOMvt0zEOACAIA0DkwTymH8bJTRTKZGJXyaWEKPKTCQAH4Ls37cItcDUzsxHNDLZNhCq7Gt1wh9ErV7EjyGAhyGLphlnsClWuS32rn0czAV+vNGrM/LBtAAAAAElFTkSuQmCC)
+}
+.gantt_cal_qi_controls .gantt_menu_icon.icon_delete {
+ width: 20px;
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MjFENzI3NUNDMzA0MTFFMjhBNjJGQTc3MUIyQzYzNEYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MjFENzI3NURDMzA0MTFFMjhBNjJGQTc3MUIyQzYzNEYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyMUQ3Mjc1QUMzMDQxMUUyOEE2MkZBNzcxQjJDNjM0RiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyMUQ3Mjc1QkMzMDQxMUUyOEE2MkZBNzcxQjJDNjM0RiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PmUD0gAAAABvSURBVHjaYvz//z8DIyMjAxYQicReji4J0ofKQNP8HwmgGQbXB8IsWGwDSSwDuioKjY9uBthVjFAXYHUGAQA2kYmBUoAUBpGk0LAwgBvwH+YX4mkwptgLowYMRgOITUyYKRFIN/wnDjQgJySAAAMApryKzL8wjfUAAAAASUVORK5CYII=)
+}
+.gantt_qi_big_icon {
+ font-size: 13px;
+ border-radius: 4px;
+ font-weight: 700;
+ background: #fff;
+ margin: 5px 9px 8px 0;
+ min-width: 60px;
+ line-height: 32px;
+ vertical-align: middle;
+ padding: 0 10px 0 5px;
+ cursor: pointer;
+ border: 1px solid #cecece
+}
+.gantt_cal_qi_controls div {
+ float: left;
+ height: 32px;
+ text-align: center;
+ line-height: 32px
+}
+.gantt_tooltip {
+ box-shadow: 3px 3px 3px rgba(0, 0, 0, .07);
+ background-color: #fff;
+ border-left: 1px solid rgba(0, 0, 0, .07);
+ border-top: 1px solid rgba(0, 0, 0, .07);
+ font-family: Arial;
+ font-size: 8pt;
+ color: #454545;
+ padding: 10px;
+ position: absolute;
+ z-index: 50
+}
+.gantt_marker {
+ height: 100%;
+ width: 2px;
+ top: 0;
+ position: absolute;
+ text-align: center;
+ background-color: rgba(255, 0, 0, .4);
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box
+}
+.gantt_marker .gantt_marker_content {
+ padding: 5px;
+ background: inherit;
+ color: #fff;
+ position: absolute;
+ font-size: 12px;
+ line-height: 12px;
+ opacity: .8
+}
+.gantt_marker_area {
+ position: absolute;
+ top: 0;
+ left: 0
+}
+.gantt_noselect {
+ -moz-user-select: -moz-none;
+ -webkit-user-select: none;
+ -ms-user-select: none;
+ user-select: none
+}
+.gantt_drag_marker {
+ position: absolute;
+ font-family: Arial;
+ font-size: 13px
+}
+.gantt_drag_marker .gantt_tree_icon.gantt_blank,
+.gantt_drag_marker .gantt_tree_icon.gantt_close,
+.gantt_drag_marker .gantt_tree_icon.gantt_open,
+.gantt_drag_marker .gantt_tree_indent {
+ display: none
+}
+.gantt_drag_marker,
+.gantt_drag_marker .gantt_row.odd {
+ background-color: #fff
+}
+.gantt_drag_marker .gantt_row {
+ border-left: 1px solid #d2d2d2;
+ border-top: 1px solid #d2d2d2
+}
+.gantt_drag_marker .gantt_cell {
+ border-color: #d2d2d2
+}
+.gantt_row.gantt_over,
+.gantt_task_row.gantt_over {
+ background-color: #0070fe
+}
+.gantt_row.gantt_transparent .gantt_cell {
+ opacity: .7
+}
+.gantt_task_row.gantt_transparent {
+ background-color: #f8fdfd
+}
+.dhtmlx_popup_button.dhtmlx_delete_button {
+ background: #3db9d3;
+ text-shadow: 0 -1px 0 #248a9f;
+ color: #fff;
+ font-weight: 700;
+ border-width: 0
+}
+/*
+
+
+
+*/
+
+@media print {
+ .content-title {
+ display: none;
+ }
+
+ @page {
+ size: landscape
+ }
+
+ .gantt-grid-checkbox-cont {
+ display: none;
+ }
+}
+
+.gantt_container {
+ display: inline-block;
+}
+
+#gantt_cont {
+ position: relative;
+ z-index: 0;
+}
+
+#easy_gantt .weekend {
+ background-color: #F7F7F7;
+}
+
+#easy_gantt .first-date {
+ position: relative;
+}
+
+#easy_gantt .first-date:after {
+ content: "";
+ position: absolute;
+ display: block;
+ left: -1px;
+ top: 0;
+ bottom: 0;
+ border-left: 1px solid #628DB6;
+}
+
+#easy_gantt {
+ position: relative;
+}
+
+.gantt_task_content {
+ overflow: visible;
+ /*color:black;*/
+}
+
+.no_task_controls .gantt_link_control div {
+ display: none !important;
+}
+
+.gantt-fresh .gantt_link_control div {
+ display: none !important;
+}
+
+.no_task_controls .gantt_task_drag, .no_task_controls .gantt_task_progress_drag {
+ display: none !important;
+}
+
+#gantt_link_dialog {
+ border: 1px #000 solid;
+ background-color: #fff;
+ width: 200px;
+ position: absolute;
+ padding: 10px;
+ z-index: 2;
+}
+
+#gantt_link_dialog input[type="number"] {
+ width: 38px;
+}
+
+.gantt-tooltip {
+ position: absolute;
+ display: none;
+ background-color: white;
+ -webkit-box-shadow: 0 0 4px 2px rgba(232, 232, 232, 1);
+ -moz-box-shadow: 0 0 4px 2px rgba(232, 232, 232, 1);
+ box-shadow: 0 0 4px 2px rgba(232, 232, 232, 1);
+ padding: 20px;
+ z-index: 10;
+}
+
+.gantt-tooltip-header {
+ font-size: 1em;
+ padding-bottom: 10px;
+ border-bottom: 1px solid rgba(0, 0, 0, 0.2);
+ margin: 0 0 10px;
+}
+
+.gantt-tooltip-label {
+ font-size: 0.89em;
+ color: #a0a0a0;
+}
+
+.gantt-tooltip-problem {
+ color: #d94838;
+ font-size: smaller;
+}
+
+#easy_gantt.gantt .gantt_task_line.overdue {
+ background-color: #d94838;
+}
+
+#easy_gantt.easy .gantt_task_line, #easy_gantt.easy .gantt_row {
+ padding: 0;
+ border-width: 0 0 1px 0;
+}
+
+.gantt_task_progress {
+ /*background-color: rgba(0, 0, 0, 0.3);*/
+ margin-left: 1px;
+}
+
+#link_popup_button_cont {
+ margin-top: 35px;
+}
+
+#easy_gantt a.disabled:hover {
+ text-decoration: none;
+ cursor: not-allowed;
+}
+
+.milestone-type .gantt_cell {
+ border-right: 0;
+}
+
+.gantt-legend-color-square {
+ border: 1px solid transparent;
+ margin-left: 10px;
+}
+
+.gantt-color-square, .gantt-legend-color-square {
+ width: 15px;
+ height: 15px;
+ display: inline-block;
+ vertical-align: middle;
+ border: 1px solid transparent;
+}
+
+.easy-gantt-legend-symbol {
+ margin-left: 10px;
+}
+
+.gantt_cell {
+ padding: 0;
+}
+
+.gantt_grid {
+ border-right-width: 2px;
+}
+
+.gantt_row .gantt_drag_handle:before {
+ width: 18px;
+ height: 100%;
+ font-size: 20px;
+ font-weight: bold;
+}
+
+.gantt_row:hover .gantt_drag_handle:before {
+ content: '\21F5';
+ opacity: 0.5;
+}
+
+.gantt_row .gantt_drag_handle:hover:before {
+ opacity: 1;
+ content: '\21F5';
+}
+
+.gantt_row.gantt_drag_to_allowed {
+ background-color: #FFEB59;
+}
+
+.gantt_row.gantt_drag_hover {
+ background-color: #eeeeee;
+}
+
+.gantt_row.gantt_drag_to_allowed.gantt_drag_hover {
+ background-color: #FBCF00;
+}
+
+/*#sample_cont.flash {*/
+/*background-image: none;*/
+/*}*/
+.gantt-supertop-panel {
+ position: relative;
+}
+
+#easy_gantt .gantt-sample-flash {
+ font-size: 14px;
+}
+
+.gantt-menu {
+ z-index: 1;
+ position: relative;
+ background-color: #ffffff;
+ padding: 5px 0;
+}
+
+.gantt-footer-menu {
+ padding: 5px 0;
+}
+
+/*.easy-gantt-menu .action-buttons-with-submenu {*/
+/*display: inline;*/
+/*}*/
+.gantt-modal-video {
+ margin-left: 10px;
+ margin-top: 5px;
+}
+
+.gantt_drag_marker {
+ z-index: 1;
+ pointer-events: none;
+}
+
+.gantt_grid_column_resize_wrap, .gantt_grid_columns_resize_wrap {
+ top: 0;
+ height: 100%;
+ cursor: col-resize;
+ position: absolute;
+ /*background-color: red;*/
+ width: 12px
+}
+
+/*.gantt_task_line.parent{*/
+/*background-color: yellow;*/
+/*}*/
+.gantt-sample-close-button {
+ background-color: #cd0a0a;
+ color: white;
+ width: auto;
+ height: auto;
+ float: none;
+ display: inline;
+ margin-left: 25px;
+ padding: 8px 10px 8px 25px;
+ background-position-x: 5px;
+}
+
+/* Easy Redmine < 2016 */
+#easy_gantt.easy .push-left {
+ float: left;
+}
+
+#easy_gantt.easy .push-right {
+ float: right;
+ text-align: right
+}
+
+/*#easy_gantt.easy .gantt-menu p[id^="button_"], #easy_gantt.easy .gantt-menu div[id^="button_"] {*/
+/*display: inline-block;*/
+/*}*/
+.gantt_grid_data div.empty-type div {
+ display: none;
+}
+
+.gantt_bars_area div.empty-type {
+ display: none;
+}
+
+.gantt_task_line.planned {
+ z-index: 1;
+}
+
+.gantt_link_tooltip.gantt_link_deny {
+ background-color: #ff6666;
+}
+
+@media print {
+ #easy_servicebar {
+ display: none;
+ }
+
+ #easy_gantt_menu {
+ display: none;
+ }
+
+ #easy_gantt_footer {
+ display: none;
+ }
+
+ .flash {
+ display: none;
+ }
+}
+
+.gantt_grid_superitem {
+ font-weight: bold;
+ /*font-style: italic;*/
+ height: 100%;
+ width: 100%;
+ vertical-align: top;
+}
+
+.gantt_grid_scale, .gantt_task_scale {
+ background-color: #ffffff;
+ z-index: 1;
+ position: relative;
+ border-top: 1px solid #cecece;
+ transform: translate(0, -1px);
+}
+
+.gantt_grid_scale .gantt_grid_head_cell, .gantt_task .gantt_task_scale .gantt_scale_cell {
+ color: rgba(72, 72, 72, 0.8);
+}
+
+/*.gantt_scale_cell{*/
+/*overflow: visible;*/
+/*}*/
+
+.gantt-footer-legend {
+ display: inline-block;
+ float: right;
+ margin-top: 20px;
+}
+
+.gantt-legend-symbol {
+ font-size: 15px;
+}
+
+#easy_gantt input.wrong {
+ background-color: #cd0a0a;
+}
+
+.gantt-reload-model-error {
+ color: #cd0a0a;
+}
+
+.gantt_task_line {
+ background-color: inherit !important;
+ border: none !important;
+ box-shadow: none !important;
+}
+
+.gantt_task_line.gantt_selected .gantt_task_content {
+ box-shadow: none !important;
+}
+
+.gantt_task_line.closed .gantt_task_ticks,
+.gantt_task_line.closed .gantt_task_content {
+ background-color: rgba(200, 200, 200, 0.2);
+ border-color: rgba(200, 200, 200, 1);
+}
+
+.gantt_link_point {
+ border-color: rgba(217, 72, 56, 1) !important;
+ background-color: rgba(217, 72, 56, 1) !important;
+}
+
+.gantt_task_drag {
+ background: radial-gradient(rgba(217, 72, 56, 1) 25%, transparent 10%) 1px 1px;
+ background-size: 4px 4px;
+}
+
+.gantt_task_progress_drag {
+ border-bottom: 10px solid rgba(217, 72, 56, 1);
+}
+
+.gantt_line_wrapper div, .gantt_link_arrow {
+ border-color: rgba(255, 125, 30, 1);
+}
+
+.gantt-relation-simple > .gantt_line_wrapper div, .gantt-relation-simple > .gantt_link_arrow {
+ border-color: rgba(30, 120, 255, 1);
+}
+
+.gantt-relation-simple:hover > .gantt_line_wrapper div {
+ box-shadow: 0 0 5px 0 rgba(30, 120, 255, 1);
+}
+.gantt-relation-unlocked > .gantt_line_wrapper div, .gantt-relation-unlocked > .gantt_link_arrow {
+ border-color: rgba(51, 141, 71, 1);
+}
+
+.gantt-relation-unlocked:hover > .gantt_line_wrapper div {
+ box-shadow: 0 0 5px 0 rgba(255, 125, 30, 1);
+}
+
+#easy_gantt .wrong .gantt_line_wrapper div {
+ border-color: rgba(217, 72, 56, 1) !important;
+}
+
+#easy_gantt .wrong .gantt_link_arrow {
+ border-color: rgba(217, 72, 56, 1) !important;
+ border-top-color: transparent !important;
+ border-right-color: transparent !important;
+ border-bottom-color: transparent !important;
+}
+
+.gantt_task_progress_drag {
+ border-bottom: 10px solid rgba(217, 72, 56, 1);
+}
+
+#easy_gantt .gantt_link_arrow_right {
+ border-top-color: transparent !important;
+ border-right-color: transparent !important;
+ border-bottom-color: transparent !important;
+}
+
+.gantt_task_progress_drag {
+ width: 0 !important;
+ height: 0 !important;
+ background: none !important;
+ border-left: 6.5px solid transparent;
+ border-right: 6.5px solid transparent;
+ border-bottom-width: 10px;
+ border-bottom-style: solid;
+ margin-left: -6.5px !important;
+}
+
+.gantt_task_drag {
+ background-size: 4px 4px;
+}
+
+.gantt_link_control.task_left {
+ left: -6.5px;
+ width: 6.5px;
+ border-radius: 6.5px 0 0 6.5px;
+}
+
+.gantt_link_control.task_right {
+ right: -6.5px;
+ width: 6.5px;
+ border-radius: 0 6.5px 6.5px 0;
+}
+
+.gantt_link_control.task_left .gantt_link_point {
+ width: 6.5px;
+ border-radius: 6.5px 0 0 6.5px;
+}
+
+.gantt_link_control.task_right .gantt_link_point {
+ width: 6.5px;
+ border-radius: 0 6.5px 6.5px 0;
+}
+
+@media print {
+ body {
+ margin: 0;
+ }
+
+ .gantt_sort {
+ display: none;
+ }
+}
+
+.gantt-grid-header-collapse-buttons {
+ position: absolute;
+ left: 5px;
+ bottom: 2px;
+}
+
+.gantt-grid-header-collapse-buttons a {
+ font-size: 18px;
+ color: #a6a6a6;
+ font-weight: bold;
+ font-family: monospace;
+ display: inline-block;
+}
+
+.gantt-grid-header-collapse-buttons a.active {
+ font-size: 18px;
+ color: #d94838 !important;
+ background-color: transparent !important;
+ border: none !important;
+}
+
+.gantt-grid-header-collapse-buttons a:hover {
+ font-size: 18px;
+ color: rgba(72, 72, 72, 1);
+ text-decoration: none;
+ background-color: #eeeeee !important;
+ box-shadow: 0 0 15px 5px #eeeeee;
+ border-radius: 11px;
+}
+
+.gantt-grid-checkbox-cont br {
+ display: none;
+}
+
+@media screen {
+ .gantt-icon-parent-issue:before {
+ content: '⥐'
+ }
+
+ .gantt-icon-milestone:before {
+ content: '♦';
+ }
+}
+
+.gantt_task_line.gantt_parent_task-subtype .gantt_task_content {
+ height: 50%;
+ -moz-border-radius-bottomleft: 0;
+ -moz-border-radius-bottomright: 0;
+}
+
+.gantt_task_line.gantt_parent_task-subtype .gantt_task_progress {
+ height: 50%;
+}
+
+.gantt_task_ticks {
+ height: 0;
+ margin-top: -1px;
+ border: 10px solid rgba(51, 141, 71, 1);
+ border-top-width: 0;
+ border-bottom-color: transparent !important;
+ background-color: transparent !important;
+}
+
+.gantt-milestone-icon {
+ transform: scale(0.65) rotate(45deg);
+ width: 16px !important;
+ height: 16px !important;
+ background-color: rgba(62, 91, 118, 1);
+ border: 2px solid rgba(62, 91, 118, 1);
+}
+
+.gantt_row:hover .gantt-bullet-hover-hide {
+ display: none;
+}
+
+.gantt-sum-row-small {
+ font-size: 8px;
+}
+
+.gantt-sum-row-negative {
+ color: red;
+}
+
+#easy_gantt.easy #easy_gantt_menu {
+ z-index: 2;
+ overflow: visible;
+}
+
+#easy_gantt .contextual.settings a {
+ z-index: 1;
+ border: none;
+ padding-right: 0;
+ opacity: 0.6;
+}
+
+#easy_gantt.easy .contextual.settings a {
+ background: none;
+}
+
+#easy_gantt .contextual.settings a:hover {
+ opacity: 1;
+}
+
+#easy_gantt.easy .contextual.settings a:hover {
+ background: none;
+}
+
+.gantt-grid-header-multi {
+ line-height: normal;
+ display: inline-block;
+ white-space: normal;
+}
+
+.gantt_task_relation_stop {
+ position: absolute;
+ width: 8px;
+ top: 0;
+ height: 100%;
+ border: 2px solid rgba(255, 120, 0, 0.5);
+ box-sizing: border-box;
+}
+
+.gantt_task_relation_stop_left {
+ border-right-color: transparent;
+}
+
+.gantt_task_relation_stop_right {
+ border-left-color: transparent;
+ -webkit-transform: translate(-100%);
+ -moz-transform: translate(-100%);
+ -ms-transform: translate(-100%);
+ -o-transform: translate(-100%);
+ transform: translate(-100%);
+}
+
+.gantt-menu-sub-panel {
+ margin-top: 3px;
+}
+
+.gantt_task .gantt-sum-row .gantt_scale_cell {
+ font-weight: bold;
+ color: #260080;
+}
+
+.gantt-menu-problems-count.gantt-with-problems {
+ background-color: red;
+ padding: 1px;
+ border: 1px solid #b0b0b0;
+ border-radius: 4px;
+}
+
+.gantt-menu-problems-list {
+ overflow: auto;
+ position: absolute;
+ z-index: 2;
+ max-width: 600px;
+ margin-top: 5px;
+ border: 2px solid #cecece;
+ background-color: white;
+ right: 0;
+ text-align: left;
+}
+
+.gantt-menu-problems-list ol {
+ margin: 5px 5px 5px -5px;
+}
+
+.gantt-menu-problems-list li {
+ border-bottom: 1px solid #d9d9d9;
+ white-space: nowrap;
+ padding: 5px 25px 5px 5px;
+}
+
+.gantt-menu-problems-list ol,
+.gantt-menu-problems-list a {
+ color: #4b5561;
+}
+
+.gantt-menu-problems-reason {
+ color: red;
+}
+
+.gantt-task-bar-line {
+ position: absolute;
+ left: 0;
+ top: 0;
+ overflow: hidden
+}
+
+@media print {
+ /* Because of gaps between cells in header */
+ .gantt_scale_line.gantt-print__scale-line{
+ font-size: 0;
+ }
+ .gantt_scale_line.gantt-print__scale-line .gantt_scale_cell{
+ font-size: 12px;
+ }
+}
+/*----------------------------------------*/
+/* Vendors */
+/*----------------------------------------*/
+/*----------------------------------------*/
+/* Mixins & Placeholders */
+/*----------------------------------------*/
+/* line 88, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/css3.scss */
+div#easy_gantt.easy .button.active, .easy .easy-gantt__menu-group--tooltiped ul li > .menu-children, .easy .easy-gantt__menu-group--tooltiped ul {
+ -webkit-border-radius: 2px;
+ -moz-border-radius: 2px;
+ border-radius: 2px;
+}
+
+/* line 97, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/css3.scss */
+.easy-gantt__menu .gantt-menu-problems-count.gantt-with-problems {
+ -webkit-border-radius: 5000px;
+ -moz-border-radius: 5000px;
+ border-radius: 5000px;
+}
+
+/* line 118, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/css3.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li > .menu-children, .easy .easy-gantt__menu-group--tooltiped ul {
+ -webkit-box-shadow: 0px 0px 5px 0 rgba(0, 0, 0, 0.125);
+ -moz-box-shadow: 0px 0px 5px 0 rgba(0, 0, 0, 0.125);
+ box-shadow: 0px 0px 5px 0 rgba(0, 0, 0, 0.125);
+}
+
+/* line 130, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/css3.scss */
+div#easy_gantt.easy .active.button {
+ -webkit-box-shadow: inset 0px 1px 10px 0px rgba(0, 0, 0, 0.125);
+ -moz-box-shadow: inset 0px 1px 10px 0px rgba(0, 0, 0, 0.125);
+ box-shadow: inset 0px 1px 10px 0px rgba(0, 0, 0, 0.125);
+}
+
+/* line 305, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/css3.scss */
+.easy-gantt__menu {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+/* line 502, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/css3.scss */
+.easy-gantt__menu {
+ display: -webkit-box;
+ display: -moz-box;
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
+}
+
+/* line 524, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/css3.scss */
+.easy-gantt__menu {
+ -webkit-justify-content: space-between;
+ -ms-justify-content: space-between;
+ justify-content: space-between;
+}
+
+/* line 551, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/css3.scss */
+.easy-gantt__menu {
+ -webkit-flex-wrap: wrap;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+}
+
+/* line 15, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/typography.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li {
+ font-family: "Open Sans", sans-serif;
+ font-size: 13px;
+ line-height: 1.5;
+ font-weight: normal;
+ color: #42321a;
+}
+
+@media only screen and (min-resolution: 100dpi) {
+ /* line 15, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/typography.scss */
+ .easy .easy-gantt__menu-group--tooltiped ul li {
+ font-size: 14px;
+ }
+}
+
+@media only screen and (max-width: 960px) {
+ /* line 15, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/typography.scss */
+ .easy .easy-gantt__menu-group--tooltiped ul li {
+ font-size: 11px;
+ }
+}
+
+@media only screen and (max-width: 960px) and (min-resolution: 100dpi) {
+ /* line 15, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/typography.scss */
+ .easy .easy-gantt__menu-group--tooltiped ul li {
+ font-size: 13px;
+ }
+}
+
+@media only screen and (min-width: 1401px) {
+ /* line 15, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/typography.scss */
+ .easy .easy-gantt__menu-group--tooltiped ul li {
+ font-size: 14px;
+ }
+}
+
+@media only screen and (min-width: 1401px) and (min-resolution: 100dpi) {
+ /* line 15, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/typography.scss */
+ .easy .easy-gantt__menu-group--tooltiped ul li {
+ font-size: 16px;
+ }
+}
+
+@media only screen and (min-width: 1901px) {
+ /* line 15, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/typography.scss */
+ .easy .easy-gantt__menu-group--tooltiped ul li {
+ font-size: 15px;
+ }
+}
+
+@media only screen and (min-width: 1901px) and (min-resolution: 100dpi) {
+ /* line 15, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/typography.scss */
+ .easy .easy-gantt__menu-group--tooltiped ul li {
+ font-size: 17px;
+ }
+}
+
+/* line 98, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/typography.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li a {
+ -ms-word-break: break-all;
+ word-break: break-word;
+ -webkit-hyphens: auto;
+ -moz-hyphens: auto;
+ -ms-hyphens: auto;
+ hyphens: auto;
+}
+
+/* line 1, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/icons.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li a.submenu:after, .easy-gantt__icon:before {
+ speak: none;
+ font-weight: normal;
+ font-style: normal;
+ text-decoration: none;
+ -webkit-font-smoothing: antialiased;
+ display: inline-block;
+ width: auto;
+ height: auto;
+ background-position: 0% 0%;
+ background-repeat: repeat;
+ background-image: none;
+ vertical-align: baseline;
+}
+
+/* line 21, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/icons.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li a.submenu:after, .easy-gantt__icon:before {
+ font-family: "EasyIcons";
+}
+
+/* line 24, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/icons.scss */
+.easy-gantt__icon {
+ position: relative;
+ background-repeat: no-repeat;
+ background-image: none !important;
+}
+
+/* line 2, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/pseudo.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li > .menu-children:after, .easy .easy-gantt__menu-group--tooltiped ul li > .menu-children:before {
+ content: "";
+ display: block;
+ z-index: 1;
+}
+
+/* line 7, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/pseudo.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li > .menu-children {
+ position: relative;
+}
+
+/* line 12, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/pseudo.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li > .menu-children:after {
+ position: absolute;
+}
+
+/* line 19, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/pseudo.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li > .menu-children:before {
+ position: absolute;
+}
+
+/* line 16, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+.splitcontent .contextual div#easy_gantt.easy .button.active, div#easy_gantt.easy .splitcontent .contextual .button.active {
+ padding: 2.5px 5px !important;
+ font-size: 0.89em;
+}
+
+/* line 19, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+.splitcontent .contextual div#easy_gantt.easy .icon.button.active, div#easy_gantt.easy .splitcontent .contextual .icon.button.active {
+ padding-left: 30px !important;
+}
+
+/* line 21, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+.splitcontent .contextual div#easy_gantt.easy .icon.button.active:before, div#easy_gantt.easy .splitcontent .contextual .icon.button.active:before {
+ width: 30px !important;
+ font-size: 1.1em;
+}
+
+/* line 26, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+#sidebar .splitcontent .contextual div#easy_gantt.easy .button.active, .splitcontent .contextual div#easy_gantt.easy #sidebar .button.active, #sidebar div#easy_gantt.easy .splitcontent .contextual .button.active, div#easy_gantt.easy .splitcontent .contextual #sidebar .button.active, #easy_grid_sidebar .splitcontent .contextual div#easy_gantt.easy .button.active, .splitcontent .contextual div#easy_gantt.easy #easy_grid_sidebar .button.active, #easy_grid_sidebar div#easy_gantt.easy .splitcontent .contextual .button.active, div#easy_gantt.easy .splitcontent .contextual #easy_grid_sidebar .button.active {
+ display: inline-block !important;
+}
+
+/* line 46, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+div#easy_gantt.easy .icon.button.active:before {
+ position: absolute;
+ left: 0;
+ width: 30px;
+ text-align: center;
+ font-size: 1.2em;
+ line-height: 1;
+ color: inherit;
+ top: 50%;
+ margin-top: -0.5em;
+}
+
+/* line 58, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+#sidebar div#easy_gantt.easy .icon.button.active, div#easy_gantt.easy #sidebar .icon.button.active, #easy_grid_sidebar div#easy_gantt.easy .icon.button.active, div#easy_gantt.easy #easy_grid_sidebar .icon.button.active {
+ padding-left: 40px !important;
+}
+
+/* line 60, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+#sidebar div#easy_gantt.easy .icon.button.active:before, div#easy_gantt.easy #sidebar .icon.button.active:before, #easy_grid_sidebar div#easy_gantt.easy .icon.button.active:before, div#easy_gantt.easy #easy_grid_sidebar .icon.button.active:before {
+ width: 40px !important;
+}
+
+/* line 64, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+div#easy_gantt.easy .button.active {
+ font-size: 0.89em;
+ font-weight: bold;
+ display: inline-block;
+ border: 1px solid transparent;
+ padding: 5px 10px;
+ text-align: left;
+ cursor: pointer;
+ position: relative;
+ vertical-align: middle;
+}
+
+/* line 75, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+div#easy_gantt.easy .icon.button.active {
+ padding-left: 30px;
+}
+
+/* line 82, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+#sidebar div#easy_gantt.easy .button.active, div#easy_gantt.easy #sidebar .button.active, #easy_grid_sidebar div#easy_gantt.easy .button.active, div#easy_gantt.easy #easy_grid_sidebar .button.active {
+ display: block;
+ position: relative !important;
+ z-index: 2;
+ padding-left: 20px;
+ margin-bottom: 3px;
+}
+
+@media only screen and (min-width: 641px) {
+ /* line 93, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+ .nosidebar #sidebar div#easy_gantt.easy .button.active:hover, div#easy_gantt.easy .nosidebar #sidebar .button.active:hover, .nosidebar #easy_grid_sidebar div#easy_gantt.easy .button.active:hover, div#easy_gantt.easy .nosidebar #easy_grid_sidebar .button.active:hover {
+ -webkit-animation: sidebar-buttons-slide-left 0.25s forwards;
+ -moz-animation: sidebar-buttons-slide-left 0.25s forwards;
+ -ms-animation: sidebar-buttons-slide-left 0.25s forwards;
+ -o-animation: sidebar-buttons-slide-left 0.25s forwards;
+ animation: sidebar-buttons-slide-left 0.25s forwards;
+ }
+}
+
+/* line 99, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+.form-actions div#easy_gantt.easy .button.active, div#easy_gantt.easy .form-actions .button.active {
+ margin: 3px 0;
+}
+
+@-webkit-keyframes sidebar-buttons-slide-left {
+ from {
+ -webkit-transform: translate(0, 0);
+ -moz-transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
+ transform: translate(0, 0);
+ }
+ to {
+ -webkit-transform: translate(-200px, 0);
+ -moz-transform: translate(-200px, 0);
+ -ms-transform: translate(-200px, 0);
+ -o-transform: translate(-200px, 0);
+ transform: translate(-200px, 0);
+ }
+}
+
+@-moz-keyframes sidebar-buttons-slide-left {
+ from {
+ -webkit-transform: translate(0, 0);
+ -moz-transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
+ transform: translate(0, 0);
+ }
+ to {
+ -webkit-transform: translate(-200px, 0);
+ -moz-transform: translate(-200px, 0);
+ -ms-transform: translate(-200px, 0);
+ -o-transform: translate(-200px, 0);
+ transform: translate(-200px, 0);
+ }
+}
+
+@-ms-keyframes sidebar-buttons-slide-left {
+ /* line 110, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+ from {
+ -webkit-transform: translate(0, 0);
+ -moz-transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
+ transform: translate(0, 0);
+ }
+ /* line 113, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+ to {
+ -webkit-transform: translate(-200px, 0);
+ -moz-transform: translate(-200px, 0);
+ -ms-transform: translate(-200px, 0);
+ -o-transform: translate(-200px, 0);
+ transform: translate(-200px, 0);
+ }
+}
+
+@keyframes sidebar-buttons-slide-left {
+ from {
+ -webkit-transform: translate(0, 0);
+ -moz-transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
+ transform: translate(0, 0);
+ }
+ to {
+ -webkit-transform: translate(-200px, 0);
+ -moz-transform: translate(-200px, 0);
+ -ms-transform: translate(-200px, 0);
+ -o-transform: translate(-200px, 0);
+ transform: translate(-200px, 0);
+ }
+}
+
+/* line 152, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+div#easy_gantt.easy .button.active {
+ line-height: 18px;
+ min-height: 18px;
+ background: #007aad;
+ border-color: #004461;
+ color: #ffffff;
+}
+
+/* line 126, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+div#easy_gantt.easy .button.active:hover {
+ color: #ffffff;
+ text-decoration: none;
+ background: #006894;
+}
+
+/* line 131, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+div#easy_gantt.easy .selected.button.active {
+ background: #006894;
+ color: rgba(255, 255, 255, 0.75);
+}
+
+/* line 135, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/buttons.scss */
+.ui-widget-content div#easy_gantt.easy .button.active, div#easy_gantt.easy .ui-widget-content .button.active {
+ color: #ffffff;
+}
+
+/* line 183, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/forms.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li a.submenu:after {
+ position: absolute;
+ right: 1px;
+ top: 1px;
+ bottom: 1px;
+ font-size: 1em;
+ line-height: 2.25;
+ margin: 0;
+ padding: 0;
+ display: block;
+ background: none;
+ border: none;
+ min-width: 20px;
+ text-align: center;
+}
+
+/* line 197, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/forms.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li a.submenu:after {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+}
+
+/* line 204, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/forms.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li a.submenu:after span {
+ display: none;
+}
+
+/* line 124, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/pseudo.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li > .menu-children:before {
+ left: -5px;
+ right: auto;
+ top: 6px;
+ border-top: 5px solid transparent;
+ border-bottom: 5px solid transparent;
+ border-right: 5px solid #dfccaf;
+ border-left: none;
+}
+
+/* line 130, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/pseudo.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li > .menu-children:after {
+ left: -4px;
+ right: auto;
+ top: 6px;
+ border-top: 5px solid transparent;
+ border-bottom: 5px solid transparent;
+ border-right: 5px solid #ffffff;
+ border-left: none;
+}
+
+/* line 32, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/tooltips.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li > .menu-children, .easy .easy-gantt__menu-group--tooltiped ul {
+ position: absolute;
+ background-color: #ffffff;
+ border: 1px solid #dfccaf;
+ color: #42321a;
+ padding: 0.5em;
+ font-size: 11.57px;
+ line-height: 1;
+ margin-top: -0.25em;
+ white-space: pre;
+}
+
+/* line 42, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/tooltips.scss */
+.easy .easy-gantt__menu-group--tooltiped ul a {
+ color: #42321a;
+ text-decoration: underline;
+}
+
+/* line 46, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/tooltips.scss */
+.input-append .easy .easy-gantt__menu-group--tooltiped ul li > .menu-children, .easy .easy-gantt__menu-group--tooltiped ul .input-append li > .menu-children, .input-append .easy .easy-gantt__menu-group--tooltiped ul, .easy .easy-gantt__menu-group--tooltiped .input-append ul {
+ font-weight: normal;
+ margin-top: 1px;
+}
+
+/* line 1, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li {
+ padding: 0;
+ padding-left: 30px;
+ border: 1px solid transparent;
+ border-left: none;
+ border-right: none;
+ position: relative;
+ line-height: 1.25;
+}
+
+/* line 10, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li:hover {
+ border-color: #fcf1f0 !important;
+ background: #fcf1f0 !important;
+ z-index: 1;
+}
+
+/* line 15, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li a {
+ padding: 5px 10px;
+ padding-left: 40px;
+ margin-left: -30px;
+ display: block;
+ text-decoration: none;
+}
+
+/* line 22, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li a.active {
+ color: #e50026;
+ background: none;
+ border: none;
+}
+
+/* line 26, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li a.active:before {
+ color: #e50026;
+}
+
+/* line 30, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li a:before {
+ position: absolute;
+ left: 0;
+ width: 30px;
+ text-align: center;
+ padding-top: 1px;
+ color: #42321a;
+}
+
+/* line 38, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li a.submenu {
+ padding-right: 0 !important;
+ background: none !important;
+ position: relative;
+}
+
+/* line 42, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li a.submenu:after {
+ content: "\005d" !important;
+ left: auto;
+ font-size: 10px;
+ text-align: left;
+ line-height: 1.9;
+}
+
+/* line 51, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li a ~ span {
+ font-size: 0.89em;
+}
+
+/* line 56, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul {
+ z-index: 1000;
+ margin: 0;
+ list-style: none;
+ font-size: 1.125em;
+ min-width: 200px;
+ padding: 5px 0;
+ white-space: normal !important;
+}
+
+/* line 66, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul:after {
+ content: '';
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: auto;
+ left: 30px;
+ border-left: 1px solid #eee3d4;
+ z-index: 0;
+}
+
+/* line 78, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li > .menu-children {
+ display: none;
+ white-space: normal;
+ top: 6px;
+ left: 99%;
+ width: 150px;
+}
+
+/* line 86, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li > .menu-children > li + li {
+ border-top: 1px dashed #eee3d4;
+}
+
+/* line 89, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li > .menu-children > li a {
+ text-decoration: none;
+ display: block;
+ padding: 0.5em;
+}
+
+/* line 93, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li > .menu-children > li a:hover {
+ text-decoration: underline;
+}
+
+/* line 96, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li > .menu-children > li a:before {
+ color: #4ebf67;
+ text-decoration: none;
+ margin-right: 5px;
+}
+
+/* line 105, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped ul li:hover > .menu-children {
+ display: inline-block;
+}
+
+/* line 111, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/menus.scss */
+.easy .easy-gantt__menu-group--tooltiped {
+ position: relative;
+}
+
+/* line 17, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/material/material__elevation.scss */
+.gantt_task_scale, .gantt_grid_scale {
+ -webkit-box-shadow: material__elevation--shadow_bottom(1), material__elevation--shadow_top(1);
+ -moz-box-shadow: material__elevation--shadow_bottom(1), material__elevation--shadow_top(1);
+ box-shadow: material__elevation--shadow_bottom(1), material__elevation--shadow_top(1);
+}
+
+/* line 20, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/material/material__elevation.scss */
+.easy-gantt__menu .gantt-menu-problems-list {
+ -webkit-box-shadow: material__elevation--shadow_bottom(2), material__elevation--shadow_top(2);
+ -moz-box-shadow: material__elevation--shadow_bottom(2), material__elevation--shadow_top(2);
+ box-shadow: material__elevation--shadow_bottom(2), material__elevation--shadow_top(2);
+}
+
+/* line 26, plugins/easyproject/easy_plugins/easy_extensions/assets/../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/mixins/material/material__elevation.scss */
+.easy .easy-gantt__menu-group--tooltiped ul {
+ -webkit-box-shadow: material__elevation--shadow_bottom(4), material__elevation--shadow_top(4);
+ -moz-box-shadow: material__elevation--shadow_bottom(4), material__elevation--shadow_top(4);
+ box-shadow: material__elevation--shadow_bottom(4), material__elevation--shadow_top(4);
+}
+
+/* line 10, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_icons.scss */
+.easy-gantt__icon:before {
+ font-family: "Material Icons", sans-serif;
+}
+
+/* line 14, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_icons.scss */
+.easy-gantt__icon--open:before {
+ content: "\e147";
+}
+
+/* line 14, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_icons.scss */
+.easy-gantt__icon--close:before {
+ content: "\e15c";
+}
+
+/* line 25, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_icons.scss */
+.gantt_tree_icon {
+ margin-right: 7px;
+}
+
+/* line 29, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_icons.scss */
+.gantt_tree_icon.gantt_folder_open {
+ background-image: none;
+}
+
+/* line 31, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_icons.scss */
+.gantt_tree_icon.gantt_folder_open:before {
+ content: url(data:image/gif;base64,R0lGODlhEgASAJECAJeXl7Gvrf///wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTdDRDM3QzVDMDZEMTFFMUJGMzhFMDhCN0RGRjBGQ0YiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTdDRDM3QzZDMDZEMTFFMUJGMzhFMDhCN0RGRjBGQ0YiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1N0NEMzdDM0MwNkQxMUUxQkYzOEUwOEI3REZGMEZDRiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1N0NEMzdDNEMwNkQxMUUxQkYzOEUwOEI3REZGMEZDRiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAIALAAAAAASABIAAAIzlI+pywcPm3mhWgkCsjBOvVkimElG9ZlCBlXd+2XjjLKg5GqoeZXqvsOQXK/ijUZTKVUFADs=);
+}
+
+/* line 29, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_icons.scss */
+.gantt_tree_icon.gantt_folder_close {
+ background-image: none;
+}
+
+/* line 31, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_icons.scss */
+.gantt_tree_icon.gantt_folder_close:before {
+ content: url(data:image/gif;base64,R0lGODlhEgASAJECAJeXl7Gvrf///wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTAyMTU1RTNDMDZEMTFFMUJGNzZCRThBRkFCRjg4MTIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTAyMTU1RTRDMDZEMTFFMUJGNzZCRThBRkFCRjg4MTIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1MDIxNTVFMUMwNkQxMUUxQkY3NkJFOEFGQUJGODgxMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1MDIxNTVFMkMwNkQxMUUxQkY3NkJFOEFGQUJGODgxMiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAIALAAAAAASABIAAAIwlI+pywcPm3mhWgkCsjBOvVkimElG9ZlCuYIY6TYs+6bmHDO4igfdD3GNhheV0VQAADs=);
+}
+
+/* line 38, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_icons.scss */
+.gantt_tree_icon.gantt_folder_open:before, .gantt_tree_icon.gantt_folder_close:before {
+ vertical-align: sub;
+}
+
+/* line 43, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_icons.scss */
+.gantt_tree_icon.gantt_open, .gantt_tree_icon.gantt_close {
+ margin-right: 0;
+ margin-left: 7px;
+}
+
+/* line 16, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .button-important {
+ color: #fff;
+}
+
+/* line 20, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .gantt-menu-button {
+ display: inline-block;
+ border-radius: 2px;
+ border: 1px solid #e4e4e4;
+ padding: 8px 16px;
+}
+
+/* line 27, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .gantt-menu-button.button-positive {
+ background-color: #4ebf67;
+ border-color: #338d47;
+ color: #ffffff;
+}
+
+/* line 33, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .gantt-menu-button.active, .redmine #easy_gantt.redmine .gantt_button.active {
+ background-color: #628DB6;
+ border-color: #3E5B76;
+}
+
+/* line 37, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .problem-finder {
+ border: none;
+ padding-right: 0;
+}
+
+/* line 42, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .gantt-menu-button.icon, .redmine .gantt_button.icon {
+ padding: 8px 10px 8px 25px;
+ background-position-x: 5px;
+}
+
+/* line 47, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .icon-calendar-week {
+ background-image: url("../../../../../images/magnifier.png");
+}
+
+/* line 47, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .icon-calendar-day {
+ background-image: url("../../../../../images/zoom_in.png");
+}
+
+/* line 47, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .icon-calendar-month {
+ background-image: url("../../../../../images/magnifier.png");
+}
+
+.redmine .icon-calendar-quarter {
+ background-image: url("../../../../../images/magnifier.png");
+}
+
+.redmine .icon-calendar-year {
+ background-image: url("../../../../../images/zoom_out.png");
+}
+
+/* line 47, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .icon-calendar {
+ background-image: url("../../../../../images/calendar.png");
+}
+
+/* line 47, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .icon-print {
+ background-image: url("../../../../../images/document.png");
+}
+
+/* line 47, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .icon-plugin {
+ background-image: url("../../../../../images/plugin.png");
+}
+
+/* line 47, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .icon-back {
+ background-image: url("../../../../../images/cancel.png");
+}
+
+/* line 47, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .icon-unlink {
+ background-image: url("../../../../../images/link_break.png");
+}
+
+/* line 47, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .icon-link {
+ background-image: url("../../../../../images/link.png");
+}
+
+/* line 47, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .icon-youtube {
+ background-image: url("../../../../../images/yt.png");
+}
+
+/* line 47, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .icon-settings {
+ background-image: url("../../../../../images/changeset.png");
+}
+
+/* line 47, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .icon-filter {
+ background-image: url("../../../../../images/task_parent_end.png");
+}
+
+/* line 51, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .icon-youtube {
+ padding-left: 28px;
+}
+
+/* line 54, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .icon.icon-filter {
+ background-position-x: 9px;
+ background-position-y: 7px;
+}
+
+/* line 58, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .easy-gantt__menu {
+ margin: 0 0 1px;
+ padding: 5px 0 5px 0;
+ background-color: white;
+}
+
+/* line 63, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine #gantt_cont {
+ /* width: auto !important; */
+ margin: 0;
+}
+
+/* line 67, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .gantt_tree_icon {
+ width: 20px;
+}
+
+/* line 69, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .gantt_tree_icon:before {
+ vertical-align: sub;
+}
+
+/* line 74, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine a.active {
+ color: #fff;
+}
+
+/* line 77, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine a.disabled {
+ opacity: 0.25;
+ color: #484848;
+ font-weight: lighter;
+}
+
+/* line 82, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine #link_delay_input {
+ width: auto;
+}
+
+/* line 85, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .push-left {
+ float: left;
+}
+
+/* line 89, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .push-right {
+ float: right;
+ text-align: right;
+}
+
+/* line 94, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .gantt-footer p {
+ text-align: center;
+}
+
+/* line 97, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine #button_close_all_projects {
+ width: 18px;
+ height: 25px;
+ padding: 0;
+ vertical-align: bottom;
+ background-position: 0 50%;
+ background-repeat: no-repeat;
+}
+
+/* line 106, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .overdue {
+ color: #e50026;
+}
+
+/* line 109, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .contextual {
+ text-align: right;
+}
+
+/* line 112, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .easy-gantt__menu-group--tooltiped {
+ position: relative;
+}
+
+/* line 114, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .easy-gantt__menu-group--tooltiped ul {
+ position: absolute;
+ right: 0;
+ background-color: white;
+ border: 1px solid #cccccc;
+ padding: 5px;
+ padding-left: 0;
+ min-width: 180px;
+ display: none;
+}
+
+/* line 123, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .easy-gantt__menu-group--tooltiped ul:after {
+ content: '';
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: auto;
+ left: 25px;
+ border-left: 1px solid #eee3d4;
+}
+
+/* line 132, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .easy-gantt__menu-group--tooltiped ul li {
+ display: block;
+}
+
+/* line 135, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .easy-gantt__menu-group--tooltiped ul .gantt-menu-button {
+ border: none;
+ padding: 5px 5px 5px 30px;
+ background-color: transparent;
+}
+
+/* line 141, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+.redmine .easy-gantt__menu-group--tooltiped:hover ul {
+ display: block;
+}
+
+@media print {
+ /* line 146, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+ .redmine .gantt_task_progress {
+ border-right: 1px solid #4ebf67;
+ box-sizing: border-box;
+ margin-top: 1px;
+ margin-bottom: 1px;
+ height: calc(100% - 2px);
+ }
+ /* line 153, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+ .redmine .wrong .gantt_task_progress {
+ border-color: #e50026;
+ }
+ /* line 156, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+ .redmine .gantt_project-type .gantt_task_progress {
+ border-color: #009ee0;
+ }
+ /* line 159, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss */
+ .redmine .odd {
+ background: none;
+ }
+}
+
+/* line 16, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss */
+.gantt-print__header-logo {
+ vertical-align: middle;
+ display: inline-block;
+}
+
+/* line 20, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss */
+.gantt-print__header-header {
+ display: inline-block;
+ margin: 0;
+}
+
+/* line 24, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss */
+.gantt-print__header-text {
+ display: inline-block;
+ vertical-align: bottom;
+ margin-left: 20px;
+}
+
+/* line 31, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss */
+.gantt-print__area {
+ background-color: white;
+}
+
+/* line 35, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss */
+.gantt-print__strip {
+ border: 1px solid #cecece;
+ overflow: hidden;
+ white-space: nowrap;
+ /*page-break-before:always;*/
+ /*page-break-inside: avoid;*/
+ break-inside: avoid;
+ margin: 10px 0;
+ margin-left: -1px;
+ display: inline-block;
+ background-color: #ffffff;
+ border-left: 0;
+}
+
+/* line 40, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss */
+.gantt-print__bg-canvas {
+ display: block;
+ /*page-break-before:avoid;*/
+}
+
+/* line 45, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss */
+.gantt-print__bg {
+ position: absolute;
+ /*page-break-before:avoid;*/
+}
+
+/* line 50, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss */
+.gantt-print__data-area {
+ /*page-break-before:avoid;*/
+}
+
+/* line 54, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss */
+.gantt-print__bars-area {
+ position: relative;
+ top: 0;
+}
+
+/* line 59, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss */
+.gantt-print__scale {
+ transform: none;
+ border-top: 0;
+}
+
+/* line 64, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss */
+.gantt-print__grid {
+ border: 1px solid #cecece;
+ overflow: hidden;
+ white-space: nowrap;
+ /*page-break-before:always;*/
+ /*page-break-inside: avoid;*/
+ break-inside: avoid;
+ margin: 10px 0;
+ margin-left: -1px;
+ display: inline-block;
+ background-color: #ffffff;
+ border-right: 2px solid #cecece;
+ margin-right: 1px;
+}
+
+/* line 68, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss */
+.gantt-print__grid .gantt_grid_scale {
+ margin-top: -2px;
+}
+
+/* line 71, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss */
+.gantt-print__grid .gantt-grid-header-collapse-buttons,
+.gantt-print__grid .gantt_sort {
+ display: none;
+}
+
+/* line 77, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss */
+.gantt-print__template--nowrap {
+ white-space: nowrap;
+}
+
+/* line 5, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div#easy_gantt.easy #easy_gantt_menu {
+ padding-bottom: 7px;
+}
+
+/* line 8, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div#easy_gantt.easy #easy_gantt_menu p {
+ margin-bottom: 0;
+}
+
+/* line 12, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div#easy_gantt.easy #gantt_footer_buttons {
+ float: left;
+ margin-top: 10px;
+}
+
+/* line 15, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div#easy_gantt.easy #gantt_footer_buttons + p {
+ float: right;
+ margin-top: 10px;
+}
+
+/* line 25, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+#button_jump_today {
+ padding-right: 0;
+}
+
+/* line 30, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.easy-gantt__menu {
+ user-select: none;
+ position: relative;
+ z-index: 1;
+ background-color: #fdfbf9;
+ padding: 20px;
+ margin: 0 -20px;
+}
+
+/* line 42, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.easy-gantt__menu:after {
+ display: none;
+}
+
+/* line 45, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.easy-gantt__menu-item {
+ display: inline-block;
+ text-align: left;
+}
+
+/* line 48, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.easy-gantt__menu-item .active {
+ color: #e50026 !important;
+}
+
+/* line 50, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.easy-gantt__menu-item .active:before {
+ color: #e50026;
+}
+
+/* line 55, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.easy-gantt__menu-group {
+ display: inline-block;
+}
+
+/* line 57, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.easy-gantt__menu-group ul {
+ margin: 0;
+}
+
+/* line 62, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.easy .easy-gantt__menu-group--tooltiped > ul {
+ display: none;
+ right: 0;
+}
+
+/* line 67, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.easy .easy-gantt__menu-group--tooltiped:hover > ul {
+ display: block;
+}
+
+/* line 73, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.easy .easy-gantt__menu .problem-finder {
+ font-size: 0.89em;
+ color: #42321a;
+}
+
+/* line 76, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.easy .easy-gantt__menu .problem-finder.active {
+ background: none;
+ border: none;
+ color: #42321a;
+}
+
+/* line 81, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.easy .easy-gantt__menu .problem-finder:hover {
+ text-decoration: none;
+}
+
+/* line 85, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.easy-gantt__menu .gantt-menu-problems-list {
+ border-width: 1px !important;
+}
+
+/* line 89, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.easy-gantt__menu .gantt-menu-problems-count.gantt-with-problems {
+ font-weight: bold;
+ background: #e50026;
+ border: 1px solid #cc0022;
+ text-align: center;
+ width: 15px;
+ line-height: 15px;
+ display: inline-block;
+ color: white;
+ padding: 2.5px;
+ margin-right: 10px;
+}
+
+/* line 106, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.gantt-menu-sub-panel {
+ width: 100%;
+}
+
+/* line 108, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.gantt-menu-sub-panel > span {
+ display: none !important;
+}
+
+/* line 113, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+#button_problem_finder.active {
+ color: #e50026 !important;
+ background: none !important;
+ border: none !important;
+}
+
+/* line 119, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.gantt-menu-problems-reason {
+ color: #e50026 !important;
+}
+
+/* line 123, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.gantt-grid-milestone-bullet {
+ margin-top: 4px !important;
+ margin-left: 5px;
+ background: #42321a !important;
+ border: none !important;
+}
+
+/* line 128, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.gantt-milestone-shared .gantt-grid-milestone-bullet {
+ background: #d94838 !important;
+}
+
+/* line 133, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.gantt_subtask_arrow:before {
+ content: '\21B3';
+ opacity: .75;
+}
+
+/* line 138, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.gantt_cell + .gantt_cell, .gantt_side_content {
+ color: #42321a !important;
+}
+
+/* line 142, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.gantt_grid .gantt_grid_head_cell, .gantt_grid_scale, #gantt_grid, .gantt_scale_cel, .gantt_task_scale {
+ border-color: #eee3d4 !important;
+}
+
+/* line 146, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.gantt_grid {
+ border-right-width: 1px !important;
+}
+
+/* line 154, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.gantt_grid_data .gantt_row:hover, .gantt_grid_data .gantt_row.odd:hover {
+ background: rgba(229, 0, 38, 0.25);
+}
+
+/* line 158, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.gantt_grid_data .gantt_row.closed {
+ background-color: rgba(223, 204, 175, 0.5);
+ border-color: #dfccaf;
+}
+
+/* line 161, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.gantt_grid_data .gantt_row.closed .gantt_tree_content {
+ text-decoration: line-through;
+}
+
+/* line 168, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.gantt_task_scale, .gantt_grid_scale {
+ z-index: 2 !important;
+ margin-top: -1px;
+}
+
+/* line 174, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+#gantt_cont {
+ width: auto !important;
+ margin: 0 -21px;
+ background: #ffffff;
+}
+
+/* line 182, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.easy .gantt_tree_indent {
+ width: 20px;
+}
+
+/* line 185, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.easy .gantt_tree_icon {
+ width: 20px;
+ text-align: center;
+}
+
+/* line 192, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_progress {
+ position: relative;
+ z-index: 1 !important;
+}
+
+/* line 199, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_line.gantt_parent_task-subtype .gantt_task_progress, div.gantt_task_line.gantt_parent_task-subtype .gantt_task_content {
+ height: 100%;
+}
+
+/* line 203, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_line .gantt_task_content {
+ border-radius: 2px;
+ border: 1px solid;
+ box-sizing: border-box;
+}
+
+/* line 208, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_line .gantt_task_content,
+div.gantt_task_line .gantt_task_ticks {
+ background-color: rgba(78, 191, 103, 0.1);
+ border-color: #4ebf67;
+}
+
+/* line 213, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_line .gantt_task_progress {
+ background-color: rgba(78, 191, 103, 0.5);
+}
+
+/* line 217, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_line.wrong .gantt_task_ticks,
+div.gantt_task_line.wrong .gantt_task_content {
+ background-color: rgba(229, 0, 38, 0.1);
+ border-color: #e50026;
+}
+
+/* line 222, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_line.wrong .gantt_task_progress {
+ background-color: rgba(229, 0, 38, 0.5);
+}
+
+/* line 227, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_line.closed .gantt_task_ticks,
+div.gantt_task_line.closed .gantt_task_content {
+ background-color: rgba(223, 204, 175, 0.25);
+ border-color: #dfccaf;
+}
+
+/* line 232, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_line.closed .gantt_task_progress {
+ background-color: rgba(223, 204, 175, 0.5);
+}
+
+/* line 237, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_line.gantt_project-type .gantt_task_content {
+ background-color: rgba(0, 158, 224, 0.25);
+ border-color: #009ee0;
+}
+
+/* line 241, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_line.gantt_project-type div.gantt_task_progress {
+ background-color: rgba(0, 158, 224, 0.5);
+}
+
+/* line 245, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_line.gantt_project-type.wrong .gantt_task_content {
+ background-color: rgba(172, 40, 85, 0.25);
+}
+
+/* line 248, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_line.gantt_project-type.wrong div.gantt_task_progress {
+ background-color: rgba(172, 40, 85, 0.5);
+}
+
+/* line 254, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_line.gantt_milestone-type .gantt_task_content {
+ -webkit-transform: scale(0.65) rotate(45deg);
+ -moz-transform: scale(0.65) rotate(45deg);
+ -ms-transform: scale(0.65) rotate(45deg);
+ -o-transform: scale(0.65) rotate(45deg);
+ transform: scale(0.65) rotate(45deg);
+ background-color: #42321a;
+ border-color: #42321a;
+}
+
+/* line 260, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_line.gantt_milestone-type.gantt-milestone-shared .gantt_task_content {
+ -webkit-transform: scale(0.65) rotate(45deg);
+ -moz-transform: scale(0.65) rotate(45deg);
+ -ms-transform: scale(0.65) rotate(45deg);
+ -o-transform: scale(0.65) rotate(45deg);
+ transform: scale(0.65) rotate(45deg);
+ background-color: #d94838;
+ border-color: #d94838;
+}
+
+/* line 268, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_line.critical .gantt_task_ticks,
+div.gantt_task_line.critical .gantt_task_content {
+ background-color: rgba(200, 0, 255, 0.5);
+ border-color: #c800ff;
+}
+
+/* line 273, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+div.gantt_task_line.critical .gantt_task_progress {
+ background-color: #c800ff;
+}
+
+/* line 279, plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss */
+.gantt_hor_scroll {
+ z-index: 1;
+}
+
+@font-face {
+ font-family: "Material Icons";
+ src: local("Material Icons"), local("MaterialIcons-Regular"), url(../../../fonts/EasyMaterialIcons-Regular.eot);
+ src: local("Material Icons"), local("MaterialIcons-Regular"), url(../../../fonts/EasyMaterialIcons-Regular.eot?#iefix) format("embedded-opentype"), url(../../../fonts/EasyMaterialIcons-Regular.woff) format("woff"), url(../../../fonts/EasyMaterialIcons-Regular.woff2) format("woff2"), url(../../../fonts/EasyMaterialIcons-Regular.ttf) format("truetype"), url(../../../fonts/EasyMaterialIcons-Regular.svg) format("svg");
+ font-weight: normal;
+ font-style: normal; }
diff --git a/plugins/easy_gantt/assets/stylesheets/easy_gantt/modal_editor.css b/plugins/easy_gantt/assets/stylesheets/easy_gantt/modal_editor.css
new file mode 100644
index 0000000..f063d1a
--- /dev/null
+++ b/plugins/easy_gantt/assets/stylesheets/easy_gantt/modal_editor.css
@@ -0,0 +1,63 @@
+/*
+ a missing css for issue modals
+*/
+
+#form-modal .tabs {height: 2.6em; margin-bottom:1.2em; position:relative; overflow:hidden;}
+#form-modal .tabs ul {margin:0; position:absolute; bottom:0; padding-left:0.5em; min-width: 2000px; width: 100%; border-bottom: 1px solid #bbbbbb;}
+#form-modal .tabs ul li {
+ float:left;
+ list-style-type:none;
+ white-space:nowrap;
+ margin-right:4px;
+ position:relative;
+ margin-bottom:-1px;
+}
+#form-modal .tabs ul li a{
+ display:block;
+ font-size: 0.9em;
+ text-decoration:none;
+ line-height:1.3em;
+ padding:4px 6px 4px 6px;
+ border: 1px solid #ccc;
+ border-bottom: 1px solid #bbbbbb;
+ color:#999;
+ font-weight:bold;
+ border-top-left-radius:3px;
+ border-top-right-radius:3px;
+}
+
+#form-modal .tabs ul li a:hover {
+ color:#777;
+ text-decoration:none;
+}
+
+#form-modal .tabs ul li a.selected {
+ background-color: #fff;
+ border: 1px solid #bbbbbb;
+ border-bottom: 1px solid #fff;
+ color:#444;
+}
+
+#form-modal .tabs ul li a.selected:hover {background-color: #fff;}
+
+#form-modal div.tabs-buttons { position:absolute; right: 0; width: 54px; height: 24px; background: white; bottom: 0; border-bottom: 1px solid #bbbbbb; }
+
+#form-modal .jstTabs.tabs {
+ margin-bottom: -1px;
+}
+#form-modal .jstTabs.tabs ul {border-bottom:0;}
+#form-modal .jstTabs.tabs li {
+ height: 42px;
+}
+#form-modal .jstTabs.tabs li:before{
+ content: '';
+ display: inline-block;
+ vertical-align: middle;
+ height: 100%;
+}
+#form-modal .jstTabs.tabs li a {
+ display: inline-block;
+ vertical-align: bottom;
+ line-height: 19px;
+border-bottom: 1px solid transparent;
+}
\ No newline at end of file
diff --git a/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_icons.scss b/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_icons.scss
new file mode 100644
index 0000000..79dc151
--- /dev/null
+++ b/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_icons.scss
@@ -0,0 +1,47 @@
+//@include loadFontFace('EasyIcons','easy_icons-webfont','fontLocal','fontLocalAlt',normal,normal);
+$gantt-icons: (
+ open: \e147,
+ close: \e15c,
+);
+
+.easy-gantt {
+ &__icon {
+ @include icon-parent;
+ &:before {
+ font-family: "Material Icons", sans-serif;
+ }
+ @each $icon, $sign in $gantt-icons {
+ &--#{$icon}:before {
+ content: unicode($sign);
+ }
+ }
+ }
+}
+
+$tree_icons: (
+ folder_open:url(data:image/gif;base64,R0lGODlhEgASAJECAJeXl7Gvrf///wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTdDRDM3QzVDMDZEMTFFMUJGMzhFMDhCN0RGRjBGQ0YiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTdDRDM3QzZDMDZEMTFFMUJGMzhFMDhCN0RGRjBGQ0YiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1N0NEMzdDM0MwNkQxMUUxQkYzOEUwOEI3REZGMEZDRiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1N0NEMzdDNEMwNkQxMUUxQkYzOEUwOEI3REZGMEZDRiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAIALAAAAAASABIAAAIzlI+pywcPm3mhWgkCsjBOvVkimElG9ZlCBlXd+2XjjLKg5GqoeZXqvsOQXK/ijUZTKVUFADs=),
+ folder_close:url(data:image/gif;base64,R0lGODlhEgASAJECAJeXl7Gvrf///wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTAyMTU1RTNDMDZEMTFFMUJGNzZCRThBRkFCRjg4MTIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTAyMTU1RTRDMDZEMTFFMUJGNzZCRThBRkFCRjg4MTIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1MDIxNTVFMUMwNkQxMUUxQkY3NkJFOEFGQUJGODgxMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1MDIxNTVFMkMwNkQxMUUxQkY3NkJFOEFGQUJGODgxMiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAEAAAIALAAAAAASABIAAAIwlI+pywcPm3mhWgkCsjBOvVkimElG9ZlCuYIY6TYs+6bmHDO4igfdD3GNhheV0VQAADs=)
+);
+.gantt_tree_icon{
+ margin-right: 7px;
+ //margin-right: 10px;
+ @each $type, $url in $tree_icons{
+ &.gantt_#{$type}{
+ background-image: none;
+ &:before{
+ content: $url;
+ }
+ }
+ }
+ &.gantt_folder{
+ &_open,&_close{
+ &:before{
+ vertical-align: sub;
+ }
+ }
+ }
+ &.gantt_open,&.gantt_close{
+ margin-right: 0;
+ margin-left: 7px;
+ }
+}
\ No newline at end of file
diff --git a/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss b/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss
new file mode 100644
index 0000000..ec43632
--- /dev/null
+++ b/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_main.scss
@@ -0,0 +1,281 @@
+div#easy_gantt.easy{
+ a{
+
+ }
+ #easy_gantt_menu{
+ //overflow: hidden;
+ padding-bottom: $gap - 3;
+ p{
+ margin-bottom: 0;
+ }
+ }
+ #gantt_footer_buttons{
+ float: left;
+ margin-top: $gap;
+ & + p{
+ float: right;
+ margin-top: $gap;
+ }
+ }
+ .button.active{
+ @extend %button-main !optional;
+ }
+}
+
+#button_jump_today{
+ padding-right: 0;
+}
+
+.easy-gantt{
+ &__menu{
+ @extend %box-sizing-border-box !optional;
+ //@extend %material__elevation--inline !optional;
+ @extend %flex !optional;
+ @extend %flex-wrap-wrap !optional;
+ @extend %justify-content-space-between !optional;
+ user-select: none;
+ position: relative;
+ z-index: 1;
+ background-color: $gantt-background-menu;
+ padding: $box-padding;
+ margin: 0 (-$box-padding);
+ &:after{
+ display: none;
+ }
+ &-item{
+ display: inline-block;
+ text-align: left;
+ .active{
+ color: $color-negative !important;
+ &:before{
+ color: $color-negative;
+ }
+ }
+ }
+ &-group{
+ display: inline-block;
+ ul{
+ margin: 0;
+ }
+ .easy &--tooltiped{
+ @extend %menu-tooltip !optional;
+ & > ul{
+ display: none;
+ right: 0;
+ }
+ &:hover{
+ & > ul{
+ display: block;
+ }
+ }
+ }
+ }
+ .easy & .problem-finder{
+ @include small;
+ color: $color-text;
+ &.active{
+ background: none;
+ border: none;
+ color: $color-text;
+ }
+ &:hover{
+ text-decoration: none;
+ }
+ }
+ .gantt-menu-problems-list{
+ @extend %material__elevation--depth_2 !optional;
+ border-width: 1px !important;
+ }
+ .gantt-menu-problems-count.gantt-with-problems{
+ @extend %border-radius-infinite !optional;
+ font-weight: bold;
+ background: $color-negative;
+ border: 1px solid darken($color-negative, 5%);
+ text-align: center;
+ width: 1.5*$gap;
+ line-height: 1.5*$gap;
+ display: inline-block;
+ color: white;
+ padding: .25*$gap;
+ margin-right: $gap;
+
+ }
+ }
+}
+
+.gantt-menu-sub-panel{
+ width: 100%;
+ & > span{
+ display: none !important;
+ }
+}
+
+#button_problem_finder.active{
+ color: $color-negative !important;
+ background: none !important;
+ border: none !important;
+}
+
+.gantt-menu-problems-reason{
+ color: $color-negative !important;
+}
+
+.gantt-grid-milestone-bullet{
+ margin-top: 4px !important;
+ margin-left: 5px;
+ background: $color-text !important;
+ border: none !important;
+ .gantt-milestone-shared &{
+ background: $color-important !important;
+ }
+}
+
+.gantt_subtask_arrow:before{
+ content: '\21B3';
+ opacity: .75;
+}
+
+.gantt_cell + .gantt_cell, .gantt_side_content{
+ color: $color-text !important;
+}
+
+.gantt_grid .gantt_grid_head_cell, .gantt_grid_scale, #gantt_grid, .gantt_scale_cel, .gantt_task_scale{
+ border-color: $color-border-minor !important;
+}
+
+.gantt_grid{
+ //@extend %material__elevation--depth_2 !optional;
+ border-right-width: 1px !important;
+}
+
+.gantt{
+ &_grid_data &_row{
+ &, &.odd{
+ &:hover{
+ background: rgba($color-negative, .25);
+ }
+ }
+ &.closed{
+ background-color: rgba($color-service-text, .5);
+ border-color: rgba($color-service-text, 1);
+ .gantt_tree_content{
+ text-decoration: line-through;
+ }
+ }
+ }
+}
+
+.gantt_task_scale, .gantt_grid_scale{
+ @extend %material__elevation--depth_1 !optional;
+ z-index: 2 !important;
+ margin-top: -1px;
+}
+
+#gantt_cont{
+ width: auto !important;
+ margin: 0 (-$box-padding - 1);
+ background: $color-foreground;
+}
+
+.easy{
+ & .gantt_tree{
+ &_indent{
+ width: $box-padding;
+ }
+ &_icon{
+ width: $box-padding;
+ text-align: center;
+ }
+ }
+}
+
+div.gantt_task_progress{
+ position: relative;
+ z-index: 1 !important;
+}
+
+div.gantt_task_line{
+ &.gantt_parent_task-subtype{
+ .gantt_task_progress, .gantt_task_content{
+ height: 100%;
+ }
+ }
+ .gantt_task_content{
+ border-radius: 2px;
+ border: 1px solid;
+ box-sizing: border-box;
+ }
+ .gantt_task_content,
+ .gantt_task_ticks{
+ background-color: rgba($color-positive, .1);
+ border-color: rgba($color-positive, 1);
+ }
+ .gantt_task_progress{
+ background-color: rgba($color-positive, .5);
+ }
+ &.wrong{
+ .gantt_task_ticks,
+ .gantt_task_content{
+ background-color: rgba($color-negative, .1);
+ border-color: rgba($color-negative, 1);
+ }
+ .gantt_task_progress{
+ background-color: rgba($color-negative, .5);
+ }
+ }
+ &.closed{
+ .gantt_task_ticks,
+ .gantt_task_content{
+ background-color: rgba($color-service-text, .25);
+ border-color: rgba($color-service-text, 1);
+ }
+ .gantt_task_progress{
+ background-color: rgba($color-service-text, .5);
+ }
+ }
+ &.gantt_project-type{
+ .gantt_task_content{
+ background-color: rgba($color-main, .25);
+ border-color: rgba($color-main, 1);
+ }
+ div.gantt_task_progress{
+ background-color: rgba($color-main, .5);
+ }
+ &.wrong{
+ .gantt_task_content{
+ background-color: rgba(mix($color-negative, $color-main, 75%), .25);
+ }
+ div.gantt_task_progress{
+ background-color: rgba(mix($color-negative, $color-main, 75%), .5);
+ }
+ }
+ }
+ &.gantt_milestone-type{
+ .gantt_task_content{
+ @include transform(#{scale(.65) rotate(45deg)});
+ background-color: rgba($color-text, 1);
+ border-color: rgba($color-text, 1);
+ }
+ &.gantt-milestone-shared{
+ .gantt_task_content{
+ @include transform(#{scale(.65) rotate(45deg)});
+ background-color: rgba($color-important, 1);
+ border-color: rgba($color-important, 1);
+ }
+ }
+ }
+ &.critical{
+ .gantt_task_ticks,
+ .gantt_task_content{
+ background-color: rgba($gantt-color-critical, .5);
+ border-color: rgba($gantt-color-critical, 1);
+ }
+ .gantt_task_progress{
+ background-color: rgba($gantt-color-critical, 1);
+ }
+ }
+}
+
+.gantt_hor_scroll{
+ z-index: 1;
+}
diff --git a/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss b/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss
new file mode 100644
index 0000000..04ce749
--- /dev/null
+++ b/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_print.scss
@@ -0,0 +1,81 @@
+@mixin print-strip{
+ border: 1px solid #cecece;
+ overflow: hidden;
+ white-space: nowrap;
+ /*page-break-before:always;*/
+ /*page-break-inside: avoid;*/
+ break-inside: avoid;
+ margin: 10px 0;
+ margin-left: -1px;
+ display: inline-block;
+ background-color: #ffffff;
+}
+
+.gantt-print{
+ &__header{
+ &-logo{
+ vertical-align: middle;
+ display: inline-block;
+ }
+ &-header{
+ display: inline-block;
+ margin: 0;
+ }
+ &-text{
+ display: inline-block;
+ vertical-align: bottom;
+ margin-left: 20px;
+ }
+ }
+
+ &__area{
+ background-color: white;
+ }
+
+ &__strip{
+ @include print-strip;
+ border-left: 0;
+ }
+
+ &__bg-canvas{
+ display: block;
+ /*page-break-before:avoid;*/
+ }
+
+ &__bg{
+ position: absolute;
+ /*page-break-before:avoid;*/
+ }
+
+ &__data-area{
+ /*page-break-before:avoid;*/
+ }
+
+ &__bars-area{
+ position: relative;
+ top: 0;
+ }
+
+ &__scale{
+ transform: none;
+ border-top: 0;
+ }
+
+ &__grid{
+ @include print-strip;
+ border-right: 2px solid #cecece;
+ margin-right: 1px;
+ .gantt_grid_scale{
+ margin-top: -2px;
+ }
+ .gantt-grid-header-collapse-buttons,
+ .gantt_sort{
+ display: none;
+ }
+ }
+
+ &__template--nowrap{
+ white-space: nowrap;
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss b/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss
new file mode 100644
index 0000000..1f88c44
--- /dev/null
+++ b/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_redmine.scss
@@ -0,0 +1,166 @@
+$redmine_icons: (
+ calendar-week:magnifier,
+ calendar-day:zoom_in,
+ calendar-month:magnifier,
+ calendar-quarter:magnifier,
+ calendar-year:zoom_out,
+ calendar:calendar,
+ print:document,
+ plugin:plugin,
+ back:cancel,
+ unlink:link_break,
+ link:link,
+ youtube:yt,
+ settings:changeset,
+ filter:task_parent_end
+);
+.redmine{
+ .button-important{
+ color: #fff;
+ }
+
+ .gantt-menu-button{
+ display: inline-block;
+ border-radius: 2px;
+ border: 1px solid #e4e4e4;
+ padding: 8px 16px;
+ }
+
+ .gantt-menu-button.button-positive{
+ background-color: #4ebf67;
+ border-color: rgb(51, 141, 71);
+ color: #ffffff;
+ }
+
+ .gantt-menu-button.active, #easy_gantt.redmine .gantt_button.active{
+ background-color: #628DB6;
+ border-color: #3E5B76;
+ }
+ .problem-finder{
+ border: none;
+ padding-right: 0;
+ }
+
+ .gantt-menu-button.icon, .gantt_button.icon{
+ padding: 8px 10px 8px 25px;
+ background-position-x: 5px;
+ }
+ @each $icon, $image in $redmine_icons{
+ .icon-#{$icon}{
+ background-image: url('../../../../../images/#{$image}.png');
+ }
+ }
+ .icon-youtube{
+ padding-left: 28px;
+ }
+ .icon.icon-filter{
+ background-position-x: 9px;
+ background-position-y: 7px;
+ }
+ .easy-gantt__menu{
+ margin: 0 0 1px;
+ padding: 5px 0 5px 0;
+ background-color: white;
+ }
+ #gantt_cont{
+ /* width: auto !important; */
+ margin: 0;
+ }
+ .gantt_tree_icon{
+ width: 20px;
+ &:before{
+ vertical-align: sub;
+ }
+ }
+
+ a.active{
+ color: #fff;
+ }
+ a.disabled{
+ opacity: 0.25;
+ color: #484848;
+ font-weight: lighter;
+ }
+ #link_delay_input{
+ width: auto;
+ }
+ .push-left{
+ float: left;
+ }
+
+ .push-right{
+ float: right;
+ text-align: right
+ }
+
+ .gantt-footer p{
+ text-align: center;
+ }
+ #button_close_all_projects{
+ width: 18px;
+ height: 25px;
+ padding: 0;
+ vertical-align: bottom;
+ background-position: 0 50%;
+ background-repeat: no-repeat;
+ }
+
+ .overdue{
+ color: #e50026;
+ }
+ .contextual{
+ text-align: right;
+ }
+ .easy-gantt__menu-group--tooltiped{
+ position: relative;
+ ul{
+ position: absolute;
+ right: 0;
+ background-color: white;
+ border: 1px solid #cccccc;
+ padding: 5px;
+ padding-left: 0;
+ min-width: 180px;
+ display: none;
+ &:after{
+ content: '';
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: auto;
+ left: 25px;
+ border-left: 1px solid #eee3d4;
+ }
+ li{
+ display: block;
+ }
+ .gantt-menu-button{
+ border: none;
+ padding: 5px 5px 5px 30px;
+ background-color: transparent;
+ }
+ }
+ &:hover ul{
+ display: block;
+ }
+ }
+ @media print {
+ .gantt_task_progress{
+ border-right: 1px solid #4ebf67;
+ box-sizing: border-box;
+ margin-top: 1px;
+ margin-bottom: 1px;
+ height: calc(100% - 2px);
+ }
+ .wrong .gantt_task_progress{
+ border-color: #e50026;;
+ }
+ .gantt_project-type .gantt_task_progress{
+ border-color: #009ee0;
+ }
+ .odd{
+ background: none;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_variables.scss b/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_variables.scss
new file mode 100644
index 0000000..62c8ed2
--- /dev/null
+++ b/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/_gantt_variables.scss
@@ -0,0 +1,3 @@
+$gantt-background-menu: white !default;
+$gantt-color-critical: #c800ff !default;
+$gap: 5px !default;
\ No newline at end of file
diff --git a/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/easy_gantt_sass.scss.erb b/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/easy_gantt_sass.scss.erb
new file mode 100644
index 0000000..fe22462
--- /dev/null
+++ b/plugins/easy_gantt/assets/stylesheets/easy_gantt/sass/easy_gantt_sass.scss.erb
@@ -0,0 +1,17 @@
+<% if Redmine::Plugin.installed?(:easy_project_com) %>
+@import "../../../../easyproject/easy_plugins/easy_project_com/assets/stylesheets/scss/common_assets";
+<% else %>
+@import "../../../../easyproject/easy_plugins/easy_extensions/assets/stylesheets/scss/common_assets";
+<% end %>
+
+@import "gantt_variables";
+@import "gantt_icons";
+@import "gantt_redmine";
+@import "gantt_print";
+@import "gantt_main";
+
+<% if Redmine::Plugin.installed?(:easy_project_com) %>
+@include loadFontFace('Material Icons', '../../plugin_assets/easy_gantt/fonts/EasyMaterialIcons-Regular', 'Material Icons', 'MaterialIcons-Regular', normal, normal);
+<% else %>
+@include loadFontFace--non-rails('Material Icons', '../../plugin_assets/easy_gantt/fonts/EasyMaterialIcons-Regular', 'Material Icons', 'MaterialIcons-Regular', normal, normal);
+<% end %>
\ No newline at end of file
diff --git a/plugins/easy_gantt/config/locales/ar.yml b/plugins/easy_gantt/config/locales/ar.yml
new file mode 100644
index 0000000..b93c21a
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/ar.yml
@@ -0,0 +1,2 @@
+---
+ar:
diff --git a/plugins/easy_gantt/config/locales/cs.yml b/plugins/easy_gantt/config/locales/cs.yml
new file mode 100644
index 0000000..2acd316
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/cs.yml
@@ -0,0 +1,183 @@
+---
+cs:
+ button_print: Tisk
+ button_project_menu_easy_gantt: Easy Gantt
+ button_top_menu_easy_gantt: Globální Gantt
+ button_use_actual_delay: Použít skutečné zpoždění
+ easy_gantt_toolbar:
+ day: Dny
+ month: Měsíce
+ week: Týdny
+ easy_gantt:
+ button:
+ close_all: Zavřít vše
+ close_all_parent_issues: Zavřít všechny rodičovské úkoly
+ create_baseline: Baseline
+ critical_path: Kritická cesta
+ day_zoom: Dny
+ delayed_project_filter: Filtrovat zpožděné projekty
+ jump_today: Přejít na dnešek
+ load_sample_data: Nahrát zkušební data
+ month_zoom: Měsíce
+ moth_zoom: Měsíce
+ print_fit: Přizpůsobit stránce
+ problem_finder: Problémy
+ reload: Znovu načíst (uložit)
+ remove_delay: Odstranit zpoždění
+ resource_management: Vytížení zdrojů
+ tool_panel: Nástroje
+ week_zoom: Týdny
+ critical_path:
+ disabled: Vypnuto
+ last: Poslední
+ last_text: Úkoly, které by se neměly odkládat
+ longest: Nejdelší
+ longest_text: Zobrazit nejdelší sled úkolů
+ errors:
+ duplicate_link: Není možné vytvořit zdvojenou vazbu
+ fresh_milestone: Není možné přidat úkol na neuložený milník. Nejprve uložte
+ mílník.
+ link_target_new: Nelze vytvořit vazbu na neuložený úkol. Nejprve uložte změny.
+ link_target_readonly: Cílový úkol pouze pro čtení
+ loop_link: Není možné vytvořit cyklickou vazbu
+ no_rest_api: Easy Gantt potřebuje mít zapnuté REST API. Zapněte ho v Administraci
+ -> Nastavení -> API -> Zapnout službu REST
+ overdue: má skončit v budoucnu, nebo být již uzavřen
+ progress_date_overdue: se opožduje za plánem o %{days} dní
+ overmile: musí končit %{effective_date}, aby dodržel milník
+ short_delay: mělo by být delší o %{diff} dnů
+ too_short: není dost dlouhý pro zbývajících %{rest} hodin odhadovaného času
+ unsaved_parent: Nelze přidat úkol k neuloženému rodiči. Nejprve uložte změny.
+ unsupported_link_type: Nepodporovaný typ vazby
+ gateway:
+ entity_save_failed: "%{entityType} %{entityName} se nepodařilo uložit kvůli
+ chybě"
+ send_failed: 'Následující požadavky se nepodařilo odeslat:'
+ label_pro_upgrade: Upgradovat na PRO verzi
+ link_dir:
+ link_end: jako předchůdce
+ link_start: jako následovník
+ popup:
+ add_task:
+ heading: Přidat úkol
+ text: "Tato funkce je dostupná pouze v Easy Gantt PRO \r\n
Upgradovat
+ na PRO verzi "
+ baseline:
+ heading: Baseline
+ text: "Tato funkce je dostupná pouze v Easy Gantt PRO \r\n
Upgradovat
+ na PRO verzi "
+ critical:
+ heading: Kritická cesta
+ text: "Tato funkce je dostupná pouze v Easy Gantt PRO \r\n
Upgradovat
+ na PRO verzi "
+ resource:
+ heading: Vytížení zdrojů
+ text: Vytížení zdrojů je dostupné v
+ Easy Project
+ reload_modal:
+ label_errors: Chyby
+ text_reload_appeal: Chcete ignorovat neuložené položky a znovu načíst data ze
+ serveru?
+ title: Gantt se nepodařilo správně uložit
+ sample_global_free:
+ text: Zkušební data nelze uzavřít. Gantt nad všemi projekty je k dispozici pouze
+ ve verzi PRO.
+ video:
+ text: Zde si můžete prohlédnout většinu funkcí Ganttu nad všemi projekty
+ title: Ukázkové video Ganttu nad všemi projekty
+ video_id: EiiqBrrY4m4
+ sample_video:
+ text: Zde můžete vidět většinu funkcí modulu Easy Gantt
+ title: Ukázkové video
+ sample:
+ active_label: Jsou načtena testovací data!
+ close_label: Zavřít toto okno a načíst skutečná data
+ header: Jsou načtena zkušební data!
+ text: Připravili jsme zkušební data, abyste
vyzkoušeli všechny funkce
+ Easy Ganttu bez obav . Koukněte se také na video průvodce ukazujícího
+ užitečné triky. Zavřením tohoto okna načtete skutečná data.
+ video_id: UHgqfsrD59Q
+ video_label: Spustit video návod
+ video:
+ text: Zde můžete vidět většinu funkcí modulu Easy Gantt
+ title: Spustit video návod
+ video_id: UHgqfsrD59Q
+ text_blocker_milestone: Milník blokuje posunutí úkolu za toto datum
+ text_blocker_move_pre: Úkol obsahuje vazbu, která blokuje posunutí úkolu za toto
+ datum
+ title:
+ button_test: Testovací tlačítko (pouze pro testování)
+ day_zoom: Dny
+ jump_today: Přejít na dnešek
+ month_zoom: Měsíce
+ week_zoom: Týdny
+ easy_query:
+ name:
+ easy_gantt_easy_issue_query: Easy Gantt
+ easy_gantt_easy_project_query: Globální Easy Gantt
+ error_easy_gantt_view_permission: Nemáte právo vidět Easy Gantt
+ error_epm_easy_gantt_already_active: Easy gantt je na této stránce již aktivní
+ errors:
+ duplicate_link: Cannot create duplicate link
+ fresh_milestone: Cannot add task to non-saved milestone. Save the milestone first.
+ loop_link: Cannot create looped link
+ overmile: Task should end before its milestone
+ too_short: Task is too short for its estimated hours count
+ field_easy_gantt_default_zoom: Výchozí přiblížení
+ field_easy_gantt_show_holidays: Zobrazit svátky
+ field_easy_gantt_show_project_progress: Zobrazit pokrok na projektu
+ field_easy_gantt_show_task_soonest_start: Zobrazit nejdřívější začátek
+ field_keep_link_delay_in_drag: Zachovat zpoždění vazby během přesunu
+ field_relation: Vazba
+ gantt_grid_head_subject: Předmět
+ heading_delay_popup: Nastavte zpoždění úkolu ve dnech
+ heading_demo_feature_popup: Již brzy...
+ heading_easy_gantts_issues: Easy Gantt Free
+ label_easy_gantt: Easy Gantt
+ label_easy_gantt_critical_path: Kritická cesta
+ label_easy_gantt_settings: Nastavení Ganttu
+ label_filter_group_easy_gantt_easy_issue_query: Úkolová pole
+ label_finish_to_finish: Konec na konec
+ label_parent_issue_plural: Rodičovské úkoly
+ label_pro_upgrade: Upgrade to PRO version
+ label_start_to_finish: Začátek na konec
+ label_start_to_start: Začátek na začátek
+ link_easy_gantt_plugin: https://www.easyredmine.com/easy-gantt-upgrade-to-pro
+ permission_edit_easy_gantt: Upravit Easy Gantt & Vytížení zdrojů na projektu
+ permission_edit_global_easy_gantt: Upravit globální Easy Gantt & Vytížení zdrojů
+ permission_edit_personal_easy_gantt: Upravit osobní Easy Gantt & Vytížení zdrojů
+ permission_view_easy_gantt: Zobrazit Easy Gantt & Vytížení zdrojů na projektu
+ permission_view_global_easy_gantt: Zobrazit globální Easy Gantt & Vytížení zdrojů
+ permission_view_personal_easy_gantt: Zobrazit osobní Easy Gantt & Vytížení zdrojů
+ project_default_page:
+ easy_gantt: Easy Gantt
+ project_module_easy_gantt: Easy Gantt
+ sample_global_free:
+ text: Sample data cannot be closed. Gantt over all projects is available only
+ in PRO version
+ video:
+ text: Here you can see most of features of Gantt over all projects
+ title: Sample video of Gantt over all projects
+ video_id: UHgqfsrD59Q
+ sample:
+ close_label: Close this window and load real project data
+ header: Sample data are loaded!
+ text: We have prepared some sample data for you to
try all Gantt features
+ with no stress . We also want to encourage you to watch a video guide
+ showing useful tweaks. Closing this window will load real project data.
+ video_label: Watch video tutorial
+ video:
+ text: Here you can see most of features of this Gantt module
+ title: Sample video
+ video_id: UHgqfsrD59Q
+ text_demo_feature_popup: Tato funkce bude brzy dostupná.
+ text_easy_gantt_footer: Redmine Gantt powered by Easy
+ text_easy_gantt_keep_link_delay_in_drag: Zachovat zpoždění vazby, když je úkol přetažen
+ zpět
+ text_easy_gantt_show_holidays: Zobrazit aktuální dovolenou uživatelů v Ganttu (funguje
+ pouze v Easy Redmine)
+ text_easy_gantt_show_project_progress: Zobrazit procentuální dokončení na liště
+ projektu (načítání může být pomalé)
+ text_easy_gantt_show_task_soonest_start: Ukázat nejnižší platná data pro úkoly definovaná
+ vazbami nebo rodičem
+ title_easy_gantt_settings: Easy Gantt
diff --git a/plugins/easy_gantt/config/locales/da.yml b/plugins/easy_gantt/config/locales/da.yml
new file mode 100644
index 0000000..d3dcd59
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/da.yml
@@ -0,0 +1,2 @@
+---
+da:
diff --git a/plugins/easy_gantt/config/locales/de.yml b/plugins/easy_gantt/config/locales/de.yml
new file mode 100644
index 0000000..8a0e45a
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/de.yml
@@ -0,0 +1,194 @@
+---
+de:
+ button_print: Drucken
+ button_project_menu_easy_gantt: Easy Gantt
+ button_top_menu_easy_gantt: Projekte Gantt
+ button_use_actual_delay: Aktuelle Verzögerung übernehmen
+ easy_gantt_toolbar:
+ day: Days
+ month: Months
+ week: Weeks
+ easy_gantt:
+ buton_create_baseline: Baselines
+ button_critical_path: Critical path
+ button_resource_management: Ressourcenmanagement
+ button:
+ close_all: Alle schließen
+ close_all_parent_issues: Alle übergeordneten Aufgaben schliessen
+ create_baseline: Basispläne
+ critical_path: Kritischer Weg
+ day_zoom: Tage
+ delayed_project_filter: Verspätete Projekte filtern
+ jump_today: Zum heutigen Tag überspringen
+ load_sample_data: Beispieldaten laden
+ month_zoom: Monate
+ print_fit: Der Seite anpassen
+ problem_finder: Probleme
+ reload: Neu laden (speichern)
+ remove_delay: Die Verzögerung entfernen
+ resource_management: Ressourcenmanagement
+ tool_panel: Werkzeuge
+ week_zoom: Wochen
+ critical_path:
+ disabled: Deaktiviert
+ last: Letzte
+ last_text: Die Aufgaben, die ohne Verspätung erfüllt werden sollen
+ longest: Längste
+ longest_text: Die längste Sequenz anzeigen
+ error_overmile: Task should end before its milestone
+ error_too_short: Task is too short for its estimated hours count
+ errors:
+ duplicate_link: Das Duplikat des Links kann nicht erstellt werden
+ fresh_milestone: "Die Aufgabe kann nicht zu dem nicht gespeicherten Meilenstein
+ hinzugefügt werden.\r\nBitte speichern Sie erst den Meilenstein."
+ link_target_new: Ein Link zur nicht abgespeicherte Aufgabe kann nicht erstellt
+ werden. Bitte die Veränderungen erst speichern.
+ link_target_readonly: Nur-lese-Modus die Zielaufgabe
+ loop_link: Der geloopter Link kann nicht erstellt werden.
+ no_rest_api: Easy Gantt braucht REST API aktiviert. Bitte aktivieren Sie es
+ in der Administration -> Einstellungen-> API -> Aktivieren REST Web Service
+ overdue: Soll in der Zukunft enden oder soll bereits geschlossen werden
+ overmile: Soll am %{effective_date} enden, um den Meilenstein einzuhalten
+ short_delay: Soll länger sein als %{diff} Tage
+ too_short: enthält nicht genug Tage für %{rest} Stunden der abgeschätzten Zeit.
+ unsaved_parent: "Die Aufgabe kann nicht zur nicht gespeicherten übergeordneten
+ Aufgabe hinzugefügt werden.\r\nBitte erst die Änderungen speichern."
+ unsupported_link_type: Der Link Typ wird nicht unterstützt
+ gateway:
+ entity_save_failed: "%{entityType} %{entityName} kann nicht gespeichert werden.
+ Ein Fehler ist aufgetreten."
+ send_failed: Die Anfrage ist fehlgeschlagen
+ label_pro_upgrade: Auf die Pro Version upgraden
+ link_dir:
+ link_end: wie vorangegangen
+ link_start: als nächstes
+ popup:
+ add_task:
+ heading: Eine Funktion der Aufgabe hinzufügen
+ text: "Neue Funktion für eine/einen Aufgabe/Meilenstein ist ausschließlich
+ verfügbar für Easy Gantt PRO Mitglieder\r\n
Check
+ for update! "
+ baseline:
+ heading: Funktion für Basispläne
+ text: "Funktionen für Basisplan ist ausschließlich verfügbar für Easy Gantt
+ PRO Mitglieder\r\n
Check
+ for update! "
+ critical:
+ heading: Funktion für den kritischen Weg
+ text: "Funktion für den kritischen Weg ist ausschließlich verfügbar für Easy
+ Gantt PRO Mitglieder\r\n
Check
+ for update! "
+ resource:
+ heading: Ressourcenmanager Funktion
+ text: Ressourcenmanagement Funktion steht Ihnen hier zur Verfügung
+ Easy Redmine
+ reload_modal:
+ label_errors: Fehler
+ text_reload_appeal: Möchten Sie nicht gespeicherte Elemente ignorieren und die
+ Daten vom Server neuladen?
+ title: Gantt wurde nicht ordnungsgemäß gespeichert
+ sample_global_free:
+ text: Beispieldaten können nicht geschlossen werden. Gantt über alle Projekte
+ ist nur in der PRO Version verfügrbar
+ video:
+ text: Hier bekommen Sie ein Übersicht über die meisten Funktionen des Gantt
+ über alle Projekte
+ title: Beispielvideo für Gantt über alle Projekte
+ video_id: EiiqBrrY4m4
+ sample:
+ close_label: Das Fenster schließen und die echten Projektdaten laden
+ header: Beispieldaten sind hochgeladen
+ text: "Wir haben einige Beispieldaten für Sie vorbereitet, um alle Easy Gantt
+ Funktionen ohne Stress testen zu können. Wir möchten Sie auch ermutigen, sich
+ die Video-Anleitung über Optimierungsmethoden anzuschauen.\r\nSchließen Sie
+ dieses Fenster, um das Laden der echten Projektdaten auszulösen."
+ video_label: Die Video-Anleitung anschauen
+ video:
+ text: Hier können Sie die meisten der Funktionen für dieses Gantt Modul sehen
+ title: Beispielvideo
+ video_id: UHgqfsrD59Q
+ soon:
+ add_task:
+ heading: Add Issue feature
+ text: This feature is comming soon.
Check
+ the availability here!
+ baseline:
+ heading: Baselines feature
+ text: Baselines feature is comming soon.
Check
+ the availability here! "
+ resource:
+ heading: Resource manager feature
+ text: Resource Management feature is available just in
+ Easy Redmine
+ text_blocker_milestone: Der Meilenstein blockiert das Verschieben der Aufgabe
+ außerhalb des Datums
+ text_blocker_move_pre: Die Aufgabe hat eine Beziehung, die das Verschieben der
+ Aufgabe außerhalb des Datums verhindert.
+ title:
+ button_test: Test Taste (nur zum Testen)
+ day_zoom: In den täglichen Zeitplan zoomen
+ jump_today: springe zum heutigen Tag
+ month_zoom: In den monatlichen Zeitplan zoomen
+ print_fit: Skalieren Sie das Gantt auf eine Seite
+ week_zoom: In den wöchentlichen Zeitplan zoomen
+ easy_printable_templates_categories:
+ easy_gantt: Easy Gantt
+ easy_query:
+ name:
+ easy_gantt_easy_issue_query: Easy Gantt
+ easy_gantt_easy_project_query: Globales Easy Gantt
+ error_easy_gantt_view_permission: Sie haben nicht die Berechtigung, Easy Gantt zu
+ sehen
+ error_epm_easy_gantt_already_active: Easy Gantt ist auf der Seite bereits aktiv
+ field_easy_gantt_default_zoom: Standard Zoom
+ field_easy_gantt_relation_delay_in_workdays: Relationsverzögerungen in Arbeitstagen
+ field_easy_gantt_show_holidays: Feiertage anzeigen
+ field_easy_gantt_show_project_progress: Den Projektfortschritt anzeigen
+ field_easy_gantt_show_task_soonest_start: Den frühestmöglichen Starttermin anzeigen
+ field_keep_link_delay_in_drag: Konstante Link-Verzögerung beim Ziehen (Drag)
+ field_relation: Beziehung
+ heading_delay_popup: Definition der Verzögerung in Tagen
+ heading_demo_feature_popup: Coming soon
+ heading_easy_gantts_issues: Aufgaben Gantt
+ label_easy_gantt: Easy Gantt
+ label_easy_gantt_critical_path: Kritischer Weg
+ label_easy_gantt_settings: Gantt Einstellungen
+ label_filter_group_easy_gantt_easy_issue_query: Aufgabenfelder
+ label_finish_to_finish: Ende zu Ende
+ label_parent_issue_plural: Probleme der übergeordneten Aufgaben
+ label_start_to_finish: Start zu Ende
+ label_start_to_start: Start zu Start
+ link_easy_gantt_footer: https://www.easyredmine.com/redmine-gantt-plugin
+ link_easy_gantt_plugin: https://www.easyredmine.com/easy-gantt-upgrade-to-pro
+ permission_edit_easy_gantt: Easy Gantt & Ressourcenmanagement in dem Projekt bearbeiten
+ permission_edit_global_easy_gantt: Easy Gantt & Ressourcenmanagement in dem Prokjekt
+ global bearbeiten
+ permission_edit_personal_easy_gantt: Persönliche Easy Gantt & Resource management
+ bearbeiten
+ permission_view_easy_gantt: Easy Gantt & Resourcenmanagement in dem Prokjekt sehen
+ permission_view_global_easy_gantt: Easy Gantt & Ressourcenmanagement in dem Prokjekt
+ global sehen
+ permission_view_personal_easy_gantt: Persönliche Easy Gantt & Ressourcenmanagement
+ sehen
+ project_default_page:
+ easy_gantt: Easy Gantt
+ project_module_easy_gantt: Easy Gantt
+ text_demo_feature_popup: This feature will be available soon.
+ text_easy_gantt_footer: Redmine Gantt powered by Easy
+ text_easy_gantt_keep_link_delay_in_drag: Die Verzögerung der Beziehung konstant
+ beibehalten während die Aufgabe nach hinten gezogen wird
+ text_easy_gantt_print_easy_gantt_current: Aktuelles Easy Gantt anzeigen (funktioniert
+ nur von einer Seite, wo Easy Gantt geladen wird)
+ text_easy_gantt_relation_delay_in_workdays: Rechnen Sie nicht Nichtarbeitstage in
+ der Relationsverzögerung mit.
+ text_easy_gantt_show_holidays: Die aktuellen Feiertage des Benutzers im Gantt- Diagram
+ anzeigen (Die Funktion ist nur in Easy Redmine verfügbar)
+ text_easy_gantt_show_project_progress: Den Fortschritt in Prozent auf dem Balken
+ des Projekts anzeigen (kann die Ladezeit beeinträchtigen)
+ text_easy_gantt_show_task_soonest_start: Die kleinsten zulässigen Daten, die durch
+ Beziehungen oder übergeordnete Aufgaben definiert sind, für die Aufgabe anzeigen
+ title_easy_gantt_settings: Easy Gantt
diff --git a/plugins/easy_gantt/config/locales/en-AU.yml b/plugins/easy_gantt/config/locales/en-AU.yml
new file mode 100644
index 0000000..56b80b3
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/en-AU.yml
@@ -0,0 +1,2 @@
+---
+en-AU:
diff --git a/plugins/easy_gantt/config/locales/en-GB.yml b/plugins/easy_gantt/config/locales/en-GB.yml
new file mode 100644
index 0000000..a32c228
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/en-GB.yml
@@ -0,0 +1,2 @@
+---
+en-GB:
diff --git a/plugins/easy_gantt/config/locales/en-US.yml b/plugins/easy_gantt/config/locales/en-US.yml
new file mode 100644
index 0000000..54b3be8
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/en-US.yml
@@ -0,0 +1,2 @@
+---
+en-US:
diff --git a/plugins/easy_gantt/config/locales/en.yml b/plugins/easy_gantt/config/locales/en.yml
new file mode 100644
index 0000000..b1f1115
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/en.yml
@@ -0,0 +1,162 @@
+---
+en:
+ button_print: Print
+ button_project_menu_easy_gantt: Easy Gantt
+ button_top_menu_easy_gantt: Projects Gantt
+ button_use_actual_delay: Use actual delay
+ easy_gantt:
+ button:
+ close_all: Close all
+ close_all_parent_issues: Close all parent tasks
+ create_baseline: Baselines
+ critical_path: Critical path
+ day_zoom: Days
+ delayed_project_filter: Filter Delayed Projects
+ jump_today: Jump to today
+ load_sample_data: Load sample data
+ month_zoom: Months
+ print_fit: Fit to page
+ problem_finder: Problems
+ quarter_zoom: Quarters
+ reload: Reload (save)
+ remove_delay: Remove delay
+ resource_management: Resource management
+ tool_panel: Tools
+ week_zoom: Weeks
+ year_zoom: Years
+ critical_path:
+ disabled: Disabled
+ last: Last
+ last_text: Tasks which should not be delayed
+ longest: Longest
+ longest_text: Show longest sequence of tasks
+ errors:
+ duplicate_link: Cannot create duplicate link
+ fresh_milestone: Cannot add task to non-saved milestone. Save the milestone
+ first.
+ link_target_new: Cannot create link to unsaved task. Save the changes first.
+ link_target_readonly: Read-only target task
+ loop_link: Cannot create looped link
+ no_rest_api: Easy Gantt needs REST API enabled. Turn it on in Administration
+ -> Settings -> API -> Enable REST web service
+ overdue: should end in future or should be closed already
+ progress_date_overdue: is behind schedule by %{days} days
+ overmile: should end on %{effective_date} in order to keep milestone
+ short_delay: should be longer by %{diff} days
+ too_short: does not contain enough days for %{rest} hours of estimated time
+ unsaved_parent: Cannot add task to non-saved parent. Save the changes first.
+ unsupported_link_type: Unsupported link type
+ change_link_length: The delay between {{source_task}} and {{target_task}} has been changed to a minimum length of {{minimum_link_length}}
+ gateway:
+ entity_save_failed: "%{entityType} %{entityName} failed to save due to error"
+ send_failed: Request failed
+ label_pro_upgrade: Upgrade to PRO version
+ link_dir:
+ link_end: as preceding
+ link_start: as following
+ popup:
+ add_task:
+ heading: Add task feature
+ text: "New task/milestone feature is available only in Easy Gantt PRO \r\n
Check for
+ update! "
+ baseline:
+ heading: Baselines feature
+ text: "Baselines feature is available only in Easy Gantt PRO \r\n
Check
+ for update! "
+ critical:
+ heading: Critical path feature
+ text: "Critical path feature is available only in Easy Gantt PRO \r\n
Check
+ for update! "
+ resource:
+ heading: Resource manager feature
+ text: Resource management feature is available only in
+ Easy Redmine
+ reload_modal:
+ label_errors: Errors
+ text_reload_appeal: Do you want to ignore unsaved items and reload data from
+ server?
+ title: Gantt failed to save properly
+ sample_global_free:
+ text: Sample data cannot be closed. Gantt over all projects is available only
+ in PRO version
+ video:
+ text: Here you can see most of features of Gantt over all projects
+ title: Sample video of Gantt over all projects
+ video_id: EiiqBrrY4m4
+ sample:
+ close_label: Close this window and load real project data
+ header: Sample data are loaded!
+ text: We have prepared some sample data for you to
try all Easy Gantt
+ features with no stress . We also want to encourage you to watch a
+ video guide showing useful tweaks. Closing this window will load real project
+ data.
+ video_label: Watch video tutorial
+ video:
+ text: Here you can see most of features of this Gantt module
+ title: Sample video
+ video_id: UHgqfsrD59Q
+ text_blocker_milestone: Milestone is blocking task to be moved beyond this date
+ text_blocker_move_pre: Task has relation that blocks moving task beyond this date
+ text_blocker_move_end: At least one following task will be postponed if moved after this date
+ title:
+ button_test: Test button (only for testing)
+ day_zoom: Zoom to day scale
+ jump_today: Display timeline at today
+ month_zoom: Zoom to month scale
+ print_fit: Scale the gantt to one page
+ quarter_zoom: Zoom to quarter scale
+ week_zoom: Zoom to week scale
+ year_zoom: Zoom to year scale
+ easy_printable_templates_categories:
+ easy_gantt: Easy Gantt
+ easy_query:
+ name:
+ easy_gantt_easy_issue_query: Easy Gantt
+ easy_gantt_easy_project_query: Global Easy Gantt
+ error_easy_gantt_view_permission: You do not have permission to see Easy Gantt
+ error_epm_easy_gantt_already_active: Easy gantt on the page is already active
+ field_easy_gantt_default_zoom: Default zoom
+ field_easy_gantt_relation_delay_in_workdays: Relation delays in workdays
+ field_easy_gantt_show_holidays: Show holidays
+ field_easy_gantt_show_project_progress: Show project progress
+ field_easy_gantt_show_task_soonest_start: Show soonest start
+ field_relation: Relation
+ heading_delay_popup: Define delay in days
+ heading_demo_feature_popup: Coming soon
+ heading_easy_gantts_issues: Easy Gantt Free
+ label_easy_gantt: Easy Gantt
+ label_easy_gantt_critical_path: Critical path
+ label_easy_gantt_settings: Gantt settings
+ label_filter_group_easy_gantt_easy_issue_query: Task fields
+ label_finish_to_finish: Finish to finish
+ label_parent_issue_plural: Parent tasks
+ label_start_to_finish: Start to finish
+ label_start_to_start: Start to start
+ link_easy_gantt_plugin: https://www.easyredmine.com/easy-gantt-upgrade-to-pro
+ permission_edit_easy_gantt: Edit Easy Gantt & Resource management on a project
+ permission_edit_global_easy_gantt: Edit global Easy Gantt & Resource management
+ permission_edit_personal_easy_gantt: Edit personal Easy Gantt & Resource management
+ permission_view_easy_gantt: View Easy Gantt & Resource management on a project
+ permission_view_global_easy_gantt: View global Easy Gantt & Resource management
+ permission_view_personal_easy_gantt: View personal Easy Gantt & Resource management
+ project_default_page:
+ easy_gantt: Easy Gantt
+ project_module_easy_gantt: Easy Gantt
+ text_demo_feature_popup: This feature will be available soon.
+ text_easy_gantt_footer: Redmine Gantt powered by Easy
+ text_easy_gantt_print_easy_gantt_current: Show current Easy Gantt (works only from
+ page where is easy gantt loaded)
+ text_easy_gantt_relation_delay_in_workdays: Do not count non-working days in relation
+ delay
+ text_easy_gantt_show_holidays: Show current user holidays on gantt (works only in
+ Easy Redmine)
+ text_easy_gantt_show_project_progress: Show completed percent on project's bar (may
+ be slow to load)
+ text_easy_gantt_show_task_soonest_start: Show lowest valid dates for tasks defined
+ by relations or parent
+ title_easy_gantt_settings: Easy Gantt
+ field_easy_gantt_fixed_delay: Fixed delay
+ text_easy_gantt_fixed_delay: Keep relation delay fixed when task is dragging (works only on easy gantt)
+ label_easy_gantt_recalculate_fixed_delay: recalculate fixed delay
+ notice_easy_gantt_fixed_delay_recalculated: Fixed delay on all relations was recalculated
diff --git a/plugins/easy_gantt/config/locales/es.yml b/plugins/easy_gantt/config/locales/es.yml
new file mode 100644
index 0000000..40ad8fa
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/es.yml
@@ -0,0 +1,163 @@
+---
+es:
+ button_print: Imprimir
+ button_project_menu_easy_gantt: Easy Gantt
+ button_top_menu_easy_gantt: Proyectos Gantt
+ button_use_actual_delay: Emplear retraso exacto
+ easy_gantt:
+ button:
+ close_all: Cerrar todo
+ close_all_parent_issues: Cerrar todas las tareas matrices
+ create_baseline: Referencias
+ critical_path: Ruta crítica
+ day_zoom: Días
+ delayed_project_filter: Filtrar los proyectos atrasados
+ jump_today: Saltar a hoy
+ load_sample_data: Cargar datos de muestra
+ month_zoom: Meses
+ print_fit: Ajustar a la página
+ problem_finder: Problemas
+ reload: Recargar (guardar)
+ remove_delay: Eliminar retraso
+ resource_management: Gestión de los recursos
+ tool_panel: Herramientas
+ week_zoom: Semanas
+ critical_path:
+ disabled: Deshabilitada
+ last: Última
+ last_text: Tareas que no deberían retrasarse
+ longest: Más largas
+ longest_text: Mostrar la secuencia de tareas más larga
+ errors:
+ duplicate_link: No se puede crear enlace duplicado
+ fresh_milestone: No se puede añadir tarea a un objetivo no guardado. Primero,
+ guarda el objetivo.
+ link_target_new: No se puede crear enlace a la tarea sin guardar. Primero, guarda
+ los cambios.
+ link_target_readonly: Tarea objetivo solo de lectura
+ loop_link: No se puede crear enlace con vínculo
+ no_rest_api: Easy Gantt requiere que REST API esté habilitado. Actívalo en Administración
+ -> Ajustes -> API -> Activar servicio web REST
+ overdue: debería terminar en el futuro o debería haberse cerrado ya
+ overmile: debería terminar en %{effective_date} para poder mantener el objetivo
+ short_delay: debe ser más extenso en %{diff} días
+ too_short: no contiene días suficientes para %{rest} horas de tiempo estimado
+ unsaved_parent: No se puede añadir tarea a una matriz sin guardar. Primero,
+ guarda los cambios.
+ unsupported_link_type: Tipo de enlace no compatible
+ gateway:
+ entity_save_failed: "%{entityType} %{entityName} no se ha guardado debido a
+ un error"
+ send_failed: Solicitud fallida
+ label_pro_upgrade: Actualizar a la versión PRO
+ link_dir:
+ link_end: como el anterior
+ link_start: como el siguiente
+ popup:
+ add_task:
+ heading: Añadir característica de tarea
+ text: La nueva característica de tarea/objetivo está disponible únicamente
+ en Easy Gantt PRO
¡Marcar
+ para actualizar!
+ baseline:
+ heading: Característica de referencias
+ text: La característica de la referencia está disponible únicamente en Easy
+ Gantt PRO
¡Marcar
+ para actualizar!
+ critical:
+ heading: Característica de ruta crítica
+ text: La característica de la ruta crítica está disponible únicamente en Easy
+ Gantt PRO
Marcar
+ para actualizar
+ resource:
+ heading: Característica de gestor de recursos
+ text: La característica de gestor de recursos está disponible únicamente en
+ Easy Redmine
+ reload_modal:
+ label_errors: Errores
+ text_reload_appeal: "¿Quieres ignorar los objetos no guardados y cargar de nuevo
+ los datos del servidor?"
+ title: Gantt no ha podido guardar correctamente
+ sample_global_free:
+ text: No se pueden cerrar los datos de muestra. Gantt en todos los proyectos
+ está disponible únicamente en la versión PRO
+ video:
+ text: Aquí podrás ver la mayoría de las características de Gantt en todos
+ los proyectos
+ title: Vídeo de muestra de Gant en todos los proyectos
+ video_id: EiiqBrrY4m4
+ sample:
+ close_label: Cerrar esta ventana y cargar los datos reales del proyecto
+ header: "¡Se han cargado los datos de muestra!"
+ text: Hemos preparado unos datos de muestra para que
pruebes todas las
+ características de Easy Gantt sin estrés . También nos gustaría animarte
+ a que visualices un vídeo de guía que muestra ajustes útiles. Al cerrar esta
+ ventana se cargarán los datos reales del proyecto.
+ video_label: Ver el vídeo tutorial
+ video:
+ text: Aquí podrás ver la mayoría de las características de este módulo de
+ Gantt
+ title: Vídeo de muestra
+ video_id: UHgqfsrD59Q
+ text_blocker_milestone: El objetivo no permite que la tarea se desplace después
+ de esta fecha
+ text_blocker_move_pre: La tarea tiene una relación que bloquea su desplazamiento
+ a una fecha posterior
+ title:
+ button_test: Botón de prueba (sólo para pruebas)
+ day_zoom: Ampliar a escala de día
+ jump_today: Mostrar calendario en hoy
+ month_zoom: Ampliar a escala de mes
+ print_fit: Ajustar gantt a una página
+ week_zoom: Ampliar a escala de semana
+ easy_printable_templates_categories:
+ easy_gantt: Easy Gantt
+ easy_query:
+ name:
+ easy_gantt_easy_issue_query: Easy Gantt
+ easy_gantt_easy_project_query: Global Easy Gantt
+ error_easy_gantt_view_permission: No tienes permiso para ver Easy Gantt
+ error_epm_easy_gantt_already_active: Ya está activo Easy Gantt en la página
+ field_easy_gantt_default_zoom: Zoom por defecto
+ field_easy_gantt_relation_delay_in_workdays: Retrasos de relación en días hábiles
+ field_easy_gantt_show_holidays: Mostrar vacaciones
+ field_easy_gantt_show_project_progress: Mostrar el progreso del proyecto
+ field_easy_gantt_show_task_soonest_start: Mostrar el inicio más próximo
+ field_keep_link_delay_in_drag: Retraso constante del enlace durante el arrastre
+ field_relation: Relación
+ heading_delay_popup: Definir retraso en días
+ heading_demo_feature_popup: Muy pronto
+ heading_easy_gantts_issues: Easy Gantt gratis
+ label_easy_gantt: Easy Gantt
+ label_easy_gantt_critical_path: Senda crítica
+ label_easy_gantt_settings: Ajustes de Gantt
+ label_filter_group_easy_gantt_easy_issue_query: Campos de tarea
+ label_finish_to_finish: Fin a fin
+ label_parent_issue_plural: Problemas de matriz
+ label_start_to_finish: Inicio a fin
+ label_start_to_start: Inicio a inicio
+ link_easy_gantt_plugin: https://www.easyredmine.com/actualizar-easy-gantt-a-pro
+ permission_edit_easy_gantt: Editar Easy Gantt y gestión de recursos en un proyecto
+ permission_edit_global_easy_gantt: Editar Easy Gantt y gestión de recursos global
+ permission_edit_personal_easy_gantt: Editar Easy Gantt y gestión de recursos personal
+ permission_view_easy_gantt: Ver Easy Gantt y gestión de recursos en un proyecto
+ permission_view_global_easy_gantt: Ver Easy Gantt y gestión de recursos global
+ permission_view_personal_easy_gantt: Ver Easy Gantt y gestión de recursos personal
+ project_default_page:
+ easy_gantt: Easy Gantt
+ project_module_easy_gantt: Easy Gantt
+ text_demo_feature_popup: Esta característica está disponible pronto.
+ text_easy_gantt_footer: Redmine Gantt respaldado por Easy
+ text_easy_gantt_keep_link_delay_in_drag: Mantener constante la relación de retraso
+ mientras se arrastra la tarea
+ text_easy_gantt_print_easy_gantt_current: Mostrar Easy Gantt actual (funciona sola
+ desde la página en la que se carga easy gantt)
+ text_easy_gantt_relation_delay_in_workdays: No contar días no hábiles en el retraso
+ de relación
+ text_easy_gantt_show_holidays: Mostrar las vacaciones del usuario actual en gantt
+ (funciona sólo en Easy Redmine)
+ text_easy_gantt_show_project_progress: Mostrar porcentaje completado en la barra
+ del proyecto (podría tardar al cargar)
+ text_easy_gantt_show_task_soonest_start: Mostrar las fechas válidas más bajas para
+ tareas definidas por relaciones o matriz
+ title_easy_gantt_settings: Easy Gantt
diff --git a/plugins/easy_gantt/config/locales/fi.yml b/plugins/easy_gantt/config/locales/fi.yml
new file mode 100644
index 0000000..e173d18
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/fi.yml
@@ -0,0 +1,2 @@
+---
+fi:
diff --git a/plugins/easy_gantt/config/locales/fr.yml b/plugins/easy_gantt/config/locales/fr.yml
new file mode 100644
index 0000000..ae08ce6
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/fr.yml
@@ -0,0 +1,163 @@
+---
+fr:
+ button_print: Imprimer
+ button_project_menu_easy_gantt: Easy Gantt
+ button_top_menu_easy_gantt: Easy Gantt
+ button_use_actual_delay: Utilisez le délai réel
+ easy_gantt_toolbar:
+ day: Jours
+ month: Mois
+ week: Semaines
+ easy_gantt:
+ button:
+ close_all: Fermer tout
+ close_all_parent_issues: Fermer toutes les tâches parents
+ create_baseline: Lignes de base
+ critical_path: Chemin critique
+ day_zoom: Jours
+ delayed_project_filter: Filtrer les projets retardés
+ jump_today: Aller à aujourd'hui
+ load_sample_data: Charger données d'échantillon
+ month_zoom: Mois
+ print_fit: Ajuster à la page
+ problem_finder: Problèmes
+ reload: Recharger (sauvegarder)
+ remove_delay: Éliminer délai
+ resource_management: Gestion des resources
+ tool_panel: Outils
+ week_zoom: Semaines
+ critical_path:
+ disabled: Désactivé
+ last: Dernier
+ last_text: Tâches qui ne doivent pas être retardées
+ longest: La plus longue
+ longest_text: Afficher la séquence de tâches la plus longue
+ errors:
+ duplicate_link: Cannot create duplicate link
+ fresh_milestone: Cannot add task to non-saved milestone. Save the milestone
+ first.
+ link_target_new: Vous ne pouvez pas créer un lien vers la tâche non-sauvegardée.
+ Commencez par enregistrer les modifications.
+ link_target_readonly: Tâche cible en lecture seule
+ loop_link: Cannot create looped link
+ no_rest_api: Easy Gantt doit activer REST API. Allumez-le dans Administration
+ - > Paramètres -> API - > Activer REST web service
+ overdue: devrait se terminer à l'avenir ou devrait être déjà fermé
+ overmile: La tâche doit être terminée avant la date d'échéance du jalon
+ short_delay: Devrait être plus long de %{diff} jours
+ too_short: Tâche est trop courte pour le nombre d'heures estimés
+ unsaved_parent: Impossible d'ajouter la tâche au parent non-enregistré. Commencez
+ par enregistrez les modifications.
+ unsupported_link_type: Type de lien non reconnu
+ gateway:
+ entity_save_failed: "%{entityType} %{entityName} n'a pas pu sauvegarder due
+ à une erreur"
+ send_failed: Request failed
+ label_pro_upgrade: Upgrade to PRO version
+ link_dir:
+ link_end: as preceding
+ link_start: as following
+ popup:
+ add_task:
+ heading: Ajouter la tâche fonctionnalité
+ text: Cette fonctionnalité est à venir bientôt.
Check
+ the availability here!
+ baseline:
+ heading: Lignes de base disposent
+ text: Baselines fonctionnalité bientôt disponible.
Check
+ the availability here!
+ critical:
+ heading: Fonctionnalité du chemin critique
+ text: "Fonctionnalité du chemin critique sera disponible bientôt.\r\n
Check
+ the availability here! "
+ resource:
+ heading: Fonctionnalité de gestion de ressources
+ text: Fonctionnalité de gestion de ressources est disponible
+ Easy Redmine
+ reload_modal:
+ label_errors: Erreurs
+ text_reload_appeal: Voulez-vous ignorer des éléments non enregistrés et recharger
+ les données à partir du serveur ?
+ title: Gantt n'a pas réussi à enregistrer correctement
+ sample_global_free:
+ text: Sample data cannot be closed. Gantt over all projects is available only
+ in PRO version
+ video:
+ text: Here you can see most of features of Gantt over all projects
+ title: Sample video of Gantt over all projects
+ video_id: EiiqBrrY4m4
+ sample:
+ close_label: Close this window and load real project data
+ header: Sample data are loaded!
+ text: We have prepared some sample data for you to
try all Gantt features
+ with no stress . We also want to encourage you to watch a video guide
+ showing useful tweaks. Closing this window will load real project data.
+ video_label: Watch video tutorial
+ video:
+ text: Here you can see most of features of this Gantt module
+ title: Sample video
+ video_id: UHgqfsrD59Q
+ text_blocker_milestone: Un jalon empêche la tâche d'être déplacée au-delà de cette
+ date
+ text_blocker_move_pre: La tâche a une relation qui bloque le déplacement de la
+ tâche au-delà de cette date
+ title:
+ button_test: Test button (only for testing)
+ day_zoom: Zoom to day scale
+ jump_today: Display timeline at today
+ month_zoom: Zoom to month scale
+ print_fit: Réduire le diagramme de Gantt à une page
+ week_zoom: Zoom to week scale
+ easy_printable_templates_categories:
+ easy_gantt: Easy Gantt
+ easy_query:
+ name:
+ easy_gantt_easy_issue_query: Easy Gantt
+ easy_gantt_easy_project_query: Global Easy Gantt
+ error_easy_gantt_view_permission: Vous n'êtes pas autorisé à voir Easy Gantt
+ error_epm_easy_gantt_already_active: Easy gantt sur la page est déjà actif
+ field_easy_gantt_default_zoom: Zoom par défaut
+ field_easy_gantt_relation_delay_in_workdays: Délais des relations en journées de
+ travail
+ field_easy_gantt_show_holidays: Afficher les vacances
+ field_easy_gantt_show_project_progress: Afficher les progrès du projet
+ field_easy_gantt_show_task_soonest_start: Afficher le démarrage le plus tôt
+ field_keep_link_delay_in_drag: Délai de lien constant pendant glissement
+ field_relation: Relation
+ heading_delay_popup: Définir délai en jours
+ heading_demo_feature_popup: À venir
+ heading_easy_gantts_issues: Easy Gantt Free
+ label_easy_gantt: Easy Gantt
+ label_easy_gantt_critical_path: Chemin critique
+ label_easy_gantt_settings: Paramètres de Gantt
+ label_filter_group_easy_gantt_easy_issue_query: Champs de tâches
+ label_finish_to_finish: Terminer pour terminer
+ label_parent_issue_plural: Problèmes parents
+ label_start_to_finish: Début à la fin
+ label_start_to_start: Démarrer pour démarrer
+ link_easy_gantt_plugin: https://www.easyredmine.com/easy-gantt-upgrade-to-pro
+ permission_edit_easy_gantt: Éditer Easy Gantt et gestion des ressources sur un projet
+ permission_edit_global_easy_gantt: Éditer Easy Gantt & Resource management global
+ permission_edit_personal_easy_gantt: Éditer Easy Gantt & Gestion des ressources
+ personnel
+ permission_view_easy_gantt: Voir Easy Gantt et Gestion des ressources sur un projet
+ permission_view_global_easy_gantt: Voir Easy Gantt & Resource management global
+ permission_view_personal_easy_gantt: Voir Easy Gantt & Resource management personnel
+ project_default_page:
+ easy_gantt: Easy Gantt
+ project_module_easy_gantt: Easy Gantt
+ text_demo_feature_popup: Cette fonctionnalité sera disponible bientôt.
+ text_easy_gantt_footer: Redmine Gantt powered by Easy
+ text_easy_gantt_keep_link_delay_in_drag: Maintient le délai de relation constant
+ pendant que la tâche est déplacée en arrière
+ text_easy_gantt_print_easy_gantt_current: Afficher l'actuel Easy Gantt (fonctionne
+ uniquement à partir de la page sur laquelle easy gantt est chargé)
+ text_easy_gantt_relation_delay_in_workdays: Ne pas compter les journées non-ouvrables
+ en délai de relation
+ text_easy_gantt_show_holidays: Afficher les vacances de l'utilisateur actuel sur
+ Gantt ( fonctionne uniquement dans Easy Redmine)
+ text_easy_gantt_show_project_progress: Afficher le pourcentage terminé sur la barre
+ de projet (peut être lent à charger)
+ text_easy_gantt_show_task_soonest_start: Afficher les dates de validité les plus
+ basses pour les tâches définies par des relations ou parent
+ title_easy_gantt_settings: Easy Gantt
diff --git a/plugins/easy_gantt/config/locales/he.yml b/plugins/easy_gantt/config/locales/he.yml
new file mode 100644
index 0000000..de35edf
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/he.yml
@@ -0,0 +1,2 @@
+---
+he:
diff --git a/plugins/easy_gantt/config/locales/hr.yml b/plugins/easy_gantt/config/locales/hr.yml
new file mode 100644
index 0000000..8ecf54a
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/hr.yml
@@ -0,0 +1,8 @@
+---
+hr:
+ button_print: Ispiši
+ button_use_actual_delay: Koristi stvarno kašnjeje
+ easy_gantt:
+ button:
+ close_all: Zatvori sve
+ tool_panel: Alati
diff --git a/plugins/easy_gantt/config/locales/hu.yml b/plugins/easy_gantt/config/locales/hu.yml
new file mode 100644
index 0000000..0b8ade7
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/hu.yml
@@ -0,0 +1,159 @@
+---
+hu:
+ button_print: Nyomtatás
+ button_project_menu_easy_gantt: Easy Gantt
+ button_top_menu_easy_gantt: Projekt Gantt
+ button_use_actual_delay: Használja a jelenlegi késést
+ easy_gantt:
+ button:
+ close_all: Mind bezárása
+ close_all_parent_issues: Minden feladat bezására
+ create_baseline: Baselines
+ critical_path: Kritikus végrehajtási útvonal
+ day_zoom: Napok
+ delayed_project_filter: Elhalasztott projektek szűrése
+ jump_today: Ugrás a mai napra
+ load_sample_data: Minta adat betöltése
+ month_zoom: Hónapok
+ print_fit: Oldalhoz igazítás
+ problem_finder: Problémák
+ reload: Újratöltés (mentés)
+ remove_delay: Késés megszüntetése
+ resource_management: Erőforrások kezelése
+ tool_panel: Eszközök
+ week_zoom: Hetek
+ critical_path:
+ disabled: Letiltva
+ last: Utolsó
+ last_text: Nem halasztható feladatok
+ longest: Leghosszabb
+ longest_text: Leghosszabb feladatsorozat megjelenítése
+ errors:
+ duplicate_link: Kettős kapcsolat létrehozása nem lehetséges
+ fresh_milestone: A nem mentett mérföldkövekhez nem adható feladat. Először mentse
+ el a mérföldkövet.
+ link_target_new: A nem mentett feladatokhoz nem hozható létre link. Először
+ mentse el a változásokat.
+ link_target_readonly: Csak olvasható célfeladat
+ loop_link: Visszahivatkozó kapcsolat létrehozása nem lehetséges
+ no_rest_api: Az Easy Gantt-nek szüksége van a REST API szolgáltatásra. Engedélyezze
+ az adminisztráció => Beállítások => REST webes szolgáltatás bekapcsolásával
+ overdue: Hamarosan be kell fejeződnie, vagy már be kellett volna fejezni.
+ overmile: "%{effective_date} dátummal kell befejeződnie hogy tartsa a mérföldkő
+ határidejét"
+ short_delay: "%{diff} nappal hosszabbnak kell lennie"
+ too_short: Nincs elegendő nap a hátralévő %{rest} becsült óra számára
+ unsaved_parent: Nem adhat feladatot nem mentett szülőfeladathoz. Először mentse
+ a változásokat.
+ unsupported_link_type: Nem támogatott linktípus
+ gateway:
+ entity_save_failed: "%{entityType} %{entityName} hiba miatt nem sikerült menteni"
+ send_failed: Kérés nem sikerült
+ label_pro_upgrade: Frissítsen PRO verzióra
+ link_dir:
+ link_end: megelőzőként
+ link_start: következőként
+ popup:
+ add_task:
+ heading: Feladat jellemző hozzáadása
+ text: Új feladat/ mérföldkő tulajdonság csak az Easy Gantt PRO csomagban érhető
+ el
Frissítés
+ keresése!
+ baseline:
+ heading: Baselines jellemzői
+ text: Alapbeállítás jellemzői csak az Easy Gantt PRO
+ csomagban érhető el.
+ critical:
+ heading: Kritikus végrehajtási út funkció
+ text: Kritikus végrehajtási út funkció csak az Easy Gantt PRO csomagban elérhető
+ el.
Kövesse
+ a frissítéseket!
+ resource:
+ heading: Erőforrástervező funkció
+ text: Az Erőforrástervező funkció csak az Easy Redmine csomagban érhető el.
Easy Redmine
+ reload_modal:
+ label_errors: Hibák
+ text_reload_appeal: Szeretné figyelmen kívül hagyni a nem mentett elemeket és
+ újratölteni az adatokat egy másik szerverről?
+ title: Nem sikerült a Gannt megfelelő mentése
+ sample_global_free:
+ text: A minta adatokat nem lehet bezárni.A Gantt átfogó projektjei csak a PRO
+ verzióban érhetők el
+ video:
+ text: Itt látható Gantt átfogó projektjeinek tulajdonságai
+ title: Gantt átfogó projektjeinek minta videója
+ video_id: EiiqBrrY4m4
+ sample:
+ close_label: Zárja be ezt az ablakot és töltsön fel valós projekt adatokat
+ header: Minta adat betöltődött
+ text: Előkészítettünk néhány mintaadatot Önnek, hogy minden Easy Gantt funkciót
+ kipróbálhasson probléma nélkül. Emellett javasoljuk, tekintse meg a videós
+ bemutatót is. Az ablak bezárása után betöltődnek a valós projektadatok.
+ video_label: Nézze meg az oktatóvideót
+ video:
+ text: Itt látható a Gantt modul legtöbb tulajdonsága
+ title: Bemutató videó
+ video_id: UHgqfsrD59Q
+ text_blocker_milestone: A mérföldkő megakadályozza, hogy a feladatot át lehessen
+ vinni az adott dátumon túl
+ text_blocker_move_pre: A feladatnak olyan kapcsolatai vannak amelyek nem engedik
+ meg hogy az adott dátumon túl átvihető legyen.
+ title:
+ button_test: Teszt gomb (csak teszteléskor)
+ day_zoom: Váltás napi nézetre
+ jump_today: Mai napi idővonal megjelenítése
+ month_zoom: Váltás havi nézetre
+ print_fit: Gantt egész oldalas nagyítása
+ week_zoom: Váltás heti nézetre
+ easy_printable_templates_categories:
+ easy_gantt: Easy Gantt
+ easy_query:
+ name:
+ easy_gantt_easy_issue_query: Easy Gantt
+ easy_gantt_easy_project_query: Global Easy Gantt
+ error_easy_gantt_view_permission: Nincs felhatalazma az Easy Gantt eléréséhez
+ error_epm_easy_gantt_already_active: Easy Gantt már aktív az oldalon
+ field_easy_gantt_default_zoom: Alapértelmezett nézet
+ field_easy_gantt_relation_delay_in_workdays: Kapcsolódó késések munkanapokban
+ field_easy_gantt_show_holidays: Szabadnapok megjelenítése
+ field_easy_gantt_show_project_progress: Projekt folyamatának mutatása
+ field_easy_gantt_show_task_soonest_start: Legkorábbi kezdés megjelenítése
+ field_keep_link_delay_in_drag: Átmozgatás során a késés és kapcsolat megőrzése
+ field_relation: Kapcsolat
+ heading_delay_popup: Adja meg a késést napokban
+ heading_demo_feature_popup: Hamarosan
+ heading_easy_gantts_issues: Ingyenes Easy Gantt
+ label_easy_gantt: Easy Gantt
+ label_easy_gantt_critical_path: Kritikus végrehajtási útvonal
+ label_easy_gantt_settings: Gantt beállítások
+ label_filter_group_easy_gantt_easy_issue_query: Feladat mezők
+ label_finish_to_finish: Befejezéstől a befejezésig
+ label_parent_issue_plural: Szülőfeladatok
+ label_start_to_finish: Kezdéstől a befejezésig
+ label_start_to_start: Kezdéstől kezdésig
+ link_easy_gantt_plugin: https://www.easyredmine.com/easy-gantt-upgrade-to-pro
+ permission_edit_easy_gantt: Easy Gantt & Erőforrástervezés szerkesztése a projekten
+ permission_edit_global_easy_gantt: Globális Easy Gantt és Erőforrástervezés szerkesztése
+ permission_edit_personal_easy_gantt: Személyes Easy Gantt és Erőforrástervező szerkesztése
+ permission_view_easy_gantt: Easy Gantt & Erőforrástervezés megtekintése a projekten
+ permission_view_global_easy_gantt: Globális Easy Gantt és Erőforrástervezés megtekintése
+ permission_view_personal_easy_gantt: Személyes Easy Gantt és Erőforrástervező megtekintése
+ project_default_page:
+ easy_gantt: Easy Gantt
+ project_module_easy_gantt: Easy Gantt
+ text_demo_feature_popup: Ez a tulajdonság hamarosan elérhető lesz
+ text_easy_gantt_footer: Az Easy működteti a Redmine Gantt
+ text_easy_gantt_keep_link_delay_in_drag: Tartsa meg a késés mértékét a feladat korábbra
+ helyezésekor
+ text_easy_gantt_print_easy_gantt_current: Mutasd az aktív Easy Gantt-et (csak arról
+ az oldalról működik, ahonnan az Easy Gantt-et betöltötték )
+ text_easy_gantt_relation_delay_in_workdays: A kapcsolódó késésben a munkaszüneti
+ napokat ne számolja
+ text_easy_gantt_show_holidays: Mutassa a jelenlegi Gantt felhasználó szabadságát
+ (csak Easy Redmine-ban működik)
+ text_easy_gantt_show_project_progress: Jelenítse meg a százalékos készültségét a
+ projekt lapon (lassan töltődhet be)
+ text_easy_gantt_show_task_soonest_start: Jelenítse meg a legkorábbi érvényes dátumokat
+ a kapcsolatok vagy szülői függőség által meghatározott feladatoknál
+ title_easy_gantt_settings: Easy Gantt
diff --git a/plugins/easy_gantt/config/locales/it.yml b/plugins/easy_gantt/config/locales/it.yml
new file mode 100644
index 0000000..5996f4d
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/it.yml
@@ -0,0 +1,164 @@
+---
+it:
+ button_print: Stampa
+ button_project_menu_easy_gantt: Easy Gantt
+ button_top_menu_easy_gantt: Progetti Gantt
+ button_use_actual_delay: Utilizza il ritardo effettivo
+ easy_gantt:
+ button:
+ close_all: Chiudi tutto
+ close_all_parent_issues: Chiudi tutti i task padre
+ create_baseline: Baseline
+ critical_path: Percorso critico
+ day_zoom: Giorni
+ delayed_project_filter: Filtra Progetti Rinviati
+ jump_today: Passa a oggi
+ load_sample_data: Carica dati di prova
+ month_zoom: Mesi
+ print_fit: Adatta alla pagina
+ problem_finder: Problemi
+ reload: Ricarica (salva)
+ remove_delay: Rimuovi ritardo
+ resource_management: Gestione risorse
+ tool_panel: Strumenti
+ week_zoom: Settimane
+ critical_path:
+ disabled: Disabilitato
+ last: Finale
+ last_text: Task che non dovrebbero essere posticipati
+ longest: Più lungo
+ longest_text: Mostra la più lunga sequenza di task
+ errors:
+ duplicate_link: Creazione copia collegamento non riuscita
+ fresh_milestone: Impossibile aggiungere task a una milestone non salvata. Salvare
+ prima la milestone.
+ link_target_new: Impossibile creare collegamento a un'attività non salvata.
+ Salvare prima le modifiche.
+ link_target_readonly: Task obiettivo di sola lettura
+ loop_link: Creazione collegamento ciclico non riuscita
+ no_rest_api: Easy Gantt necessita che le REST API siano attive. Per farlo andare
+ in Amministrazione -> Impostazione -> API -> Attiva servizi web REST
+ overdue: dovrebbe terminare in futuro o dovrebbe essere già chiusa
+ overmile: Dovrebbe terminare il %{effective_date} per rispettare la milestone
+ short_delay: dovrebbe essere più lunga di %{diff} giorni
+ too_short: non include giorni a sufficienza per le %{rest} ore stimate
+ unsaved_parent: Impossibile aggiungere task a un padre non salvato. Salvare
+ prima le modifiche.
+ unsupported_link_type: Tipo di collegamento non supportato
+ gateway:
+ entity_save_failed: Salvataggio di %{entityType} %{entityName} non riuscito
+ a causa di un errore
+ send_failed: Richiesta non riuscita
+ label_pro_upgrade: Effettua l'upgrade alla versione PRO
+ link_dir:
+ link_end: come precedente
+ link_start: come seguente
+ popup:
+ add_task:
+ heading: Aggiungi funzionalità al task
+ text: La funzionalità nuova task/milestone è disponibile solo in Easy Gantt
+ PRO
Controlla
+ aggiornamenti!
+ baseline:
+ heading: Funzionalità delle baseline
+ text: La funzionalità Baseline è disponibile solo in Easy Gantt PRO
Controlla
+ aggiornamenti!
+ critical:
+ heading: Funzionalità Percorso critico
+ text: La funzionalità Percorso critico è disponibile solo in Easy Gantt PRO
+
Check for
+ update!
+ resource:
+ heading: Funzionalità Gestione risorse
+ text: La funzionalità Gestione risorse è disponibile solo in
+ Easy Redmine
+ reload_modal:
+ label_errors: Errori
+ text_reload_appeal: Desideri ignorare le voci non salvate e ricaricare i dati
+ dal server?
+ title: Gantt non salvato correttamente
+ sample_global_free:
+ text: I dati di prova non possono essere chiusi. Il Gantt per tutti i progetti
+ è disponile solo nella versione PRO
+ video:
+ text: Qui puoi vedere la maggior parte delle funzionalità del Gantt per tutti
+ i progetti
+ title: Video di esempio di Gantt su tutti i progetti
+ video_id: EiiqBrrY4m4
+ sample:
+ close_label: Chiudi questa finestra e carica i dati del progetto reale
+ header: I dati di esempio sono stati caricati!
+ text: Abbiamo alcuni dati di esempio per farti
provare tutte le funzionalità
+ di Easy Gantt senza problemi . Ti consigliamo anche di guardare la
+ videoguida che ti mostrerà degli utili accorgimenti. Chiudendo questa finestra
+ si caricheranno i dati reali del progetto.
+ video_label: Guarda il video tutorial
+ video:
+ text: Qui puoi vedere la maggior parte delle funzionalità di questo modulo
+ Gantt
+ title: Video di esempio
+ video_id: UHgqfsrD59Q
+ text_blocker_milestone: Una milestone impedisce lo spostamento del task oltre
+ questa data
+ text_blocker_move_pre: Il task ha una relazione che impedisce il suo spostamento
+ oltre questa data
+ title:
+ button_test: Pulsante Test (solo per testare)
+ day_zoom: Ingrandisci a mostrare la scaletta giornaliera
+ jump_today: Mostra la timeline aggiornata ad oggi
+ month_zoom: Ingrandisci a mostrare la scaletta mensile
+ print_fit: Ridimensiona Gantt a una singola pagina
+ week_zoom: Ingrandisci a mostrare la scaletta settimanale
+ easy_printable_templates_categories:
+ easy_gantt: Easy Gantt
+ easy_query:
+ name:
+ easy_gantt_easy_issue_query: Easy Gantt
+ easy_gantt_easy_project_query: Global Easy Gantt
+ error_easy_gantt_view_permission: Non sei autorizzato a vedere Easy Gantt
+ error_epm_easy_gantt_already_active: Easy Gantt risulta già attivo sulla pagina
+ field_easy_gantt_default_zoom: Ingrandimento predefinito
+ field_easy_gantt_relation_delay_in_workdays: Differimento di relazione nei giorni
+ lavorativi
+ field_easy_gantt_show_holidays: Mostra giorni festivi
+ field_easy_gantt_show_project_progress: Mostra l'avanzamento del progetto
+ field_easy_gantt_show_task_soonest_start: Mostra l'inizio più prossimo
+ field_keep_link_delay_in_drag: Ritardo di collegamento costante durante il trascinamento
+ field_relation: Relazione
+ heading_delay_popup: Definisci il ritardo in giorni
+ heading_demo_feature_popup: Disponibile a breve
+ heading_easy_gantts_issues: Easy Gantt Free
+ label_easy_gantt: Easy Gantt
+ label_easy_gantt_critical_path: Percorso critico
+ label_easy_gantt_settings: Impostazioni Gantt
+ label_filter_group_easy_gantt_easy_issue_query: Settori del task
+ label_finish_to_finish: Termina dalla fine
+ label_parent_issue_plural: Task padre
+ label_start_to_finish: Parti dalla fine
+ label_start_to_start: Parti dall'inizio
+ link_easy_gantt_plugin: https://www.easyredmine.com/easy-gantt-upgrade-to-pro
+ permission_edit_easy_gantt: Modifica Easy Gantt e Gestione risorse in un progetto
+ permission_edit_global_easy_gantt: Modifica Easy Gantt e Gestione risorse
+ permission_edit_personal_easy_gantt: Modifica Easy Gantt e Gestione risorse personali
+ permission_view_easy_gantt: Visualizza Easy Gantt e Gestione risorse applicati a
+ un progetto
+ permission_view_global_easy_gantt: Visualizza Easy Gantt e Gestione risorse
+ permission_view_personal_easy_gantt: Visualizza Easy Gantt e Gestione risorse personali
+ project_default_page:
+ easy_gantt: Easy Gantt
+ project_module_easy_gantt: Easy Gantt
+ text_demo_feature_popup: Questa funzionalità sarà presto disponibile.
+ text_easy_gantt_footer: Redmine Gantt è offerto da Easy
+ text_easy_gantt_keep_link_delay_in_drag: Mantieni costanti i rapporti di ritardo
+ mentre il task viene spostato indietro
+ text_easy_gantt_print_easy_gantt_current: Mostra Easy Gantt attuale (funziona solo
+ da pagine in cui è caricato Easy Gantt)
+ text_easy_gantt_relation_delay_in_workdays: Non tenere conto dei giorni non lavorativi
+ nel differimento di relazione
+ text_easy_gantt_show_holidays: Mostra sul Gantt i giorni di ferie dell'utente (funziona
+ solo in Easy Redmine)
+ text_easy_gantt_show_project_progress: Mostra la percentuale di completamento sulla
+ barra del progetto (potrebbe risultare lenta da caricare)
+ text_easy_gantt_show_task_soonest_start: Mostra le date disponibili più vicine per
+ i task definiti da relazioni o dipendenza
+ title_easy_gantt_settings: Easy Gantt
diff --git a/plugins/easy_gantt/config/locales/ja.yml b/plugins/easy_gantt/config/locales/ja.yml
new file mode 100644
index 0000000..a7eaf2a
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/ja.yml
@@ -0,0 +1,146 @@
+---
+ja:
+ button_print: 印刷
+ button_project_menu_easy_gantt: Easy Gantt
+ button_top_menu_easy_gantt: Projects Gantt
+ button_use_actual_delay: 実際の遅延日数を使用
+ easy_gantt:
+ button:
+ close_all: すべて閉じる
+ close_all_parent_issues: すべての親タスクを閉じる
+ create_baseline: ベースライン
+ critical_path: クリティカルパス
+ day_zoom: 日数
+ delayed_project_filter: 遅延しているプロジェクトをフィルタする
+ jump_today: 今日に移動
+ load_sample_data: サンプルデータを読み込む
+ month_zoom: 月数
+ print_fit: ページに合わせる
+ problem_finder: 問題
+ reload: 再読み込み(保存)
+ remove_delay: 遅延を削除
+ resource_management: リソース・マネージメント
+ tool_panel: ツール
+ week_zoom: 週数
+ critical_path:
+ disabled: 無効
+ last: 最終
+ last_text: 遅延できないタスク
+ longest: 最長
+ longest_text: タスクの最長シーケンスを表示
+ errors:
+ duplicate_link: リンクのコピーを作成できません
+ fresh_milestone: 保存されていないマイルストーンにはタスクを追加できません。まず、マイルストーンを保存してください。
+ link_target_new: 保存されていないタスクにはリンクを作成できません。まず、変更を保存してください。
+ link_target_readonly: ターゲット・タスクは読み取り専用です
+ loop_link: 無限ループを作ってはなりません。
+ no_rest_api: このEasy Ganttを使うためには、REST APIを有効にする必要があります。管理⇒設定⇒APIと進み、REST Webサービスを有効にしてください。
+ overdue: あとで完了するか、すでにタスクはクローズされています
+ overmile: マイルストーンを保つには、%{effective date}に完了する必要があります。
+ short_delay: "%{diff} 日以上、必要です"
+ too_short: 予定作業時間%{rest}に対して、日数が不足しています
+ unsaved_parent: 保存されていない親タスクにタスクの追加はできません。まず、変更を保存してください
+ unsupported_link_type: サポートされていないリンクタイプです
+ gateway:
+ entity_save_failed: "%{entityType} %{entityName} はエラーのため、保存できませんでした"
+ send_failed: 要求は失敗しました
+ label_pro_upgrade: PROにアップグレード
+ link_dir:
+ link_end: 前の通り
+ link_start: 以下の通り
+ popup:
+ add_task:
+ heading: タスクの機能追加
+ text: 今回新たに追加されたタスク/マイルストーン機能は、Easy Gantt PROでのみ使用できます。\r\n
PROのアップデートされた機能については、こちらからご確認ください! "
+ baseline:
+ heading: ベースライン機能
+ text: "ベースライン機能は、Easy Gantt PROでのみ使用できます。\r\n
PROのアップデートされた機能については、こちらからご確認ください! "
+ critical:
+ heading: クリティカルパス機能
+ text: "クリティカルパス機能は、Easy Gantt PROでのみ使用できます。\r\n
PROのアップデートされた機能については、こちらからご確認ください! "
+ resource:
+ heading: リソース・マネージャー機能
+ text: リソースマネージメント機能は
Easy Redmine でのみ使用できます。
+ reload_modal:
+ label_errors: エラー
+ text_reload_appeal: 保存されていない変更を破棄して、サーバのデータを再読み込みしますか?
+ title: Ganttが正しく保存されませんでした。
+ sample_global_free:
+ text: 全プロジェクト横断管理ガントチャートはPROバージョンのみで使用可能です。
+ video:
+ text: 全プロジェクト横断管理ガントチャートの大半の機能はこちらから見ることができます。
+ title: 全プロジェクト横断管理ガントチャートのデモビデオ
+ video_id: zd3M0KYxcXM
+ sample:
+ close_label: このウィンドウを閉じて、実際のプロジェクトデータを読み込む
+ header: サンプルデータが読み込まれました!
+ text: "
Easy Ganttの機能をストレスなく試していただくため 、サンプルデータを用意しました。また、便利な使い方を説明したビデオガイドもご用意しています。このウィンドウを閉じると、実際のプロジェクトデータが読み込まれます。"
+ video_label: ビデオチュートリアルを見る
+ video:
+ text: このGanttモジュールの機能はこちらから見ることができます
+ title: サンプルビデオ
+ video_id: UHgqfsrD59Q
+ text_blocker_milestone: マイルストーンによってタスクの延期がブロックされています。
+ text_blocker_move_end: このタスクをこの日付以降に延期すると、以下のタスクのうち一つ以上のタスクが延期されます。
+ text_blocker_move_pre: このタスクはリレーションにより拘束されているため、このタスクをこの日付以降にずらすことはできません。
+ title:
+ button_test: テスト ボタン(テスト専用)
+ day_zoom: 日単位で表示
+ jump_today: 今日のチャートを表示する
+ month_zoom: 月単位で表示
+ print_fit: Ganttのチャートを1ページの大きさにする
+ week_zoom: 週単位で表示
+ easy_printable_templates_categories:
+ easy_gantt: Easy Gantt
+ easy_query:
+ name:
+ easy_gantt_easy_issue_query: Easy Gantt
+ easy_gantt_easy_project_query: Global Easy Gantt
+ error_easy_gantt_view_permission: Easy Ganttを見る権限がありません。
+ error_epm_easy_gantt_already_active: 既に有効になっています このページ上のEasy Ganttはすでに有効になっています。
+ error_small_screen: ガントチャートを表示するには端末の画面が小さすぎます
+ field_easy_gantt_default_zoom: デフォルト・タイムライン
+ field_easy_gantt_fixed_delay: タスク間の固定ラグタイム
+ field_easy_gantt_relation_delay_in_workdays: 作業日数におけるリレーション全体のデレイ
+ field_easy_gantt_show_holidays: 休日の表示
+ field_easy_gantt_show_project_progress: プロジェクト進捗の表示
+ field_easy_gantt_show_task_soonest_start: 最も早い開始日を表示
+ field_keep_link_delay_in_drag: ドラッグ作業中、タスク間ラグタイムは変わりません
+ field_relation: リレーション
+ heading_delay_popup: 遅延を日数で確認
+ heading_demo_feature_popup: Coming soon
+ heading_easy_gantts_issues: Easy Gantt無料版
+ label_easy_gantt: Easy Gantt
+ label_easy_gantt_critical_path: クリティカルパス
+ label_easy_gantt_critical_path: Critical path
+ label_easy_gantt_global: グローバル
+ label_easy_gantt_issue_loaded: 全タスク読み込み完了
+ label_easy_gantt_load: 読み込む
+ label_easy_gantt_recalculate_fixed_delay: タスク間の固定ラグタイムの再計算
+ label_easy_gantt_settings: Gantt設定
+ label_filter_group_easy_gantt_easy_issue_query: タスクフィールド
+ label_finish_to_finish: 終了‐終了
+ label_parent_issue_plural: 親タスク
+ label_start_to_finish: 開始‐終了
+ label_start_to_start: 開始‐開始
+ link_easy_gantt_plugin: https://www.easyredmine.com/easy-gantt-upgrade-to-pro
+ notice_easy_gantt_fixed_delay_recalculated: 関連付けられた全タスク間の固定ラグタイムが再計算完了
+ permission_edit_easy_gantt: 任意のプロジェクト上でEasy Gantt とResource Managementを編集する
+ permission_edit_global_easy_gantt: Easy Gantt(全体)とリソース・マネージメントを編集
+ permission_edit_personal_easy_gantt: Easy Gantt(個別)とリソース・マネージメントを編集
+ permission_view_easy_gantt: プロジェクトのEasy Ganttとリソース・マネージメントを閲覧
+ permission_view_global_easy_gantt: Easy Ganttチャート(全体)とリソース・マネージメントを閲覧
+ permission_view_personal_easy_gantt: Easy Ganttチャート(個別)とリソース・マネージメントを閲覧
+ project_default_page:
+ easy_gantt: Easy Gantt
+ project_module_easy_gantt: Easy Gantt
+ text_demo_feature_popup: 本機能はもうじき利用可能になります
+ text_easy_gantt_fixed_delay: ドラッグバック作業中、タスク間ラグタイムは変わりません
+ text_easy_gantt_footer: Easyにより運営されるRedmine Gantt
+ text_easy_gantt_keep_link_delay_in_drag: タスクがドラッグされてもタスク間の日程は維持
+ text_easy_gantt_print_easy_gantt_current: 現在のEasy Gantt を表示する(Easy Gantt が読み込まれたページからのみ可能です)
+ text_easy_gantt_relation_delay_in_workdays: リレーション遅延による非稼働日をカウントしない
+ text_easy_gantt_show_holidays: ユーザーの休日をGanttに表示する(Easy Redmineでのみ有効)
+ text_easy_gantt_show_project_progress: プロジェクトバー上に進捗率を表示する(読み込み速度が遅い可能性があり)
+ text_easy_gantt_show_task_soonest_start: 親タスク、またはリレーションから規定されるもっとも妥当性の低い日程を表示
+ title_easy_gantt_settings: Easy Gantt
diff --git a/plugins/easy_gantt/config/locales/ko.yml b/plugins/easy_gantt/config/locales/ko.yml
new file mode 100644
index 0000000..be786aa
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/ko.yml
@@ -0,0 +1,143 @@
+---
+ko:
+ button_print: 프린트
+ button_project_menu_easy_gantt: 쉬운 간트
+ button_top_menu_easy_gantt: 프로젝트 간트
+ button_use_actual_delay: 실제 지연일 사용
+ easy_gantt:
+ button:
+ close_all: 모두 닫기
+ close_all_parent_issues: 모든 상위작업 닫기
+ create_baseline: 베이스라인
+ critical_path: 중요한 경로
+ day_zoom: 일
+ delayed_project_filter: 지연된 프로젝트 필터
+ jump_today: 오늘로 이동하기
+ load_sample_data: 샘플 데이터 로딩
+ month_zoom: 월
+ print_fit: 페이지에 맞추기
+ problem_finder: 문제
+ reload: 다시 불러오기 (저장)
+ remove_delay: 지연 삭제
+ resource_management: 리소스 관리
+ tool_panel: 도구
+ week_zoom: 주
+ critical_path:
+ disabled: 비활성화
+ last: 지난
+ last_text: 지연되서는 안되는 작업들
+ longest: 가장 긴
+ longest_text: 가장 긴 작업 보이기
+ errors:
+ duplicate_link: 복제된 링크를 생성할 수 없습니다
+ fresh_milestone: 저장되지 않은 마일스톤에 작업을 추가 할 수 없습니다. 먼저 마일스톤을 저장하십시오.
+ link_target_new: 저장되지 않은 작업에 대한 링크를 만들 수 없습니다. 변경 사항을 먼저 저장하십시오.
+ link_target_readonly: 읽기전용 타겟 작업
+ loop_link: 루프된 링크를 생성할 수 없음
+ no_rest_api: Easy Gantt는 REST API를 활성화해야합니다. 관리 -> 설정 -> API -> REST 웹 서비스 순서로
+ 활성화 하세요.
+ overdue: 이후에 종료하고 이미 종료했어야 합니다
+ overmile: 마일스톤을 유지하려면 %{effective_date}에 작업을 끝내야합니다.
+ short_delay: "%{diff}보다 길어야 합니다"
+ too_short: 예상 시간의 %{rest} 시간 동안 충분한 일 수가 없습니다.
+ unsaved_parent: 저장되지 ㅇ낳은 상위 작업을 작업에 추가할 수 없습니다. 변경사항을 먼저 저장하세요
+ unsupported_link_type: 지원하지 않는 링크 종류
+ gateway:
+ entity_save_failed: "%{entityType} %{entityName}는 에러로 인해 저장하지 못했습니다"
+ send_failed: 요청 반려됨
+ label_pro_upgrade: PRO버전으로 업그레이드하기
+ link_dir:
+ link_end: 진행하는 동안
+ link_start: 다음과 같이
+ popup:
+ add_task:
+ heading: 작업 특성 추가
+ text: 새로운 작업 / 마일스톤 기능은 Easy Gantt PRO에서만 사용할 수 있습니다.
+ 업데이트를 확인하세요!
+ baseline:
+ heading: 베이스라인 특징
+ text: 베이스 라인 기능은 Easy Gantt PRO에서만 사용할 수 있습니다.
+ 업데이트를 확인하세요!
+ critical:
+ heading: 중요한 경로 특징
+ text: 중요 경로 기능은 Easy Gantt PRO에서만 사용할 수 있습니다.
+ 업데이트를 확인하세요!
+ resource:
+ heading: 리소스 관리 특징
+ text: 리소스 관리 기능은
Easy Redmine 에서
+ 사용하실 수 있습니다
+ reload_modal:
+ label_errors: 에러
+ text_reload_appeal: 저장하지 않은 항목을 무시하고 서버에서 데이터를 다시 불러올까요?
+ title: 간트는 올바르게 저장할 수 없습니다
+ sample_global_free:
+ text: 샘플 데이터를 닫을 수 없습니다. 모든 프로젝트의 Gantt는 PRO 버전에서만 사용이 가능합니다.
+ video:
+ text: 여기서 모든 프로젝트에 대해 Gantt의 대부분 기능을 볼 수 있습니다.
+ title: 모든 프로젝트에 관한 간트 비디오 샘플
+ video_id: EiiqBrrY4m4
+ sample:
+ close_label: 이 창을 닫고 실제 프로젝트 데이터 불러오기
+ header: 샘플데이터가 로딩되었습니다!
+ text: "
스트레스 받지 않고 모든 Easy Gantt 기능을 사용해보세요 strong>를 위한 샘플 데이터가 준비되어
+ 있습니다. 또한 유용한 조정을 보여주는 비디오 가이드를 보는 것을 추천하여 드립니다. 이 창을 닫으면 실제 프로젝트 데이터가 로딩됩니다."
+ video_label: 비디오 튜토리얼 보기
+ video:
+ text: 이 간트 모듈의 가장 최근 기능들을 확인하실 수 있습니다
+ title: 샘플 비디오
+ video_id: UHgqfsrD59Q
+ text_blocker_milestone: 마일스톤이 날짜 이후에 작업을 하지 못하도록 차단하게 되어 있습니다
+ text_blocker_move_pre: 작업이날짜 이후에 작업을 이동하지 못하도록 차단하는 상태로 있습니다.
+ title:
+ button_test: 테스트 버튼 (테스트용)
+ day_zoom: 요일별 확대
+ jump_today: 금일 타임라인 보기
+ month_zoom: 월별로 확대
+ print_fit: 간트 차트 한 페이지로 보이기
+ week_zoom: 주별로 확대
+ easy_printable_templates_categories:
+ easy_gantt: 쉬운 간트
+ easy_query:
+ name:
+ easy_gantt_easy_issue_query: 쉬운 간트
+ easy_gantt_easy_project_query: 글로벌 Easy Gantt
+ error_easy_gantt_view_permission: 이지간트 보기 권한을 가지고 있지 않습니다.
+ error_epm_easy_gantt_already_active: 페이지의 Easy Gantt는 이미 활성화 되어 있습니다
+ field_easy_gantt_default_zoom: 영구설정 확대
+ field_easy_gantt_relation_delay_in_workdays: 작업 날짜에서 관련 지연일
+ field_easy_gantt_show_holidays: 휴일 보이기
+ field_easy_gantt_show_project_progress: 프로젝트 과정 보이기
+ field_easy_gantt_show_task_soonest_start: 가장 빨리 시작하는 것 보이기
+ field_keep_link_delay_in_drag: 드래그 동안 지속적인 링크 지연
+ field_relation: 관련
+ heading_delay_popup: 지연 날짜 설정
+ heading_demo_feature_popup: 곧 출시됩니다
+ heading_easy_gantts_issues: 무료 쉬운 간트
+ label_easy_gantt: 쉬운 간트
+ label_easy_gantt_critical_path: 중요한 경로
+ label_easy_gantt_settings: 간트 설정
+ label_filter_group_easy_gantt_easy_issue_query: 작업 필드
+ label_finish_to_finish: 종료하기 종료
+ label_parent_issue_plural: 상위 작업
+ label_start_to_finish: 종료하기 시작
+ label_start_to_start: 시작하기 시작
+ link_easy_gantt_plugin: https://www.easyredmine.com/easy-gantt-upgrade-to-pro
+ permission_edit_easy_gantt: 쉬운 간트 수정 & 프로젝트 리소스 관리
+ permission_edit_global_easy_gantt: 글로벌 쉬운 간트 수정 & 리소스 관리
+ permission_edit_personal_easy_gantt: 개별 쉬운 간트 수정 & 리소스 관리
+ permission_view_easy_gantt: 쉬운 간트 확인 & 프로젝트 리소스 관리
+ permission_view_global_easy_gantt: 글로벌 쉬운 간트 보기 & 리소스 관리
+ permission_view_personal_easy_gantt: 개별 쉬운 간트 확인 & 리소스 관리
+ project_default_page:
+ easy_gantt: 쉬운 간트
+ project_module_easy_gantt: 쉬운 간트
+ text_demo_feature_popup: 이 기능은 곧 사용가능합니다.
+ text_easy_gantt_footer: Easy가 지원하는 Redmine Gantt
+ text_easy_gantt_keep_link_delay_in_drag: 작업이 지연되는 동안 연장시간을 일관적으로 유지하십시오
+ text_easy_gantt_print_easy_gantt_current: 현재 쉬운 간트 표 보기 (쉬운 간트가 표시된 페이지에만 작업하실 수
+ 있습니다)
+ text_easy_gantt_relation_delay_in_workdays: 관련 지연에서 일하지 않은 날은 세지 않기
+ text_easy_gantt_show_holidays: 간트에 있는 현재 사용자 휴일 보기 (Easy Redmine에서만 확인할 수 있습니다)
+ text_easy_gantt_show_project_progress: 프로젝트 바에서 완료율 보기 (로딩하는데 시간이 걸릴 수 있습니다)
+ text_easy_gantt_show_task_soonest_start: 관련 혹은 상위그룹으로 정렬된 작업의 가장 적은 유효날짜 표시
+ title_easy_gantt_settings: 쉬운 간트
diff --git a/plugins/easy_gantt/config/locales/mk.yml b/plugins/easy_gantt/config/locales/mk.yml
new file mode 100644
index 0000000..0ae1092
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/mk.yml
@@ -0,0 +1,2 @@
+---
+mk:
diff --git a/plugins/easy_gantt/config/locales/nl.yml b/plugins/easy_gantt/config/locales/nl.yml
new file mode 100644
index 0000000..dbb7b65
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/nl.yml
@@ -0,0 +1,159 @@
+---
+nl:
+ button_print: Afdrukken
+ button_project_menu_easy_gantt: Easy Gantt
+ button_top_menu_easy_gantt: Projecten Gantt
+ button_use_actual_delay: Gebruik actuele vertraging
+ easy_gantt:
+ button:
+ close_all: Sluit alle
+ close_all_parent_issues: Sluit alle overkoepelende taken
+ create_baseline: Baselines
+ critical_path: Kritiek pad
+ day_zoom: Dagen
+ delayed_project_filter: Filter Vertraagde Projecten
+ jump_today: Ga naar vandaag
+ load_sample_data: Laad sample gegevens
+ month_zoom: Maanden
+ print_fit: Aangepast aan pagina
+ problem_finder: Problemen
+ reload: Herladen (opslaan)
+ remove_delay: Verwijder vertraging
+ resource_management: Resource management
+ tool_panel: Tools
+ week_zoom: Weken
+ critical_path:
+ disabled: Uitgeschakeld
+ last: Laatste
+ last_text: Taken die niet vertraagd mogen worden
+ longest: Langste
+ longest_text: Toon langste sequentie taken
+ errors:
+ duplicate_link: Kan link niet dupliceren
+ fresh_milestone: Kan geen taak toevoegen aan niet-opgeslagen mijlpaal. Sla eerst
+ de mijlpaal op.
+ link_target_new: Kan geen link maken naar niet-opgeslagen taak. Sla eerst de
+ wijzigingen op.
+ link_target_readonly: Alleen lezen doeltaak
+ loop_link: Kan geloopte link niet aanmaken
+ no_rest_api: Voor Easy Gantt moet REST API ingeschakeld zijn. Zet het aan bij Administratie
+ -> Instellingen -> API -> REST web service inschakelen
+ overdue: zou in de toekomst moeten eindigen of al gesloten moeten zijn
+ overmile: moet eindigen op %{effective_date} om mijlpaal te houden
+ short_delay: Moet %{diff} dagen langer zijn
+ too_short: bevat niet genoeg dagen voor %{rest} uren geschatte tijd
+ unsaved_parent: Kan geen taak toevoegen aan niet opgeslagen overkoepeling. Sla
+ de wijzigingen eerst op.
+ unsupported_link_type: Niet ondersteund type link
+ gateway:
+ entity_save_failed: "%{entityType} %{entityName} niet opgeslagen door fout"
+ send_failed: Verzoek mislukt
+ label_pro_upgrade: Upgraden naar PRO versie
+ link_dir:
+ link_end: als voorgaande
+ link_start: als volgt
+ popup:
+ add_task:
+ heading: Voeg eigenschap taak toe
+ text: "Nieuwe taak/mijlpaal eigenschap is alleen beschikbaar in Easy Gantt
+ PRO \r\nControleer
+ voor een update! "
+ baseline:
+ heading: Baselines functie
+ text: "De Baselines functie is alleen beschikbaar in Easy Gantt PRO \r\nControleer
+ voor een update! "
+ critical:
+ heading: Kritiek pad functie
+ text: "Kritiek pad functie is alleen beschikbaar in Easy Gantt PRO \r\nKijk hier
+ voor een update! "
+ resource:
+ heading: Resource manager functie
+ text: Resource management functie is alleen beschikbaar in
+ Easy Redmine
+ reload_modal:
+ label_errors: Fouten
+ text_reload_appeal: Wilt u niet opgeslagen items negeren en data opnieuw laden
+ van de server?
+ title: Gantt niet juist opgeslagen
+ sample_global_free:
+ text: Sample data kunnen niet gesloten worden. Gantt over alle projecten is
+ alleen beschikbaar in de PRO versie
+ video:
+ text: Hier zie je de meeste functies van Gantt in alle projecten
+ title: Sample video van Gantt over alle projecten
+ video_id: EiiqBrrY4m4
+ sample:
+ close_label: Sluit dit venster en laad echte projectgegevens
+ header: Sample data zijn geladen!
+ text: We hebben wat sample gegevens voorbereid om alle Easy Gantt functies
+ stress-vrij te proberen . We adviseren ook om een video met wat nuttige
+ tips te bekijken. Het sluiten van dit venster laadt echte project gegevens.
+ video_label: Bekijk video tutorial
+ video:
+ text: Hier ziet u de meeste functies van de Gantt module
+ title: Sample video
+ video_id: UHgqfsrD59Q
+ text_blocker_milestone: Mijlpaal blokkeert taak om verplaatst te worden na deze
+ datum
+ text_blocker_move_pre: Taak heeft een relatie die het verschuiven van deze taak
+ na deze datum blokkeert
+ title:
+ button_test: Test button (alleen voor testen)
+ day_zoom: Zoom naar dagweergave
+ jump_today: Geef tijdlijn voor vandaag weer
+ month_zoom: Zoom naar maandelijkse weergave
+ print_fit: Schaal gantt tot een pagina
+ week_zoom: Zoom naar wekelijkse weergave
+ easy_printable_templates_categories:
+ easy_gantt: Easy Gantt
+ easy_query:
+ name:
+ easy_gantt_easy_issue_query: Easy Gantt
+ easy_gantt_easy_project_query: Global Easy Gantt
+ error_easy_gantt_view_permission: U heeft geen toestemming om Easy Gantt te bekijken
+ error_epm_easy_gantt_already_active: Easy gantt is al actief op de pagina
+ field_easy_gantt_default_zoom: Standaard zoom
+ field_easy_gantt_relation_delay_in_workdays: Relatie vertragingen in werkdagen
+ field_easy_gantt_show_holidays: Toon vakanties
+ field_easy_gantt_show_project_progress: Toon projectvoortgang
+ field_easy_gantt_show_task_soonest_start: Toon eerste start
+ field_keep_link_delay_in_drag: Constante link vertraging tijdens slepen
+ field_relation: Relatie
+ heading_delay_popup: Definieer vertraging in dagen
+ heading_demo_feature_popup: Binnenkort
+ heading_easy_gantts_issues: Easy Gantt Gratis
+ label_easy_gantt: Easy Gantt
+ label_easy_gantt_critical_path: Kritiek pad
+ label_easy_gantt_settings: Gantt instellingen
+ label_filter_group_easy_gantt_easy_issue_query: Taken velden
+ label_finish_to_finish: Finish om af te ronden
+ label_parent_issue_plural: Ouder kwesties
+ label_start_to_finish: Start tot finish
+ label_start_to_start: Start om te beginnen
+ link_easy_gantt_plugin: https://www.easyredmine.com/easy-gantt-upgrade-naar-pro
+ permission_edit_easy_gantt: Bewerk Easy Gantt & Resource management op een project
+ permission_edit_global_easy_gantt: Bewerk globaal Easy Gantt & Resource management
+ permission_edit_personal_easy_gantt: Bewerk persoonlijk Easy Gantt & Resource management
+ permission_view_easy_gantt: Bekijk Easy Gantt & Resource management op een project
+ permission_view_global_easy_gantt: Bekijk globaal Easy Gantt & Resource management
+ permission_view_personal_easy_gantt: Bekijk persoonlijk Easy Gantt & Resource management
+ project_default_page:
+ easy_gantt: Easy Gantt
+ project_module_easy_gantt: Easy Gantt
+ text_demo_feature_popup: Deze functie is binnenkort beschikbaar
+ text_easy_gantt_footer: Redmine Gantt mogelijk gemaakt door Easy
+ text_easy_gantt_keep_link_delay_in_drag: Hou relatievertraging constant terwijl
+ taak teruggedraaid wordt
+ text_easy_gantt_print_easy_gantt_current: Toon huidige Easy Gantt (werkt alleen
+ op pagina's waar easy gantt is geladen)
+ text_easy_gantt_relation_delay_in_workdays: Tel niet-werkdagen niet mee in relatie
+ vertraging
+ text_easy_gantt_show_holidays: Toon vakantie van huidige gebruiker op gantt (werkt
+ alleen in Easy Redmine)
+ text_easy_gantt_show_project_progress: Bekijk voortgangspercentage op de balk van
+ het project (laadt wellicht langzaam)
+ text_easy_gantt_show_task_soonest_start: Toon laagst geldige data voor taken gedefinieerd
+ door relaties of ouder
+ title_easy_gantt_settings: Easy Gantt
diff --git a/plugins/easy_gantt/config/locales/no.yml b/plugins/easy_gantt/config/locales/no.yml
new file mode 100644
index 0000000..38901c6
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/no.yml
@@ -0,0 +1,2 @@
+---
+'no':
diff --git a/plugins/easy_gantt/config/locales/pl.yml b/plugins/easy_gantt/config/locales/pl.yml
new file mode 100644
index 0000000..b53e1ce
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/pl.yml
@@ -0,0 +1,160 @@
+---
+pl:
+ button_print: Drukuj
+ button_project_menu_easy_gantt: Easy Gantt
+ button_top_menu_easy_gantt: Projekty Gantt
+ button_use_actual_delay: Użyj aktualnego opóźnienia
+ easy_gantt:
+ button:
+ close_all: Zamknij wszystko
+ close_all_parent_issues: Zamknij wszystkie zadania nadrzędne
+ create_baseline: Bazy
+ critical_path: Ścieżka krytyczna
+ day_zoom: Dni
+ delayed_project_filter: Filtruj opóźnione projekty
+ jump_today: Skok do dzisiaj
+ load_sample_data: Załaduj proste dane
+ month_zoom: Miesiące
+ print_fit: Dopasuj do strony
+ problem_finder: Problemy
+ reload: Przeładuj (zapisz)
+ remove_delay: Usuń opóźnienie
+ resource_management: Zarządzanie zasobami
+ tool_panel: Narzędzia
+ week_zoom: Tygodnie
+ critical_path:
+ disabled: Wyłączony
+ last: Ostatni
+ last_text: Zadania, które nie powinny być opóźnione
+ longest: Najdłuższy
+ longest_text: Pokaż najdłuższą sekwencję zadań
+ errors:
+ duplicate_link: Nie można utworzyć zduplikowanego linku
+ fresh_milestone: Nie można dodać zadania do niezapisanych kroków milowych. Najpierw
+ zapisz krok milowy.
+ link_target_new: Nie można utworzyć linku do niezapisanego zadania. Najpierw
+ zapisz zmiany.
+ link_target_readonly: Docelowe zadanie jedynie do odczytu
+ loop_link: Nie można utworzyć zapętlonego linku
+ no_rest_api: Easy Gantt potrzebuje włączonego API REST. Włącz go w Administracja
+ -> Ustawienia -> API -> Włącz usługę sieciową REST
+ overdue: powinno się zakończyć w przyszłości lub być już zamknięte
+ overmile: powinno zakończyć się %{effective_date}, aby zachować krok milowy
+ short_delay: powinno być dłuższe niż %{diff} dni
+ too_short: nie zawiera wystarczającej liczby dni dla %{rest} godzin oszacowanego
+ czasu
+ unsaved_parent: Nie można dodać zadania do niezapisanego zadania nadrzędnego.
+ Najpierw zapisz zmiany
+ unsupported_link_type: Nieobsługiwany typ linku
+ gateway:
+ entity_save_failed: Nie powiodło się zapisanie %{entityType} %{entityName} z
+ powodu błędu
+ send_failed: Wymagane pole
+ label_pro_upgrade: Zaktualizuj do wersji PRO
+ link_dir:
+ link_end: jak poprzedni
+ link_start: jak następujący
+ popup:
+ add_task:
+ heading: Dodaj funkcję zadania
+ text: "Funkcja nowego zadania/kroku milowego jest dostępna jedynie w Easy
+ Gantt PRO \r\nSprawdź
+ aktualizację! "
+ baseline:
+ heading: Funkcja baz
+ text: "Funkcja baz jest dostępna jedynie w Easy Gantt PRO \r\nSprawdź
+ aktualizację! "
+ critical:
+ heading: Funkcja ścieżki krytycznej
+ text: "Funkcja ścieżki krytycznej jest dostępna jedynie w Easy Gantt PRO \r\nSprawdź aktualizację! "
+ resource:
+ heading: Funkcja menedżera zasobów
+ text: Funkcja ścieżki krytycznej jest dostępna jedynie w
+ Easy Redmine
+ reload_modal:
+ label_errors: Błędy
+ text_reload_appeal: Czy chcesz zignorować niezapisane pozycje i ponownie załadować
+ dane z serwera?
+ title: Poprawne zapisanie Gantta nie powiodło się
+ sample_global_free:
+ text: Przykładowe dane nie mogą zostać zamknięte. Gantt w stosunku do innych
+ projektów jest dostępny jedynie w wersji PRO
+ video:
+ text: Tutaj możesz zobaczyć większość funkcji Gantta w stosunku do wszystkich
+ projektów
+ title: Przykładowe wideo Gantta w stosunku do wszystkich projektów
+ video_id: EiiqBrrY4m4
+ sample:
+ close_label: Zamknij to okno i załaduj prawdziwe dane projektowe
+ header: Przykładowe dane są załadowane!
+ text: Przygotowaliśmy dla ciebie pewne przykładowe dane w celu wypróbowania
+ wszystkich funkcji Easy Gantt bez stresu .
+ video_label: Zobacz samouczek filmowy
+ video:
+ text: Tutaj możesz zobaczyć większość funkcji tego modułu Gantta
+ title: Przykładowy film
+ video_id: UHgqfsrD59Q
+ text_blocker_milestone: Krok milowy blokuje przeniesienie zadania poza tę datę
+ text_blocker_move_pre: Zadanie posiada relację, która blokuje przesunięcie go
+ poza tę datę
+ title:
+ button_test: Przycisk testowy (tylko dla testowania)
+ day_zoom: Powiększ do skali dni
+ jump_today: Wyświetl linię czasu dla dzisiaj
+ month_zoom: Powiększ do skali miesiąca
+ print_fit: Skaluj Gantta na jedną stronę
+ week_zoom: Powiększ do skali tygodnia
+ easy_printable_templates_categories:
+ easy_gantt: Easy Gantt
+ easy_query:
+ name:
+ easy_gantt_easy_issue_query: Easy Gantt
+ easy_gantt_easy_project_query: Globalny Easy Gantt
+ error_easy_gantt_view_permission: Nie masz uprawnień do zobaczenia Easy Gantt
+ error_epm_easy_gantt_already_active: Easy Gantt jest już aktywny na stronie
+ field_easy_gantt_default_zoom: Domyślne powiększenie
+ field_easy_gantt_relation_delay_in_workdays: Opóźnienie relacji w dniach roboczych
+ field_easy_gantt_show_holidays: Pokaż urlopy
+ field_easy_gantt_show_project_progress: Pokaż postęp projektu
+ field_easy_gantt_show_task_soonest_start: Pokaż najwcześniejsze rozpoczęcie
+ field_keep_link_delay_in_drag: Stałe opóźnienie linku podczas przeciągania
+ field_relation: Relacja
+ heading_delay_popup: Określ opóźnienie w dniach
+ heading_demo_feature_popup: Wkrótce
+ heading_easy_gantts_issues: Bezpłatny Easy Gantt
+ label_easy_gantt: Easy Gantt
+ label_easy_gantt_critical_path: Ścieżka krytyczna
+ label_easy_gantt_settings: Ustawienia Gantta
+ label_filter_group_easy_gantt_easy_issue_query: Pole zadania
+ label_finish_to_finish: Zakończ aby zakończyć
+ label_parent_issue_plural: Zadania nadrzędne
+ label_start_to_finish: Rozpocznij aby zakończyć
+ label_start_to_start: Zacznij aby zacząć
+ link_easy_gantt_plugin: https://www.easyredmine.com/easy-gantt-upgrade-to-pro
+ permission_edit_easy_gantt: Edytuj Easy Gantt i Zarządzanie zasobami w projekcie
+ permission_edit_global_easy_gantt: Edytuj globalne Easy Gantt i Zarządzanie zasobami
+ permission_edit_personal_easy_gantt: Edytuj personalne Easy Gantt i Zarządzanie
+ zasobami
+ permission_view_easy_gantt: Zobacz Easy Gantt i Zarządzanie zasobami w projekcie
+ permission_view_global_easy_gantt: Zobacz globalne Easy Gantt i Zarządzanie zasobami
+ permission_view_personal_easy_gantt: Zobacz personalne Easy Gantt i Zarządzanie
+ zasobami
+ project_default_page:
+ easy_gantt: Easy Gantt
+ project_module_easy_gantt: Easy Gantt
+ text_demo_feature_popup: Ta funkcja będzie dostępna wkrótce.
+ text_easy_gantt_footer: Redmine Gantt powered by Easy
+ text_easy_gantt_keep_link_delay_in_drag: Utrzymaj stałe opóźnienie relacji gdy zadanie
+ jest przeciągane z powrotem
+ text_easy_gantt_print_easy_gantt_current: Pokaż obecny Easy Gantt (działa tylko
+ na stronie, na której jest załadowany Easy Gantt)
+ text_easy_gantt_relation_delay_in_workdays: Nie bierz pod uwagę nieroboczych dni
+ w opóźnieniu relacji
+ text_easy_gantt_show_holidays: Pokaż urlop obecnego użytkownika na Gantt (działa
+ jedynie w Easy Redmine)
+ text_easy_gantt_show_project_progress: Pokaż zakończony procent na pasku projektu
+ (pobranie może być wolne)
+ text_easy_gantt_show_task_soonest_start: Pokaż najbliższe ważne daty dla zadań określonych
+ przez relacje lub zadanie nadrzędne
+ title_easy_gantt_settings: Easy Gantt
diff --git a/plugins/easy_gantt/config/locales/pt-BR.yml b/plugins/easy_gantt/config/locales/pt-BR.yml
new file mode 100644
index 0000000..79d7105
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/pt-BR.yml
@@ -0,0 +1,161 @@
+---
+pt-BR:
+ button_print: Imprimir
+ button_project_menu_easy_gantt: Diagrama de Easy Gantt
+ button_top_menu_easy_gantt: Projetos diagrama de Gantt
+ button_use_actual_delay: Use atraso real
+ easy_gantt:
+ button:
+ close_all: Fechar todos
+ close_all_parent_issues: Fechar todas tarefas principais
+ create_baseline: Linhas de base
+ critical_path: Trajeto crítico
+ day_zoom: Dias
+ delayed_project_filter: Filtrar Projetos Adiados
+ jump_today: Saltar para hoje
+ load_sample_data: Carregar dados de amostra
+ month_zoom: Meses
+ print_fit: Ajustar à página
+ problem_finder: Problemas
+ reload: Recarregar (salvar)
+ remove_delay: Retirar atraso
+ resource_management: Gestão de recursos
+ tool_panel: Ferramentas
+ week_zoom: Semanas
+ critical_path:
+ disabled: Desativado
+ last: Último
+ last_text: Tarefas que não devem ser adiada
+ longest: Mais longo
+ longest_text: Mostrar sequência mais longa
+ errors:
+ duplicate_link: Não é possível duplicar link
+ fresh_milestone: Não é possível adicionar tarefa a marcos não-salvos. Primeiro
+ salve o marco.
+ link_target_new: Não é possível criar tarefas não salvas. Salve as mudanças
+ primeiro.
+ link_target_readonly: Tarefa alvo somente para leitura
+ loop_link: Não é possível criar link em repetição
+ no_rest_api: Diagrama de Easy Gantt precisa de REST API ativado. Ligar em Administração
+ ->Configurações -> API -> Habilitar serviço web REST
+ overdue: deve terminar no futuro ou já deve estar fechado
+ overmile: Deve terminar em %{effective_date} a fim de manter o marco
+ short_delay: deve ser mais longo que %{diff} dias
+ too_short: Não contém suficiente dias para %{rest} horas de tempo estimado
+ unsaved_parent: Não é possível adicionar tarefa ao principal não-salvos. Primeiro
+ salvar as alterações.
+ unsupported_link_type: Tipo de link não assistido
+ gateway:
+ entity_save_failed: "%{entityType} %{entityName} falha ao salvar devido a erro"
+ send_failed: Falha na solicitação
+ label_pro_upgrade: Atualizar para a versão PRO
+ link_dir:
+ link_end: como precedendo
+ link_start: como a seguir
+ popup:
+ add_task:
+ heading: Adicionar recurso tarefa
+ text: Novo recurso tarefa/marco está disponível apenas em Easy Gantt PRO Check for update!
+ baseline:
+ heading: Caracteristica de linhas de base
+ text: Caracteristica de linhas de base está disponível em Easy Gantt PRO Verifique se
+ há atualização!
+ critical:
+ heading: Caracteristica de trajeto crítico
+ text: Recurso de trajeto crítico somente está disponível em Easy Gantt PRO
+ Verificar
+ se há atualização!
+ resource:
+ heading: Recurso gerente de recursos
+ text: Recurso gerente de recursos só está disponível em
+ Easy Redmine
+ reload_modal:
+ label_errors: Erros
+ text_reload_appeal: Você quer ignorar itens que não foram salvos e recarregar
+ os dados do servidor?
+ title: Gantt não salvou corretamente
+ sample_global_free:
+ text: Dados de amostra não podem ser fechados. Projetos gerais Gantt só estão
+ disponíveis na versão PRO
+ video:
+ text: Aqui você pode ver a maioria das características de projetos gerais
+ Gantt
+ title: Video de amostra de projetos gerais Gantt
+ video_id: EiiqBrrY4m4
+ sample:
+ close_label: Fechar a janela e carregar os dados reais de projeto
+ header: Os dados da amostra estão carregados!
+ text: Nós preparamos alguns exemplos de dados para você experimentar
+ todos os recursos Easy Gantt sem estresse . Nós também queremos encorajá-lo
+ a assistir a um vídeo gia mostrando ajustes úteis. Ao fechar esta janela irá
+ carregar os dados de projeto real.
+ video_label: Assistir video tutorial
+ video:
+ text: Aqui você pode ver a maioria das funcionalidades deste módulo Gantt
+ title: Video exemplo
+ video_id: UHgqfsrD59Q
+ text_blocker_milestone: Marco está bloqueando tarefa a ser deslocado para além
+ desta data
+ text_blocker_move_pre: Tarefa tem relação que bloqueia mover tarefa para além
+ desta data
+ title:
+ button_test: Botão de teste (somente para teste)
+ day_zoom: Aumentar a escala de dia
+ jump_today: Exibir linha do tempo em hoje
+ month_zoom: Fazer zoom a escala mês
+ print_fit: Escale o Gantt para uma página
+ week_zoom: Fazer zoom a escala semana
+ easy_printable_templates_categories:
+ easy_gantt: Easy Gantt
+ easy_query:
+ name:
+ easy_gantt_easy_issue_query: Easy Gantt
+ easy_gantt_easy_project_query: Easy Gantt Global
+ error_easy_gantt_view_permission: Você não tem permissão para visualizar o Easy
+ Gantt
+ error_epm_easy_gantt_already_active: Easy Gantt na página já está ativado.
+ field_easy_gantt_default_zoom: Padrão de zoom
+ field_easy_gantt_relation_delay_in_workdays: Relação atrasos nos dias úteis
+ field_easy_gantt_show_holidays: Mostrar férias
+ field_easy_gantt_show_project_progress: Mostrar progresso do projeto
+ field_easy_gantt_show_task_soonest_start: Mostrar início mais breve
+ field_keep_link_delay_in_drag: Constante atraso de conexão durante o arrasto
+ field_relation: Relação
+ heading_delay_popup: Definir atraso em dias
+ heading_demo_feature_popup: Em breve
+ heading_easy_gantts_issues: Easy Gantt grátis
+ label_easy_gantt: Easy Gantt
+ label_easy_gantt_critical_path: Trajeto crítico
+ label_easy_gantt_settings: Configurações Gantt
+ label_filter_group_easy_gantt_easy_issue_query: Campos de tarefas
+ label_finish_to_finish: Final ao final
+ label_parent_issue_plural: Problemas principais
+ label_start_to_finish: Início ao final
+ label_start_to_start: Início ao início
+ link_easy_gantt_plugin: https://www.easyredmine.com/easy-gantt-upgrade-to-pro
+ permission_edit_easy_gantt: Editar Easy Gantt & Gestão de recursos em um projeto
+ permission_edit_global_easy_gantt: Editar Easy Gantt & Gestão de recursos
+ permission_edit_personal_easy_gantt: Editar Easy Gant pessoal & Gestão de recursos
+ permission_view_easy_gantt: Visualizar Easy Gantt & Gestão de recursos em um projeto
+ permission_view_global_easy_gantt: Visualizar Easy Gantt global & Gestão de recursos
+ permission_view_personal_easy_gantt: Visualizar Easy Gant geral & Gestão de recursos
+ project_default_page:
+ easy_gantt: Easy Gantt
+ project_module_easy_gantt: Easy Gantt
+ text_demo_feature_popup: Esta funcionalidade estará disponível em breve.
+ text_easy_gantt_footer: Redmine Gantt distribuído por Easy
+ text_easy_gantt_keep_link_delay_in_drag: Manter atraso de relação constante enquanto
+ a tarefa é arrastado de volta
+ text_easy_gantt_print_easy_gantt_current: Mostrar Easy Gantt atual (somente funciona
+ a partir da página onde o Easy Gantt for carregado)
+ text_easy_gantt_relation_delay_in_workdays: Não contar os dias não úteis em relação
+ ao atraso
+ text_easy_gantt_show_holidays: Mostrar férias atuais de usuário em Gantt (funciona
+ em Easy Redmine)
+ text_easy_gantt_show_project_progress: Mostrar porcentagem completa na barra do
+ projeto (pode ser lento para carregar)
+ text_easy_gantt_show_task_soonest_start: Mostrar datas válidas mais baixas para
+ as tarefas definidas por equações ou principal
+ title_easy_gantt_settings: Easy Gantt
diff --git a/plugins/easy_gantt/config/locales/pt.yml b/plugins/easy_gantt/config/locales/pt.yml
new file mode 100644
index 0000000..e40c485
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/pt.yml
@@ -0,0 +1,2 @@
+---
+pt:
diff --git a/plugins/easy_gantt/config/locales/ro.yml b/plugins/easy_gantt/config/locales/ro.yml
new file mode 100644
index 0000000..583d9e1
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/ro.yml
@@ -0,0 +1,19 @@
+---
+ro:
+ button_print: Imprimare
+ button_project_menu_easy_gantt: Gantt Simplu
+ button_top_menu_easy_gantt: Proiecte Gantt
+ easy_gantt:
+ button:
+ close_all_parent_issues: Închide toate sarcinile sursă
+ day_zoom: Zile
+ jump_today: Sari la azi
+ month_zoom: Luni
+ reload: Reincarca (salveaza)
+ tool_panel: Instrumente
+ week_zoom: Săptămani
+ field_easy_gantt_default_zoom: Zoom implicit
+ field_easy_gantt_show_holidays: Arată vacanţe
+ field_easy_gantt_show_project_progress: Arată progresul proiectului
+ field_relation: Relaţie
+ label_easy_gantt: Gantt Simplu
diff --git a/plugins/easy_gantt/config/locales/ru.yml b/plugins/easy_gantt/config/locales/ru.yml
new file mode 100644
index 0000000..35ced1e
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/ru.yml
@@ -0,0 +1,185 @@
+---
+ru:
+ button_print: Печать
+ button_project_menu_easy_gantt: Диаграмма Ганта Easy
+ button_top_menu_easy_gantt: Диаграмма Ганта
+ button_use_actual_delay: Использовать фактическую задержку
+ easy_gantt_toolbar:
+ day: Дни
+ month: Месяцы
+ week: Недели
+ easy_gantt:
+ buton_create_baseline: Базовый план
+ button_critical_path: Критический путь
+ button_resource_management: Управление персоналом
+ button:
+ close_all: Закрыть все
+ close_all_parent_issues: Закрыть все родительские задачи
+ create_baseline: Базовый план
+ critical_path: Критический путь
+ day_zoom: Дни
+ delayed_project_filter: Фильтр Просроченные Проекты
+ jump_today: Сегодня
+ load_sample_data: Загрузить демо-данные
+ month_zoom: Месяцы
+ print_fit: Подогнать
+ problem_finder: Ошибки
+ reload: Перезагрузить (сохранить)
+ remove_delay: Удалить задержку
+ resource_management: Управление персоналом
+ tool_panel: Инструменты
+ week_zoom: Недели
+ critical_path:
+ disabled: Отключен
+ last: Короткий
+ last_text: Первоочередные задачи
+ longest: Длинный
+ longest_text: Самая длинная последовательность задач
+ error_overmile: Дата выполнения задачи должна находиться до даты Вехи (Версии)
+ error_too_short: Залача слишком короткая для рассчета запланированного времени
+ errors:
+ duplicate_link: Нельзя создать двойную ссылку
+ fresh_milestone: Нельзя добавить задачу к несохраненной вехе. Сначала сохраните
+ веху.
+ link_target_new: Нельзя добавить связь к несохраненной задаче. Сохраните изменения.
+ link_target_readonly: Задача доступна только для чтения
+ loop_link: Невозможно создать цикличную связь
+ no_rest_api: Для работы Easy Gantt требуется REST API. Перейдите в Администрирование->
+ Настройки -> API -> Включить веб-сервис REST
+ overdue: должна заканчиваться в будущем или должна быть уже закрыта
+ overmile: Дата выполнения задачи должна находиться до даты Вехи (Версии)
+ short_delay: должна быть длиннее на %{diff} дней
+ too_short: недостаточно дней для %{rest} часов запланированного времени
+ unsaved_parent: Невозможно добавить задачу к несохраненной родительской задаче.
+ Пожалуйста, сохраните сначала родительскую задачу.
+ unsupported_link_type: Данный тип связи не поддерживатеся
+ gateway:
+ entity_save_failed: "%{entityType} %{entityName} не удалось сохранить из-за
+ ошибки"
+ send_failed: Ошибка запроса
+ label_pro_upgrade: Обновление до PRO-версии
+ link_dir:
+ link_end: предшествует
+ link_start: следует за
+ popup:
+ add_task:
+ heading: Функция "Добавить задачу"
+ text: "Новая задача/веха доступна только в Easy Gantt PRO \r\nCheck
+ for update! "
+ baseline:
+ heading: Функция "Базовый план"
+ text: "Базовый план доступен только в Easy Gantt PRO \r\nCheck
+ for update! "
+ critical:
+ heading: Фунция - Критический путь
+ text: "Критический путь доступен только в Easy Гант PRO \r\nПроверьте
+ обновления! "
+ resource:
+ heading: Функция управления персоналом
+ text: Resource management доступен только в
+ Easy Redmine
+ reload_modal:
+ label_errors: Ошибки
+ text_reload_appeal: Вы действительно хотите не сохранить элементы и перезагрузить
+ данные с сервера?
+ title: Не удалось правильно сохранить Гант
+ sample_global_free:
+ text: Демо-данные не могут быть удалены. Гант для всех проектов доступен только
+ в PRO версии.
+ video:
+ text: Здесть вы можете увидеть большинство возможностей Ганта для всех проектов
+ title: Видео-демонстрация возможностей Ганта для всех проектов.
+ video_id: EiiqBrrY4m4
+ sample:
+ close_label: Закройте данное окно и загрузите реальные данные по проекту.
+ header: Демо-данные загружены!
+ text: Мы подготовили специально демо-данные - попробуйте все возможности
+ Easy Гант без ущерба для Вас! . Мы также предлагаем вам просмотреть
+ видео-инструкцию, показывающее особенности работы. При закрытии данного окна
+ будут загружены реальные данные по проекту.
+ video_label: Смотреть видео-инструкцию
+ video:
+ text: Здесь вы можете ознакомиться с большинством функций модуля Ганта.
+ title: Демо-видео
+ video_id: UHgqfsrD59Q
+ soon:
+ add_task:
+ heading: Функция Дабавить задачу
+ text: Эта функция скоро появится в продукции. Проверить
+ доступность!
+ baseline:
+ heading: Функция Базовый План
+ text: Функция "Базовый План" скоро появится в продукции. Проверить
+ доступность! "
+ resource:
+ heading: Функция Управление Персоналом
+ text: Функция Управление Персоналом доступна только в
+ Easy Redmine
+ text_blocker_milestone: Веха блокирует перемещение задачи вне данной даты
+ text_blocker_move_pre: У данной задачи есть связь, которая не позволяет передвинуть
+ ее вне этой даты
+ title:
+ button_test: Тест (только для тестирования)
+ day_zoom: Отображение временной шкалы по дням
+ jump_today: Показать на графике сегодня
+ month_zoom: Отображение временной шкалы по месяцам
+ print_fit: Вписать диаграмму в страницу
+ week_zoom: Отображение временной шкалы по неделям
+ easy_printable_templates_categories:
+ easy_gantt: Диаграмма Ганта Easy
+ easy_query:
+ name:
+ easy_gantt_easy_issue_query: Easy Гант
+ easy_gantt_easy_project_query: Глобальный Easy Гант
+ error_easy_gantt_view_permission: У вас нет доступа для просмотра Easy Gantt
+ error_epm_easy_gantt_already_active: Easy Гант уже присутствует на этой странице
+ field_easy_gantt_default_zoom: Масштаб по умолчанию
+ field_easy_gantt_relation_delay_in_workdays: Задержка в рабочих днях
+ field_easy_gantt_show_holidays: Показать нерабочие дни
+ field_easy_gantt_show_project_progress: Показать прогресс проекта
+ field_easy_gantt_show_task_soonest_start: Показать скорейшее начало
+ field_keep_link_delay_in_drag: Сохранять задержку при перемещении
+ field_relation: Связь
+ heading_delay_popup: Задать задержку (в днях)
+ heading_demo_feature_popup: Скоро в продукции
+ heading_easy_gantts_issues: Гант по задачам
+ label_easy_gantt: Easy Гант
+ label_easy_gantt_critical_path: Критический путь
+ label_easy_gantt_settings: Настройки Ганта
+ label_filter_group_easy_gantt_easy_issue_query: Поля задачи
+ label_finish_to_finish: Финиш --> Финиш
+ label_parent_issue_plural: Родительские задачи
+ label_start_to_finish: Начало-Окончание
+ label_start_to_start: Старт --> Старт
+ link_easy_gantt_footer: https://www.easyredmine.com/redmine-gantt-plugin
+ link_easy_gantt_plugin: https://www.easyredmine.com/easy-gantt-upgrade-to-pro
+ permission_edit_easy_gantt: Редактировать Easy Гант & Resource management на проекте
+ permission_edit_global_easy_gantt: Редактировать глобальный Easy Гант & Resource
+ management
+ permission_edit_personal_easy_gantt: Реадактировать персональный Easy Gantt & Resource
+ management
+ permission_view_easy_gantt: Отображать Easy Гант & Resource management на проекте
+ permission_view_global_easy_gantt: Отображать глобальный Easy Гант & Resource management
+ permission_view_personal_easy_gantt: Отображать персональный Easy Гант & Resource
+ management
+ project_default_page:
+ easy_gantt: Easy Гант
+ project_module_easy_gantt: Easy Гант
+ text_demo_feature_popup: Эта функия будет скоро доступна
+ text_easy_gantt_footer: Redmine Гант от Easy
+ text_easy_gantt_keep_link_delay_in_drag: Сохранять постоянную задержку при перетаскивании
+ задачи назад
+ text_easy_gantt_print_easy_gantt_current: Показать текущую диаграмму (только для
+ страниц с модулем Easy Gantt)
+ text_easy_gantt_relation_delay_in_workdays: Не учитывать нерабочие дни при запаздывании
+ text_easy_gantt_show_holidays: Показать выходные на Ганте (работают только в Easy
+ Redmine)
+ text_easy_gantt_show_project_progress: Показать процент выполнения на диаграмме
+ (может потребовать дополнительного времени)
+ text_easy_gantt_show_task_soonest_start: Показать минимально допустимые даты для
+ связанных задач или подзадач
+ title_easy_gantt_settings: Easy Гант
diff --git a/plugins/easy_gantt/config/locales/sk.yml b/plugins/easy_gantt/config/locales/sk.yml
new file mode 100644
index 0000000..354e579
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/sk.yml
@@ -0,0 +1,2 @@
+---
+sk:
diff --git a/plugins/easy_gantt/config/locales/sl.yml b/plugins/easy_gantt/config/locales/sl.yml
new file mode 100644
index 0000000..31bb26c
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/sl.yml
@@ -0,0 +1,2 @@
+---
+sl:
diff --git a/plugins/easy_gantt/config/locales/sq.yml b/plugins/easy_gantt/config/locales/sq.yml
new file mode 100644
index 0000000..9c092f0
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/sq.yml
@@ -0,0 +1,2 @@
+---
+sq:
diff --git a/plugins/easy_gantt/config/locales/sr-YU.yml b/plugins/easy_gantt/config/locales/sr-YU.yml
new file mode 100644
index 0000000..24e1796
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/sr-YU.yml
@@ -0,0 +1,2 @@
+---
+sr-YU:
diff --git a/plugins/easy_gantt/config/locales/sr.yml b/plugins/easy_gantt/config/locales/sr.yml
new file mode 100644
index 0000000..43a1014
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/sr.yml
@@ -0,0 +1,2 @@
+---
+sr:
diff --git a/plugins/easy_gantt/config/locales/sv.yml b/plugins/easy_gantt/config/locales/sv.yml
new file mode 100644
index 0000000..ed425ea
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/sv.yml
@@ -0,0 +1,2 @@
+---
+sv:
diff --git a/plugins/easy_gantt/config/locales/th.yml b/plugins/easy_gantt/config/locales/th.yml
new file mode 100644
index 0000000..3596914
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/th.yml
@@ -0,0 +1,2 @@
+---
+th:
diff --git a/plugins/easy_gantt/config/locales/tr.yml b/plugins/easy_gantt/config/locales/tr.yml
new file mode 100644
index 0000000..3be79e7
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/tr.yml
@@ -0,0 +1,2 @@
+---
+tr:
diff --git a/plugins/easy_gantt/config/locales/zh-TW.yml b/plugins/easy_gantt/config/locales/zh-TW.yml
new file mode 100644
index 0000000..44cf0f8
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/zh-TW.yml
@@ -0,0 +1,2 @@
+---
+zh-TW:
diff --git a/plugins/easy_gantt/config/locales/zh.yml b/plugins/easy_gantt/config/locales/zh.yml
new file mode 100644
index 0000000..68de3f8
--- /dev/null
+++ b/plugins/easy_gantt/config/locales/zh.yml
@@ -0,0 +1,138 @@
+---
+zh:
+ button_print: 打印
+ button_project_menu_easy_gantt: Easy Gantt
+ button_top_menu_easy_gantt: 项目甘特图
+ button_use_actual_delay: 采用实际延迟时间
+ easy_gantt:
+ button:
+ close_all: 关闭全部
+ close_all_parent_issues: 关闭所有上一级任务
+ create_baseline: 原始时间线
+ critical_path: 关键路径
+ day_zoom: 天
+ delayed_project_filter: 筛选延误的项目
+ jump_today: 转到今天
+ load_sample_data: 载入示例数据
+ month_zoom: 月
+ print_fit: 适应页面大小
+ problem_finder: 问题
+ reload: 保存
+ remove_delay: 删除延误
+ resource_management: 资源管理
+ tool_panel: 工具栏
+ week_zoom: 周
+ critical_path:
+ disabled: 禁用
+ last: 最近的
+ last_text: 任务不能推迟
+ longest: 最长
+ longest_text: 显示最长的任务队列
+ errors:
+ duplicate_link: 不能创建重复的连接
+ fresh_milestone: 不能给未保存的里程碑添加任务, 请先保存里程碑
+ link_target_new: 不能为未保存任务创建连接, 请先保存任务
+ link_target_readonly: 只读的目标任务
+ loop_link: 不能创建循环的连接
+ no_rest_api: Easy Gantt需要将REST API开启. 请在管理(Administration)->设置 -> API-> 开启REST网络服务中进行设置.
+ overdue: 结束日该是将来的日期, 或者应该是已经完成了.
+ overmile: 必须在 %{effective_date}结束, 以达到里程碑进度要求
+ short_delay: 应当增加 %{diff} 天
+ too_short: 预计要%{rest} 小时, 所给天数不够.
+ unsaved_parent: 上一级任务未保存, 不能在其下添加任务. 请先保存
+ unsupported_link_type: 不支持的连接类型
+ gateway:
+ entity_save_failed: "%{entityType} %{entityName}保存失败"
+ send_failed: 请求失败
+ label_pro_upgrade: 升级到专业版
+ link_dir:
+ link_end: 同上一次
+ link_start: 同下一个
+ popup:
+ add_task:
+ heading: 添加任务属性
+ text: 新任务/里程碑的特性只有有 Easy Gantt PRO(专业版)内可用. 访问 进行更新!
+ baseline:
+ heading: Baseline的属性
+ text: 原始时间线(Baseline)功能仅在Easy Gantt 专业版中可用 检查更新!
+ critical:
+ heading: 关键路径(Path)的属性
+ text: 关键路径的属性只有在Easy Gantt 专业版内可用. 访问进行更新!
+
+ resource:
+ heading: 资源管理器的属性
+ text: 资源管理器的属性只在 Easy Redmine
+ 中可用
+ reload_modal:
+ label_errors: 错误
+ text_reload_appeal: 忽略未保存数据, 重新从服务器下载数据?
+ title: Gantt图没有保存成功
+ sample_global_free:
+ text: 不能关闭示例数据. 所有项目的Gantt只有在专业版中可用.
+ video:
+ text: 在这里可以查看所有项目的甘特图Gantt的属性
+ title: 所有项目的Gantt示例视频
+ video_id: EiiqBrrY4m4
+ sample:
+ close_label: 关闭窗口, 并下载真正的项目数据
+ header: 示例数据下载完成
+ text: 查看一些示例数据来轻松了解Easy Gantt的特性 . 也可以观看演示视频来进一步提高, 关闭窗口将下载真正的项目数据.
+ video_label: 观看视频教程
+ video:
+ text: 在这里可以了解Gantt模块的大部份特性
+ title: 示例视频
+ video_id: UHgqfsrD59Q
+ text_blocker_milestone: 里程碑不允许该任务移到此日期之后
+ text_blocker_move_pre: 由于一些关系的限制, 该任务不能移到此日期之后
+ title:
+ button_test: 测试按钮(仅作测试用)
+ day_zoom: 放大到按天显示
+ jump_today: 显示今天的时间安排
+ month_zoom: 按月度显示
+ print_fit: 缩放甘特图到一页大小
+ week_zoom: 按周显示
+ easy_printable_templates_categories:
+ easy_gantt: Easy 甘特图
+ easy_query:
+ name:
+ easy_gantt_easy_issue_query: Easy Gantt
+ easy_gantt_easy_project_query: ''
+ error_easy_gantt_view_permission: 你没有查看Easy 甘特图的权限
+ error_epm_easy_gantt_already_active: 本页内的Easy gantt 已经生效!
+ field_easy_gantt_default_zoom: 默认时间单位
+ field_easy_gantt_relation_delay_in_workdays: 工作日内延期关系
+ field_easy_gantt_show_holidays: 显示假日
+ field_easy_gantt_show_project_progress: 显示项目进度
+ field_easy_gantt_show_task_soonest_start: 显示最近的开始时间
+ field_keep_link_delay_in_drag: 拖放时使用固定时间延迟
+ field_relation: 关系
+ heading_delay_popup: 设置延迟天数
+ heading_demo_feature_popup: 马上就绪
+ heading_easy_gantts_issues: Easy Gantt Free
+ label_easy_gantt: Easy Gantt
+ label_easy_gantt_critical_path: 关键路径
+ label_easy_gantt_settings: Easy Gantt 设置
+ label_filter_group_easy_gantt_easy_issue_query: 任务
+ label_finish_to_finish: 以最后结束
+ label_parent_issue_plural: 上一级的问题
+ label_start_to_finish: 从结尾开始
+ label_start_to_start: 从头开始
+ link_easy_gantt_plugin: https://www.easyredmine.com/easy-gantt-upgrade-to-pro
+ permission_edit_easy_gantt: 编辑项目中的Easy Gantt和资源管理
+ permission_edit_global_easy_gantt: 编辑通用Easy Gantt 和资源管理
+ permission_edit_personal_easy_gantt: 编辑个人定制 Easy Gantt & Resource management
+ permission_view_easy_gantt: 查看项目中的Easy Gantt和资源管理
+ permission_view_global_easy_gantt: 查看通用的 Easy Gantt 和资源管理
+ permission_view_personal_easy_gantt: 查看个人定制Easy Gantt & Resource management
+ project_default_page:
+ easy_gantt: Easy Gantt
+ project_module_easy_gantt: Easy Gantt
+ text_demo_feature_popup: 该特性将很快生效
+ text_easy_gantt_footer: 由Easy开发的 Redmine Gantt
+ text_easy_gantt_keep_link_delay_in_drag: 将任务拖放回来时, 保持原有的关系和延误情况
+ text_easy_gantt_print_easy_gantt_current: 显示当前的Easy 甘特图(只有在已载入Easy 甘特图的页面有效)
+ text_easy_gantt_relation_delay_in_workdays: 在相关延误天数计算时, 不要计入非工作日
+ text_easy_gantt_show_holidays: 在Gantt上显示当前用户的假日安排(仅在Easy Redmine上可用)
+ text_easy_gantt_show_project_progress: 在项目进度条上显示完成比例(可能导致加载较慢)
+ text_easy_gantt_show_task_soonest_start: 显示由关系或其前提决定的任务的最近有效日期
+ title_easy_gantt_settings: Easy Gantt
diff --git a/plugins/easy_gantt/config/routes.rb b/plugins/easy_gantt/config/routes.rb
new file mode 100644
index 0000000..9f1d9f1
--- /dev/null
+++ b/plugins/easy_gantt/config/routes.rb
@@ -0,0 +1,13 @@
+# Because of plugin deactivations
+if Redmine::Plugin.installed?(:easy_gantt)
+ get '(projects/:project_id)/easy_gantt' => 'easy_gantt#index', as: 'easy_gantt'
+
+ scope format: true, defaults: { format: 'json' }, constraints: { format: 'json' } do
+ scope 'projects/:project_id' do
+ get 'easy_gantt/issues' => 'easy_gantt#issues', as: 'issues_easy_gantt'
+ put 'easy_gantt/relation/:id' => 'easy_gantt#change_issue_relation_delay', as: 'relation_easy_gantt'
+ get 'easy_gantt/project_issues' => 'easy_gantt#project_issues', as: 'project_issues_easy_gantt'
+ end
+ get 'easy_gantt/projects' => 'easy_gantt#projects', as: 'projects_easy_gantt'
+ end
+end
diff --git a/plugins/easy_gantt/db/migrate/20170213152215_add_default_printable_template.rb b/plugins/easy_gantt/db/migrate/20170213152215_add_default_printable_template.rb
new file mode 100644
index 0000000..b753c9f
--- /dev/null
+++ b/plugins/easy_gantt/db/migrate/20170213152215_add_default_printable_template.rb
@@ -0,0 +1,10 @@
+class AddDefaultPrintableTemplate < ActiveRecord::Migration[6.1]
+
+ def up
+ # deprecated
+ end
+
+ def down
+ end
+
+end
diff --git a/plugins/easy_gantt/db/migrate/20170224134615_update_rest_api_settings.rb b/plugins/easy_gantt/db/migrate/20170224134615_update_rest_api_settings.rb
new file mode 100644
index 0000000..37c6621
--- /dev/null
+++ b/plugins/easy_gantt/db/migrate/20170224134615_update_rest_api_settings.rb
@@ -0,0 +1,10 @@
+class UpdateRestApiSettings < ActiveRecord::Migration[6.1]
+
+ def up
+ Setting.where(name: 'rest_api_enabled').update_all(value: '1')
+ end
+
+ def down
+ end
+
+end
diff --git a/plugins/easy_gantt/init.rb b/plugins/easy_gantt/init.rb
new file mode 100644
index 0000000..d0fdc38
--- /dev/null
+++ b/plugins/easy_gantt/init.rb
@@ -0,0 +1,21 @@
+Redmine::Plugin.register :easy_gantt do
+ name 'Easy Gantt plugin'
+ author 'Easy Software Ltd'
+ url 'https://www.easysoftware.com'
+ author_url 'https://www.easysoftware.com'
+ description 'Cool gantt for redmine'
+ version '2.0'
+
+ requires_redmine version_or_higher: '5.0'
+
+ settings partial: 'settings/easy_gantt', default: {
+ 'critical_path' => 'last',
+ 'default_zoom' => 'day',
+ 'show_project_progress' => '1',
+ 'show_lowest_progress_tasks' => '0',
+ 'show_task_soonest_start' => '0',
+ 'relation_delay_in_workdays' => '0'
+ }
+end
+
+require_relative 'after_init'
\ No newline at end of file
diff --git a/plugins/easy_gantt/lib/easy_gantt.rb b/plugins/easy_gantt/lib/easy_gantt.rb
new file mode 100644
index 0000000..73fd96e
--- /dev/null
+++ b/plugins/easy_gantt/lib/easy_gantt.rb
@@ -0,0 +1,38 @@
+module EasyGantt
+
+ def self.non_working_week_days(user=nil)
+ if user.is_a?(Integer)
+ user = Principal.find_by(id: user)
+ elsif user.nil?
+ user = User.current
+ end
+
+ working_days = user.try(:current_working_time_calendar).try(:working_week_days)
+ working_days = Array(working_days).map(&:to_i)
+
+ if working_days.any?
+ (1..7).to_a - working_days
+ else
+ Array(Setting.non_working_week_days).map(&:to_i)
+ end
+ end
+
+ # Experimental function
+ def self.load_fixed_delay?
+ false
+ end
+
+ def self.easy_gantt_pro?
+ Redmine::Plugin.installed?(:easy_gantt_pro)
+ end
+
+ def self.easy_gantt_resources?
+ Redmine::Plugin.installed?(:easy_gantt_resources)
+ end
+
+ def self.easy_baseline?
+ Redmine::Plugin.installed?(:easy_baseline)
+ end
+
+end
+
\ No newline at end of file
diff --git a/plugins/easy_gantt/lib/easy_gantt/application_helper_patch.rb b/plugins/easy_gantt/lib/easy_gantt/application_helper_patch.rb
new file mode 100644
index 0000000..e864a62
--- /dev/null
+++ b/plugins/easy_gantt/lib/easy_gantt/application_helper_patch.rb
@@ -0,0 +1,17 @@
+module EasyGantt
+ module ApplicationHelperPatch
+
+ def self.prepended(base)
+ base.class_eval do
+
+ def link_to_project_with_easy_gantt(project, options = {})
+ { controller: 'easy_gantt', action: 'index', project_id: project }
+ end
+
+ end
+ end
+
+ end
+end
+
+ApplicationHelper.prepend EasyGantt::ApplicationHelperPatch
diff --git a/plugins/easy_gantt/lib/easy_gantt/hooks.rb b/plugins/easy_gantt/lib/easy_gantt/hooks.rb
new file mode 100644
index 0000000..3d695de
--- /dev/null
+++ b/plugins/easy_gantt/lib/easy_gantt/hooks.rb
@@ -0,0 +1,7 @@
+module EasyGantt
+ class Hooks < Redmine::Hook::ViewListener
+ def helper_options_for_default_project_page(context={})
+ context[:default_pages] << 'easy_gantt' if context[:enabled_modules].include?('easy_gantt')
+ end
+ end
+end
diff --git a/plugins/easy_gantt/lib/easy_gantt/issue_patch.rb b/plugins/easy_gantt/lib/easy_gantt/issue_patch.rb
new file mode 100644
index 0000000..ad9e3e3
--- /dev/null
+++ b/plugins/easy_gantt/lib/easy_gantt/issue_patch.rb
@@ -0,0 +1,50 @@
+module EasyGantt
+ module IssuePatch
+
+ def self.prepended(base)
+ base.include InstanceMethods
+
+ base.class_eval do
+
+ scope :gantt_opened, lambda {
+ joins(:status).where(IssueStatus.table_name => { is_closed: false })
+ }
+
+ end
+ end
+
+ module InstanceMethods
+
+ def gantt_editable?(user=nil)
+ user ||= User.current
+
+ (user.allowed_to?(:edit_easy_gantt, project) ||
+ user.allowed_to_globally?(:edit_global_easy_gantt) ||
+ (assigned_to_id == user.id &&
+ user.allowed_to_globally?(:edit_personal_easy_gantt))) &&
+ user.allowed_to?(:manage_issue_relations, project) &&
+ user.allowed_to?(:edit_issues, project)
+ end
+
+ def gantt_latest_due
+ if @gantt_latest_due.nil?
+ dates = relations_from.map{|relation| relation.gantt_previous_latest_start }
+
+ p = @parent_issue || parent
+ if p && Setting.parent_issue_dates == 'derived'
+ dates << p.gantt_latest_due
+ end
+
+ @gantt_latest_due = dates.compact.max
+ end
+
+ @gantt_latest_due
+ end
+
+ end
+
+ end
+end
+
+Issue.prepend EasyGantt::IssuePatch
+
diff --git a/plugins/easy_gantt/lib/easy_gantt/issue_relation_patch.rb b/plugins/easy_gantt/lib/easy_gantt/issue_relation_patch.rb
new file mode 100644
index 0000000..e3078b6
--- /dev/null
+++ b/plugins/easy_gantt/lib/easy_gantt/issue_relation_patch.rb
@@ -0,0 +1,70 @@
+#
+# THIS FILE MUST BE LOADED BEFORE IssueQuery !!!
+#
+module EasyGantt
+ module IssueRelationPatch
+
+ def self.prepended(base)
+ base.include InstanceMethods
+
+ start_to_start = 'start_to_start'
+ finish_to_finish = 'finish_to_finish'
+ start_to_finish = 'start_to_finish'
+
+ new_types = base::TYPES.merge(
+
+ start_to_start => {
+ name: :label_start_to_start,
+ sym_name: :label_start_to_start,
+ order: 20,
+ sym: start_to_start
+ },
+
+ finish_to_finish => {
+ name: :label_finish_to_finish,
+ sym_name: :label_finish_to_finish,
+ order: 21,
+ sym: finish_to_finish
+ },
+
+ start_to_finish => {
+ name: :label_start_to_finish,
+ sym_name: :label_start_to_finish,
+ order: 22,
+ sym: start_to_finish
+ }
+
+ )
+
+ base.class_eval do
+ const_set :TYPE_START_TO_START, start_to_start
+ const_set :TYPE_FINISH_TO_FINISH, finish_to_finish
+ const_set :TYPE_START_TO_FINISH, start_to_finish
+
+ remove_const :TYPES
+ const_set :TYPES, new_types.freeze
+
+ inclusion_validator = _validators[:relation_type].find{|v| v.kind == :inclusion}
+ inclusion_validator.instance_variable_set(:@delimiter, new_types.keys)
+ end
+ end
+
+ module InstanceMethods
+
+ # +---------+ (5) +---------+
+ # | Issue 1 |--------->| Issue 2 |
+ # +---------+ +---------+
+ # (issue_from) (issue_to)
+ #
+ def gantt_previous_latest_start
+ if (IssueRelation::TYPE_PRECEDES == relation_type) && delay && issue_to && (issue_to.start_date || issue_to.due_date)
+ (issue_to.start_date || issue_to.due_date) - 1 - delay
+ end
+ end
+
+ end
+
+ end
+end
+
+IssueRelation.prepend EasyGantt::IssueRelationPatch
diff --git a/plugins/easy_gantt/lib/easy_gantt/project_patch.rb b/plugins/easy_gantt/lib/easy_gantt/project_patch.rb
new file mode 100644
index 0000000..4da7280
--- /dev/null
+++ b/plugins/easy_gantt/lib/easy_gantt/project_patch.rb
@@ -0,0 +1,157 @@
+module EasyGantt
+ module ProjectPatch
+
+ def self.prepended(base)
+ base.extend ClassMethods
+ base.include InstanceMethods
+ end
+
+ module InstanceMethods
+
+ def gantt_editable?(user=nil)
+ user ||= User.current
+
+ (user.allowed_to?(:edit_easy_gantt, self) ||
+ user.allowed_to_globally?(:edit_global_easy_gantt)) &&
+ user.allowed_to?(:edit_project, self)
+ end
+
+ def gantt_reschedule(days)
+ transaction do
+ all_issues = Issue.joins(:project).where(gantt_subprojects_conditions)
+ all_issues.update_all("start_date = start_date + INTERVAL '#{days}' DAY," +
+ "due_date = due_date + INTERVAL '#{days}' DAY")
+
+ all_versions = Version.joins(:project).where(gantt_subprojects_conditions)
+ all_versions.update_all("effective_date = effective_date + INTERVAL '#{days}' DAY")
+
+ Redmine::Hook.call_hook(:model_project_gantt_reschedule, project: project, days: days, all_issues: all_issues)
+ end
+ end
+
+ # Weighted completed percent including subprojects
+ def gantt_completed_percent
+ return @gantt_completed_percent if @gantt_completed_percent || @gantt_completed_percent_added
+
+ i_table = Issue.table_name
+
+ scope = Issue.where("#{i_table}.estimated_hours IS NOT NULL").
+ where("#{i_table}.estimated_hours > 0").
+ joins(:project).
+ where(gantt_subprojects_conditions)
+
+ if scope.exists?
+ sum = scope.select('(SUM(done_ratio / 100.0 * estimated_hours) / SUM(estimated_hours) * 100) AS sum_alias').reorder(nil).first
+ @gantt_completed_percent = sum ? sum.sum_alias.to_f : 0.0
+ else
+ @gantt_completed_percent = 100.0
+ end
+
+ @gantt_completed_percent
+ end
+
+ def gantt_start_date
+ return @gantt_start_date if @gantt_start_date || @gantt_start_date_added
+
+ @gantt_start_date = [
+ Issue.joins(:project).where(gantt_subprojects_conditions).minimum('start_date'),
+ Version.joins(:project).where(gantt_subprojects_conditions).minimum('effective_date')
+ ].compact.min
+ end
+
+ def gantt_due_date
+ return @gantt_due_date if @gantt_due_date || @gantt_due_date_added
+
+ @gantt_due_date = [
+ Issue.joins(:project).where(gantt_subprojects_conditions).maximum('due_date'),
+ Version.joins(:project).where(gantt_subprojects_conditions).maximum('effective_date')
+ ].compact.max
+ end
+
+ def gantt_subprojects_conditions
+ p_table = Project.table_name
+ "#{p_table}.status <> #{Project::STATUS_ARCHIVED} AND #{p_table}.lft >= #{lft} AND #{p_table}.rgt <= #{rgt}"
+ end
+
+ end
+
+ module ClassMethods
+
+ def load_gantt_dates(projects)
+ p_table = Project.table_name
+ i_table = Issue.table_name
+ v_table = Version.table_name
+
+ project_ids = projects.map(&:id)
+
+ data = []
+ data.concat Project.where(id: project_ids).
+ joins("JOIN #{p_table} p2 ON p2.lft >= #{p_table}.lft AND p2.rgt <= #{p_table}.rgt").
+ joins("JOIN #{i_table} i ON i.project_id = p2.id").
+ where('p2.status <> ?', Project::STATUS_ARCHIVED).
+ group("#{p_table}.id").
+ pluck(Arel.sql("#{p_table}.id, MIN(i.start_date), MAX(i.due_date)"))
+
+ data.concat Project.where(id: project_ids).
+ joins("JOIN #{p_table} p2 ON p2.lft >= #{p_table}.lft AND p2.rgt <= #{p_table}.rgt").
+ joins("JOIN #{v_table} v ON v.project_id = p2.id").
+ where('p2.status <> ?', Project::STATUS_ARCHIVED).
+ group("#{p_table}.id").
+ pluck(Arel.sql("#{p_table}.id, MIN(v.effective_date), MAX(v.effective_date)"))
+
+ result = {}
+ data.each do |id, min, max|
+ if result.has_key?(id)
+ result[id][0] = [result[id][0], min].compact.min
+ result[id][1] = [result[id][1], max].compact.max
+ else
+ result[id] = [min, max]
+ end
+ end
+
+ projects.each do |project|
+ project_data = result[project.id]
+
+ if project_data
+ project.instance_variable_set :@gantt_start_date, project_data[0]
+ project.instance_variable_set :@gantt_due_date, project_data[1]
+ end
+
+ project.instance_variable_set :@gantt_start_date_added, true
+ project.instance_variable_set :@gantt_due_date_added, true
+ end
+ end
+
+ def load_gantt_completed_percent(projects)
+ p_table = Project.table_name
+ i_table = Issue.table_name
+
+ project_ids = projects.map(&:id)
+ result = Project.where(id: project_ids).
+ joins("JOIN #{p_table} p2 ON p2.lft >= #{p_table}.lft AND p2.rgt <= #{p_table}.rgt").
+ joins("JOIN #{i_table} i ON i.project_id = p2.id").
+ where("i.estimated_hours IS NOT NULL AND i.estimated_hours > 0").
+ where("p2.status <> ?", Project::STATUS_ARCHIVED).
+ group("#{p_table}.id").
+ pluck(Arel.sql("#{p_table}.id, (SUM(i.done_ratio / 100.0 * i.estimated_hours) / SUM(i.estimated_hours) * 100)")).
+ to_h
+
+ projects.each do |project|
+ done_ratio = result[project.id]
+
+ if done_ratio
+ project.instance_variable_set :@gantt_completed_percent, done_ratio
+ else
+ project.instance_variable_set :@gantt_completed_percent, 100.0
+ end
+
+ project.instance_variable_set :@gantt_completed_percent_added, true
+ end
+ end
+
+ end
+
+ end
+end
+
+Project.prepend EasyGantt::ProjectPatch
diff --git a/plugins/easy_gantt/lib/easy_gantt/queries_controller_patch.rb b/plugins/easy_gantt/lib/easy_gantt/queries_controller_patch.rb
new file mode 100644
index 0000000..7c04405
--- /dev/null
+++ b/plugins/easy_gantt/lib/easy_gantt/queries_controller_patch.rb
@@ -0,0 +1,27 @@
+module EasyGantt
+ module QueriesControllerPatch
+
+ def self.prepended(base)
+ base.prepend(InstanceMethods)
+ end
+
+ module InstanceMethods
+
+ # Redmine return only direct sublasses but
+ # Gantt query inherit from IssueQuery
+ def query_class
+ case params[:type]
+ when 'EasyGantt::EasyGanttIssueQuery'
+ EasyGantt::EasyGanttIssueQuery
+ else
+ super
+ end
+ end
+
+ end
+
+ end
+end
+
+QueriesController.prepend EasyGantt::QueriesControllerPatch
+
diff --git a/plugins/easy_gantt/lib/easy_gantt/version_patch.rb b/plugins/easy_gantt/lib/easy_gantt/version_patch.rb
new file mode 100644
index 0000000..8180f6c
--- /dev/null
+++ b/plugins/easy_gantt/lib/easy_gantt/version_patch.rb
@@ -0,0 +1,23 @@
+module EasyGantt
+ module VersionPatch
+
+ def self.prepended(base)
+ base.include(InstanceMethods)
+ end
+
+ module InstanceMethods
+
+ def gantt_editable?(user=nil)
+ user ||= User.current
+
+ (user.allowed_to?(:edit_easy_gantt, project) ||
+ user.allowed_to_globally?(:edit_global_easy_gantt)) &&
+ user.allowed_to?(:manage_versions, project)
+ end
+
+ end
+
+ end
+end
+
+Version.prepend EasyGantt::VersionPatch
diff --git a/plugins/easy_gantt/spec/controllers/easy_gantt_controller_spec.rb b/plugins/easy_gantt/spec/controllers/easy_gantt_controller_spec.rb
new file mode 100644
index 0000000..9e30591
--- /dev/null
+++ b/plugins/easy_gantt/spec/controllers/easy_gantt_controller_spec.rb
@@ -0,0 +1,28 @@
+require File.expand_path('../../../../easyproject/easy_plugins/easy_extensions/test/spec/spec_helper', __FILE__)
+
+RSpec.describe EasyGanttController, logged: :admin do
+
+ around(:each) do |example|
+ with_settings(rest_api_enabled: 1) { example.run }
+ end
+
+ context 'rest api' do
+ let(:project) { FactoryGirl.create(:project, add_modules: ['easy_gantt']) }
+
+ it 'disabled' do
+ with_settings(rest_api_enabled: 0) do
+ get :index, project_id: project
+ expect(response).to be_error
+
+ get :index
+ expect(response).to be_error
+ end
+ end
+
+ it 'enabled' do
+ get :index
+ expect(response).to be_success
+ end
+ end
+
+end
diff --git a/plugins/easy_gantt/spec/features/add_task_spec.rb b/plugins/easy_gantt/spec/features/add_task_spec.rb
new file mode 100644
index 0000000..a9d7afd
--- /dev/null
+++ b/plugins/easy_gantt/spec/features/add_task_spec.rb
@@ -0,0 +1,24 @@
+require File.expand_path('../../../../easyproject/easy_plugins/easy_extensions/test/spec/spec_helper', __FILE__)
+
+RSpec.feature 'Add task', logged: :admin, js: true do
+ let!(:project) { FactoryGirl.create(:project, add_modules: ['easy_gantt']) }
+
+ around(:each) do |example|
+ with_settings(rest_api_enabled: 1) { example.run }
+ end
+
+ describe 'toolbar' do
+
+ unless Redmine::Plugin.installed?(:easy_gantt_pro)
+ scenario 'should open help' do
+ visit easy_gantt_path(project)
+ wait_for_ajax
+ page.find('.easy-gantt__menu-tools').hover
+ expect(page).to have_selector('#button_add_task_help', text: I18n.t(:label_new))
+ page.find('#button_add_task_help').click
+ expect(page).to have_selector('#add_task_help_modal_popup')
+ end
+ end
+
+ end
+end
diff --git a/plugins/easy_gantt/spec/features/correct_tree_spec.rb b/plugins/easy_gantt/spec/features/correct_tree_spec.rb
new file mode 100644
index 0000000..9709303
--- /dev/null
+++ b/plugins/easy_gantt/spec/features/correct_tree_spec.rb
@@ -0,0 +1,73 @@
+require File.expand_path('../../../../easyproject/easy_plugins/easy_extensions/test/spec/spec_helper', __FILE__)
+
+RSpec.feature 'Correct tree', logged: :admin, js: true do
+ let(:project) {
+ FactoryGirl.create(:project, add_modules: ['easy_gantt'], number_of_issues: 0)
+ }
+ let(:sub_project) {
+ FactoryGirl.create(:project, parent_id: project.id, number_of_issues: 1)
+ }
+ let(:project_issues) {
+ FactoryGirl.create_list(:issue, 3, :project_id => project.id)
+ }
+ let(:milestone) {
+ FactoryGirl.create(:version, project_id: project.id, due_date: Date.today + 7 )
+ }
+ let(:milestone_issues) {
+ FactoryGirl.create_list(:issue, 3, :fixed_version_id => milestone.id, :project_id => project.id)
+ }
+ let(:sub_issues) {
+ FactoryGirl.create_list(:issue, 3, :parent_issue_id => milestone_issues[0].id, :project_id => project.id)
+ }
+ let(:sub_sub_issues) {
+ FactoryGirl.create_list(:issue, 3, :parent_issue_id => sub_issues[0].id, :project_id => project.id)
+ }
+
+ around(:each) do |example|
+ with_settings(rest_api_enabled: 1) { example.run }
+ end
+ it 'should show project items in correct order' do
+ sub_sub_issues
+ project_issues
+ sub_project
+ visit easy_gantt_path(project)
+ wait_for_ajax
+ bars_area = page.find('.gantt_grid_data')
+ # bars_area = page.find('.gantt_bars_area')
+ order_list = [
+ project,
+ project_issues[0],
+ project_issues[1],
+ project_issues[2],
+ milestone,
+ milestone_issues[0],
+ sub_issues[0],
+ sub_sub_issues[0],
+ sub_sub_issues[1],
+ sub_sub_issues[2],
+ sub_issues[1],
+ sub_issues[2],
+ milestone_issues[1],
+ milestone_issues[2],
+ sub_project
+ ]
+ prev_id = nil
+ order_list.each do |issue|
+ if issue.is_a? Project
+ id = 'p' + issue.id.to_s
+ name = issue.name
+ elsif issue.is_a? Version
+ id = 'm' + issue.id.to_s
+ name = issue.name
+ else
+ id = issue.id
+ name = issue.subject
+ end
+ expect(bars_area).to have_text(name)
+ unless prev_id.nil?
+ expect(bars_area.find("div[task_id='#{prev_id}']+div[task_id='#{id}']")).not_to be_nil
+ end
+ prev_id = id
+ end
+ end
+end
\ No newline at end of file
diff --git a/plugins/easy_gantt/spec/features/easy_gantt_spec.rb b/plugins/easy_gantt/spec/features/easy_gantt_spec.rb
new file mode 100644
index 0000000..1c4c4ec
--- /dev/null
+++ b/plugins/easy_gantt/spec/features/easy_gantt_spec.rb
@@ -0,0 +1,25 @@
+require File.expand_path('../../../../easyproject/easy_plugins/easy_extensions/test/spec/spec_helper', __FILE__)
+
+RSpec.feature 'Easy gantt', js: true, logged: :admin do
+ let!(:project) { FactoryGirl.create(:project, add_modules: ['easy_gantt']) }
+
+ around(:each) do |example|
+ with_settings(rest_api_enabled: 1) { example.run }
+ end
+
+ describe 'show gantt' do
+
+ scenario 'show easy gantt on project' do
+ visit easy_gantt_path(project)
+ wait_for_ajax
+ # unless Redmine::Plugin.installed?(:easy_gantt_pro)
+ # page.find('#sample_close_button').click
+ # wait_for_ajax
+ # end
+ expect(page).to have_css('#easy_gantt')
+ expect(page.find('.gantt_grid_data')).to have_content(project.name)
+ expect(page.find('#header')).to have_content(project.name)
+ end
+
+ end
+end
diff --git a/plugins/easy_gantt/spec/features/gantt_save_spec.rb b/plugins/easy_gantt/spec/features/gantt_save_spec.rb
new file mode 100644
index 0000000..8cfdca1
--- /dev/null
+++ b/plugins/easy_gantt/spec/features/gantt_save_spec.rb
@@ -0,0 +1,52 @@
+require File.expand_path('../../../../easyproject/easy_plugins/easy_extensions/test/spec/spec_helper', __FILE__)
+
+RSpec.feature 'Gantt save', logged: :admin, js: true, slow: true do
+ let(:subproject) {
+ FactoryGirl.create(:project, :parent_id => superproject.id, add_modules: ['easy_gantt'], number_of_issues: 3)
+ }
+ let(:superproject) {
+ FactoryGirl.create(:project, add_modules: ['easy_gantt'], number_of_issues: 3)
+ }
+ let(:superproject_milestone_issues) {
+ FactoryGirl.create_list(:issue, 3, :fixed_version_id => superproject_milestone.id, :project_id => superproject.id)
+ }
+ let(:subproject_milestone_issues) {
+ FactoryGirl.create_list(:issue, 3, :fixed_version_id => subproject_milestone.id, :project_id => subproject.id)
+ }
+ let(:subproject_milestone) {
+ FactoryGirl.create(:version, project_id: subproject.id)
+ }
+ let(:superproject_milestone) {
+ FactoryGirl.create(:version, project_id: superproject.id)
+ }
+ let(:subissues) {
+ FactoryGirl.create_list(:issue, 3, :parent_issue_id => superproject.issues[0].id, :project_id => superproject.id)
+ }
+
+ around(:each) do |example|
+ with_settings(rest_api_enabled: 1) { example.run }
+ end
+
+
+ it 'should save issue' do
+ issue = superproject.issues[0]
+ old_start_date = issue.start_date
+ visit easy_gantt_path(superproject)
+ wait_for_ajax
+ expect(page).to have_text(issue.subject)
+ move_script= <<-EOF
+ (function(){var issue = ysy.data.issues.getByID(#{issue.id});
+ issue.set({start_date:moment('#{Date.today + 2.days}'),end_date:moment('#{Date.today + 4.days}')});
+ return "success";})()
+ EOF
+ save_button = page.find('#button_save')
+ expect(page).to have_css('#button_save.disabled')
+ expect(page.evaluate_script(move_script)).to eq('success')
+ expect(page).not_to have_css('#button_save.disabled')
+ save_button.click
+ wait_for_ajax
+ expect(page).to have_css('#button_save.disabled')
+ issue.reload
+ expect(issue.start_date).to eq(old_start_date + 2.days)
+ end
+end
\ No newline at end of file
diff --git a/plugins/easy_gantt/spec/features/global_gantt_spec.rb b/plugins/easy_gantt/spec/features/global_gantt_spec.rb
new file mode 100644
index 0000000..63e9820
--- /dev/null
+++ b/plugins/easy_gantt/spec/features/global_gantt_spec.rb
@@ -0,0 +1,30 @@
+require File.expand_path('../../../../easyproject/easy_plugins/easy_extensions/test/spec/spec_helper', __FILE__)
+
+RSpec.feature 'Global gantt', logged: :admin, js: true do
+ let!(:superproject) {
+ FactoryGirl.create(:project, add_modules: ['easy_gantt'], number_of_issues: 3)
+ }
+ around(:each) do |example|
+ with_settings(rest_api_enabled: 1) { example.run }
+ end
+ unless Redmine::Plugin.installed?(:easy_gantt_pro) then
+ it 'should load sample Data' do
+ visit easy_gantt_path
+ wait_for_ajax
+ expect(page).to have_css('#sample_cont')
+ expect(page).to have_text('1. Administrative Projects')
+ expect(page).to have_text('2. HR Projects')
+ expect(page).to have_text('3. IT Projects')
+ expect(page).to have_text('4. Product Development')
+ end
+ it 'should open sample project' do
+ visit easy_gantt_path
+ wait_for_ajax
+ expect(page).to have_text('3. IT Projects')
+ page.find('[task_id="p3"] .gantt_open').click
+ expect(page).to have_text('Client Project')
+ expect(page).to have_text('Implementation of IS')
+ expect(page).to have_text('Managing projects')
+ end
+ end
+end
\ No newline at end of file
diff --git a/plugins/easy_gantt/spec/requests/permissions_spec.rb b/plugins/easy_gantt/spec/requests/permissions_spec.rb
new file mode 100644
index 0000000..a27b49e
--- /dev/null
+++ b/plugins/easy_gantt/spec/requests/permissions_spec.rb
@@ -0,0 +1,71 @@
+require File.expand_path('../../../../easyproject/easy_plugins/easy_extensions/test/spec/spec_helper', __FILE__)
+
+RSpec.describe 'Permission', type: :request do
+
+ let!(:user) { FactoryGirl.create(:user) }
+
+ let!(:project1) { FactoryGirl.create(:project, number_of_issues: 3, add_modules: ['easy_gantt']) }
+ let!(:project2) { FactoryGirl.create(:project, number_of_issues: 3, add_modules: ['easy_gantt']) }
+ let!(:project3) { FactoryGirl.create(:project, number_of_issues: 3, add_modules: ['easy_gantt']) }
+
+ let!(:role_nothing) { FactoryGirl.create(:role, permissions: []) }
+ let!(:role_project_view) { FactoryGirl.create(:role, permissions: [:view_issues, :view_easy_gantt]) }
+ let!(:role_project_edit) { FactoryGirl.create(:role, permissions: [:view_issues, :view_easy_gantt, :edit_easy_gantt, :manage_issue_relations, :edit_issues]) }
+
+ let(:query) do
+ _query = EasyIssueGanttQuery.new(name: '_')
+ _query.filters = {}
+ _query.add_filter('status_id', 'o', nil)
+ _query
+ end
+
+ around(:each) do |example|
+ with_settings(rest_api_enabled: 1) { example.run }
+ end
+
+ before(:each) do
+ FactoryGirl.create(:member, project: project1, user: user, roles: [role_nothing])
+ FactoryGirl.create(:member, project: project2, user: user, roles: [role_project_view])
+ FactoryGirl.create(:member, project: project3, user: user, roles: [role_project_edit])
+
+ logged_user(user)
+ end
+
+ # context 'Project level' do
+ # end
+
+ context 'Global level' do
+
+ def get_issues(project)
+ params = query.to_params.merge(opened_project_id: project.id, key: User.current.api_key, format: 'json')
+ get projects_easy_gantt_path, params
+
+ expect(response).to be_ok
+
+ json = JSON.parse(body)
+ json['easy_gantt_data']['issues']
+ end
+
+ # TODO: Global gantt now works with projects
+
+ # it 'should see nothing' do
+ # binding.pry unless $__binding
+ # issues = get_issues(project1)
+ # expect(issues).to be_empty
+ # end
+
+ # it 'only view' do
+ # issues = get_issues(project2)
+ # expect(issues).to be_any
+ # expect(issues.map{|i| i['permissions']['editable']}).to all(be_nil)
+ # end
+
+ # it 'editable' do
+ # issues = get_issues(project3)
+ # expect(issues).to be_any
+ # expect(issues.map{|i| i['permissions']['editable']}).to all(be_truthy)
+ # end
+
+ end
+
+end
diff --git a/plugins/easy_gantt_pro/.run-linter.sh b/plugins/easy_gantt_pro/.run-linter.sh
new file mode 100644
index 0000000..8de2200
--- /dev/null
+++ b/plugins/easy_gantt_pro/.run-linter.sh
@@ -0,0 +1,18 @@
+#!/bin/bash -l
+
+any_error=false
+
+if [[ -d "plugins" ]]; then
+ directory="plugins"
+else
+ directory="."
+fi
+
+for file in $(find $directory -name "*.rb" -type f -print); do
+ ruby -wc $file 1>/dev/null
+ [[ $? -eq 1 ]] && any_error=true
+done
+
+if [[ $any_error = "true" ]]; then
+ exit 1
+fi
diff --git a/plugins/easy_gantt_pro/.run-tests.sh b/plugins/easy_gantt_pro/.run-tests.sh
new file mode 100644
index 0000000..86de26d
--- /dev/null
+++ b/plugins/easy_gantt_pro/.run-tests.sh
@@ -0,0 +1,169 @@
+#!/bin/bash -l
+
+# -v print lines as they are read
+# -x print lines as they are executed
+# -e abort script at first error
+set -e
+
+if [[ $# -eq 0 ]]; then
+ echo "You must set database adapter"
+ exit 1
+fi
+
+export ADAPTER=$1
+shift
+
+case $ADAPTER in
+ mysql2)
+ export DB_USERNAME=$MYSQL_USERNAME
+ export DB_PASSWORD=$MYSQL_PASSWORD
+ ;;
+ postgresql)
+ export DB_USERNAME=$PG_USERNAME
+ export DB_PASSWORD=$PG_PASSWROD
+ ;;
+ *) echo "You must set adapter mysql2 or postgresql"
+ exit 1
+esac
+
+while [[ $# -ge 1 ]]; do
+ arg=$1
+
+ case $arg in
+ # Show variables for debugging
+ --show-variables) SHOW_VARIABLES="true"
+ ;;
+ # Add plugins which are not part of EASY_BASE_REPO
+ --add-plugins) shift
+ ADDITIONAL_PLUGINS=($(echo ${1//,/ }))
+ ;;
+ # Remove plugins
+ --remove-plugins) shift
+ UNDESIRED_PLUGINS=($(echo ${1//,/ }))
+ ;;
+ *) # Nothing to do
+ ;;
+ esac
+ shift
+done
+
+_plugin=($(echo $CI_REPOSITORY_URL | tr '/' ' '))
+CURRENT_PLUGIN=${_plugin[-1]/.git/}
+BASE_ROOT=$CI_PROJECT_DIR/.redmine
+PLUGINS_ROOT=$BASE_ROOT/plugins
+CURRENT_PLUGIN_ROOT=$PLUGINS_ROOT/$CURRENT_PLUGIN
+COMMON_BRANCHES=(bleeding-edge devel release-candidate bug-fixing master)
+
+# Try to find common branch as fallback for additional plugins
+if [[ ${#ADDITIONAL_PLUGINS[@]} -ne 0 ]]; then
+ # Get all ancestors branches
+ # logs=$(git log --branches --source --oneline | awk '{print $2}' | uniq)
+ logs=$(git log --oneline --merges | grep into | sed 's/.* into //g' | uniq | head -n 10 | tr -d "'")
+
+ # Iterater through all ancestor branches until get first common branch
+ for branch in $logs; do
+ if [[ " ${COMMON_BRANCHES[@]} " = *" $branch "* ]]; then
+ CLOSEST_COMMON_BRANCH=$branch
+ break
+ fi
+ done
+fi
+
+if [[ $SHOW_VARIABLES = "true" ]]; then
+ echo "EASY_BASE_REPO:" $EASY_BASE_REPO
+ echo "BASE_ROOT:" $BASE_ROOT
+ echo "CURRENT_PLUGIN:" $CURRENT_PLUGIN
+ echo "ADDITIONAL_PLUGINS:" ${ADDITIONAL_PLUGINS[*]}
+ echo "CLOSEST_COMMON_BRANCH:" $CLOSEST_COMMON_BRANCH
+ echo "UNDESIRED_PLUGINS:" ${UNDESIRED_PLUGINS[*]}
+fi
+
+# Ensure deleteing database even if test failed
+function before_exit {
+ return_value=$?
+ bundle exec rake db:drop
+ exit $return_value
+}
+
+trap before_exit SIGHUP SIGINT SIGTERM EXIT
+
+# Setup base easy project
+[[ -d $BASE_ROOT ]] && rm -rf $BASE_ROOT
+git clone --depth 1 ssh://git@git.easy.cz/$EASY_BASE_REPO.git $BASE_ROOT
+cd $BASE_ROOT
+
+# Init database
+ruby -ryaml -rsecurerandom -e "
+ database = 'redmine_'+SecureRandom.hex(8).to_s
+ config = {
+ 'adapter' => ENV['ADAPTER'],
+ 'database' => database,
+ 'host' => '127.0.0.1',
+ 'username' => ENV['DB_USERNAME'],
+ 'password' => ENV['DB_PASSWORD'],
+ 'encoding' => 'utf8'
+ }
+ config = {
+ 'test' => config.merge({'database' => 'test_'+database}),
+ 'development' => config,
+ 'production' => config
+ }.to_yaml
+ File.write('config/database.yml', config)
+"
+
+# Init current plugin
+[[ -d $CURRENT_PLUGIN_ROOT ]] && rm -rf $CURRENT_PLUGIN_ROOT
+ln -s $CI_PROJECT_DIR $CURRENT_PLUGIN_ROOT
+
+# Init other plugins
+pushd $PLUGINS_ROOT
+ for plugin in ${ADDITIONAL_PLUGINS[*]}; do
+ echo "--> Init plugin: $plugin"
+
+ [[ -d $plugin ]] && rm -rf $plugin
+ git clone ssh://git@git.easy.cz/devel/$plugin.git $plugin
+
+ pushd $plugin
+ # Checkout to the same branch if exist
+ if [[ $(git branch --remotes --list origin/$CI_COMMIT_REF_NAME) ]]; then
+ echo "---> Checking out $CI_COMMIT_REF_NAME"
+ git checkout $CI_COMMIT_REF_NAME
+ git pull
+
+ # If not try to use closest common branch
+ elif [[ -n $CLOSEST_COMMON_BRANCH && -n $(git branch --remotes --list origin/$CLOSEST_COMMON_BRANCH) ]]; then
+ echo "---> Checking out $CLOSEST_COMMON_BRANCH"
+ git checkout $CLOSEST_COMMON_BRANCH
+ git pull
+
+ else
+ echo "---> No common branch. Using default."
+ fi
+ popd
+ done
+popd
+
+# Removal of undesired plugins
+pushd $PLUGINS_ROOT
+ for plugin in ${UNDESIRED_PLUGINS[*]}; do
+ echo "--> Remove plugin: $plugin"
+
+ if [[ -d $plugin ]]; then
+ echo "---> Remove from plugins"
+ rm -rf $plugin
+ elif [[ -d easyproject/easy_plugins/$plugin ]]; then
+ echo "---> Remove from easyproject/easy_plugins"
+ rm -rf easyproject/easy_plugins/$plugin
+ else
+ echo "---> Plugin doesn't exist"
+ fi
+ done
+popd
+
+to_test="{$(echo ${ADDITIONAL_PLUGINS[*]} $CURRENT_PLUGIN | tr ' ' ',')}"
+
+bundle update
+bundle exec rake db:drop db:create db:migrate
+bundle exec rake easyproject:install
+bundle exec rake test:prepare RAILS_ENV=test
+bundle exec rake easyproject:tests:spec NAME=$to_test RAILS_ENV=test
diff --git a/plugins/easy_gantt_pro/LICENSE b/plugins/easy_gantt_pro/LICENSE
new file mode 100644
index 0000000..1255e47
--- /dev/null
+++ b/plugins/easy_gantt_pro/LICENSE
@@ -0,0 +1,60 @@
+LICENCE
+
+All Easy Redmine Extensions are distributed under GNU/GPL 2 license (see below).
+If not otherwise stated, all images, cascading style sheets, and included JavaScript are NOT GPL, and are released under the Easy Redmine Commercial Use License (see below).
+
+GNU GENERAL PUBLIC LICENSE
+Version 2, June 1991
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+
+Preamble
+The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.
+When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
+To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
+For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
+We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
+Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
+Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
+The precise terms and conditions for copying, distribution and modification follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".
+Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
+1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.
+You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
+2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
+a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
+b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
+c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
+These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
+Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.
+In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
+3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
+a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
+b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
+c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
+The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
+If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
+4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
+5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
+6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
+7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.
+If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.
+It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
+This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
+8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
+9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
+Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
+10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
+NO WARRANTY
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+END OF TERMS AND CONDITIONS
+
+EASY REDMINE COMMERCIAL USE LICENSE
+The Easy Redmine Commercial Use License is a GPL compatible license that pertains only to the images, cascading style sheets and JavaScript elements of Easy Redmine Themes and Styles produced by Easy Software Ltd. As stated by the GPL version 2.0 license, these elements of product that are not compiled together but are sent independently of GPL code, and combined in a client's browser, do not have to be GPL themselves. These images, cascading style sheets and JavaScript elements are copyright Easy Software Ltd. and can be used and manipulated for your own or if you have signed Easy Redmine Partner Agreement for your clients purposes. You cannot redistribute these files as your own, or include them in any package or extension of your own without prior consent of Easy Software Ltd.
+Unauthorised distribution or making it accessible to a third party without prior Easy Software Ltd. consent, authorizes Easy Software Ltd. to invoice contractual penalty in the amount of 10 000 EUR for any breach of the this License.
+
diff --git a/plugins/easy_gantt_pro/README.md b/plugins/easy_gantt_pro/README.md
new file mode 100644
index 0000000..a214974
--- /dev/null
+++ b/plugins/easy_gantt_pro/README.md
@@ -0,0 +1,3 @@
+# Easy Gantt PRO
+
+For documentation and requirements, go to https://www.easyredmine.com/redmine-gantt-plugin
diff --git a/plugins/easy_gantt_pro/after_init.rb b/plugins/easy_gantt_pro/after_init.rb
new file mode 100644
index 0000000..70e89a9
--- /dev/null
+++ b/plugins/easy_gantt_pro/after_init.rb
@@ -0,0 +1,73 @@
+lib_dir = File.join(File.dirname(__FILE__), 'lib', 'easy_gantt_pro')
+
+# Redmine patches
+patch_path = File.join(lib_dir, '*_patch.rb')
+Dir.glob(patch_path).each do |file|
+ require file
+end
+
+require lib_dir
+require File.join(lib_dir, 'hooks')
+
+Redmine::MenuManager.map :easy_gantt_tools do |menu|
+ menu.delete(:add_task)
+ menu.delete(:critical)
+ menu.delete(:baseline)
+
+ menu.push(:baseline, 'javascript:void(0)',
+ param: :project_id,
+ caption: :'easy_gantt.button.create_baseline',
+ html: { icon: 'icon-projects' },
+ if: proc { |project|
+ project.present? &&
+ Redmine::Plugin.installed?(:easy_baseline) &&
+ project.module_enabled?('easy_baselines') &&
+ User.current.allowed_to?(:view_baselines, project)
+ },
+ after: :tool_panel)
+
+ menu.push(:critical, 'javascript:void(0)',
+ param: :project_id,
+ caption: :'easy_gantt.button.critical_path',
+ html: { icon: 'icon-summary' },
+ if: proc { |p| p.present? && Setting.plugin_easy_gantt['critical_path'] != 'disabled' },
+ after: :tool_panel)
+
+ menu.push(:add_task, 'javascript:void(0)',
+ param: :project_id,
+ caption: :label_new,
+ html: { icon: 'icon-add' },
+ if: proc { |project|
+ project.present? &&
+ User.current.allowed_to?(:edit_easy_gantt, project) &&
+ (User.current.allowed_to?(:add_issues, project) ||
+ User.current.allowed_to?(:manage_versions, project))
+ },
+ after: :tool_panel)
+
+ menu.push(:ggrm, 'javascript:void(0)',
+ caption: :'easy_gantt_pro.resources.label_resources',
+ html: { icon: 'icon-stats' },
+ if: proc { |project|
+ project.nil? && Redmine::Plugin.installed?(:easy_gantt_resources)
+ })
+
+ menu.push(:delayed_project_filter, 'javascript:void(0)',
+ caption: :'easy_gantt.button.delayed_project_filter',
+ html: { icon: 'icon-filter' },
+ if: proc {
+ Setting.plugin_easy_gantt['show_project_progress'] == '1'
+ })
+
+ menu.push(:delayed_issue_filter, 'javascript:void(0)',
+ caption: :'easy_gantt.button.delayed_issue_filter',
+ html: { icon: 'icon-filter' })
+
+ menu.push(:show_lowest_progress_tasks, 'javascript:void(0)',
+ caption: :'easy_gantt.button.show_lowest_progress_tasks',
+ html: { icon: 'icon-warning' },
+ if: proc { |project|
+ project.nil? && Setting.plugin_easy_gantt['show_lowest_progress_tasks'] == '1'
+ })
+
+end
diff --git a/plugins/easy_gantt_pro/app/controllers/easy_gantt_pro_controller.rb b/plugins/easy_gantt_pro/app/controllers/easy_gantt_pro_controller.rb
new file mode 100644
index 0000000..ec0b582
--- /dev/null
+++ b/plugins/easy_gantt_pro/app/controllers/easy_gantt_pro_controller.rb
@@ -0,0 +1,64 @@
+class EasyGanttProController < EasyGanttController
+ accept_api_auth :lowest_progress_tasks
+
+ before_action :require_admin, only: [:recalculate_fixed_delay]
+
+ # TODO: Calculate progress date on DB
+ def lowest_progress_tasks
+ project_ids = Array(params[:project_ids])
+
+ @data = Hash.new { |hash, key| hash[key] = { date: Date.new(9999), ids: [] } }
+
+ issues = Issue.open.joins(:status).
+ where(project_id: project_ids).
+ where.not(start_date: nil, due_date: nil).
+ pluck(:project_id, :id, :start_date, :due_date, :done_ratio)
+
+ issues.each do |p_id, i_id, start_date, due_date, done_ratio|
+ diff = due_date - start_date
+ add_days = (diff * done_ratio.to_i) / 100
+ progress_date = start_date + add_days.days
+
+ project_data = @data[p_id]
+ if project_data[:date] == progress_date
+ project_data[:ids] << i_id
+ elsif project_data[:date] > progress_date
+ project_data[:date] = progress_date
+ project_data[:ids] = [i_id]
+ end
+ end
+
+ ids = @data.flat_map{|_, data| data[:ids]}
+ @issues = Issue.select(:project_id, :id, :subject).where(id: ids)
+ end
+
+ def recalculate_fixed_delay
+ statuses = [Project::STATUS_ACTIVE]
+
+ issues = Issue.joins(:project).where(projects: { status: statuses })
+ relations = IssueRelation.preload(:issue_from, :issue_to).
+ where(relation_type: IssueRelation::TYPE_PRECEDES).
+ where(issue_from_id: issues, issue_to_id: issues).
+ where.not(delay: nil)
+
+ relations.each do |relation|
+ next if relation.issue_from.nil? || relation.issue_to.nil?
+
+ from = relation.issue_from.due_date || relation.issue_from.start_date
+ to = relation.issue_to.start_date || relation.issue_to.due_date
+
+ next if from.nil? || to.nil?
+
+ saved_delay = relation.delay
+ correct_delay = (to-from-1).to_i
+
+ if saved_delay != correct_delay
+ relation.update_column(:delay, correct_delay)
+ end
+ end
+
+ flash[:notice] = l(:notice_easy_gantt_fixed_delay_recalculated)
+ redirect_to :back
+ end
+
+end
diff --git a/plugins/easy_gantt_pro/app/helpers/.gitkeep b/plugins/easy_gantt_pro/app/helpers/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/plugins/easy_gantt_pro/app/views/easy_gantt_pro/_gantt_tools.html.erb b/plugins/easy_gantt_pro/app/views/easy_gantt_pro/_gantt_tools.html.erb
new file mode 100644
index 0000000..e69de29
diff --git a/plugins/easy_gantt_pro/app/views/easy_gantt_pro/_includes.html.erb b/plugins/easy_gantt_pro/app/views/easy_gantt_pro/_includes.html.erb
new file mode 100644
index 0000000..985ac8b
--- /dev/null
+++ b/plugins/easy_gantt_pro/app/views/easy_gantt_pro/_includes.html.erb
@@ -0,0 +1,16 @@
+<% include_calendar_headers_tags %>
+<%= easy_gantt_include_css('easy_gantt_pro', media: 'all', from_plugin: 'easy_gantt_pro') %>
+
+ <%= easy_gantt_include_js(
+ 'common', 'sorting', 'email_silencer',
+ (['baseline', 'add_task'] if @project),
+ ('critical' if @project && Setting.plugin_easy_gantt['critical_path'] != 'disabled'),
+ ('project_move' if @project.nil?),
+ ('lowest_progress' if @project.nil? && Setting.plugin_easy_gantt['show_lowest_progress_tasks'] == '1'),
+ ('delayed_projects' if @project.nil? && Setting.plugin_easy_gantt['show_project_progress'] == '1'),
+ ('gg_resource' if @project.nil? && EasyGantt.easy_gantt_resources?),
+ ('fixed_delay' if EasyGantt.load_fixed_delay?),
+ ('delayed_issues' if params[:controller] == 'easy_gantt'),
+ from_plugin: 'easy_gantt_pro')
+ %>
+
diff --git a/plugins/easy_gantt_pro/app/views/easy_gantt_pro/_js_prepare.html.erb b/plugins/easy_gantt_pro/app/views/easy_gantt_pro/_js_prepare.html.erb
new file mode 100644
index 0000000..6ae375c
--- /dev/null
+++ b/plugins/easy_gantt_pro/app/views/easy_gantt_pro/_js_prepare.html.erb
@@ -0,0 +1,148 @@
+<%
+ subproject_gantt_params = query.to_params.merge(key: User.current.api_key, subproject_loading: '1', opened_project_id: ':projectID', format: 'json')
+
+ subproject_gantt_path = if @project
+ issues_easy_gantt_path(@project.id, subproject_gantt_params)
+ else
+ projects_easy_gantt_path(subproject_gantt_params)
+ end
+
+ conditional_paths = {}
+
+ if @project && EasyGantt.easy_baseline?
+ conditional_paths[:baselineRoot] = project_easy_baselines_path(@project, key: User.current.api_key, format: 'json')
+ conditional_paths[:baselineGET] = easy_baseline_gantt_path(':baselineID', key: User.current.api_key, format: 'json')
+ conditional_paths[:baselineDELETE] = project_easy_baseline_path(@project, ':baselineID', key: User.current.api_key, format: 'json')
+ end
+%>
+
+
\ No newline at end of file
diff --git a/plugins/easy_gantt_pro/app/views/easy_gantt_pro/lowest_progress_tasks.api.rsb b/plugins/easy_gantt_pro/app/views/easy_gantt_pro/lowest_progress_tasks.api.rsb
new file mode 100644
index 0000000..3f47311
--- /dev/null
+++ b/plugins/easy_gantt_pro/app/views/easy_gantt_pro/lowest_progress_tasks.api.rsb
@@ -0,0 +1,15 @@
+api.easy_gantt_data do
+
+ api.array :issues do
+ @issues.each do |issue|
+ api.issue do
+ api.id issue.id
+ api.project_id issue.project_id
+ api.name issue.subject
+ api.progress_date @data[issue.project_id][:date]
+ api.url issue_path(issue)
+ end
+ end
+ end
+
+end
diff --git a/plugins/easy_gantt_pro/app/views/easy_page_modules/projects/_easy_global_gantt_edit.html.erb b/plugins/easy_gantt_pro/app/views/easy_page_modules/projects/_easy_global_gantt_edit.html.erb
new file mode 100644
index 0000000..e69de29
diff --git a/plugins/easy_gantt_pro/app/views/easy_page_modules/projects/_easy_global_gantt_show.html.erb b/plugins/easy_gantt_pro/app/views/easy_page_modules/projects/_easy_global_gantt_show.html.erb
new file mode 100644
index 0000000..1374227
--- /dev/null
+++ b/plugins/easy_gantt_pro/app/views/easy_page_modules/projects/_easy_global_gantt_show.html.erb
@@ -0,0 +1,8 @@
+<% if easy_page_modules_data[:query].nil? %>
+
+ <%= l(:label_easy_page_module_settings_missing) %>
+
+<% else %>
+ <%= render template: 'easy_gantt/index', locals: { show_query: false,
+ query: easy_page_modules_data[:query] } %>
+<% end %>
diff --git a/plugins/easy_gantt_pro/app/views/easy_page_modules/projects/_easy_project_gantt_edit.html.erb b/plugins/easy_gantt_pro/app/views/easy_page_modules/projects/_easy_project_gantt_edit.html.erb
new file mode 100644
index 0000000..e69de29
diff --git a/plugins/easy_gantt_pro/app/views/easy_page_modules/projects/_easy_project_gantt_show.html.erb b/plugins/easy_gantt_pro/app/views/easy_page_modules/projects/_easy_project_gantt_show.html.erb
new file mode 100644
index 0000000..5f502c0
--- /dev/null
+++ b/plugins/easy_gantt_pro/app/views/easy_page_modules/projects/_easy_project_gantt_show.html.erb
@@ -0,0 +1,12 @@
+<% if easy_page_modules_data[:query].nil? %>
+
+ <%= l(:label_easy_page_module_settings_missing) %>
+
+<% elsif easy_page_modules_data[:can_view] %>
+ <%= render template: 'easy_gantt/index', locals: { show_query: false,
+ query: easy_page_modules_data[:query] } %>
+<% else %>
+
+ <%= l(:error_easy_gantt_view_permission) %>
+
+<% end %>
diff --git a/plugins/easy_gantt_pro/app/views/easy_settings/_easy_gantt_pro.html.erb b/plugins/easy_gantt_pro/app/views/easy_settings/_easy_gantt_pro.html.erb
new file mode 100644
index 0000000..893a8f8
--- /dev/null
+++ b/plugins/easy_gantt_pro/app/views/easy_settings/_easy_gantt_pro.html.erb
@@ -0,0 +1,38 @@
+<% # Its a hook only !!! %>
+
+
+ <%= content_tag :label, l(:field_easy_gantt_fixed_delay) %>
+
+ <%= link_to l(:label_easy_gantt_recalculate_fixed_delay), easy_gantt_recalculate_fixed_delay_path, data: { confirm: l(:warning_easy_gantt_recalculate_fixed_delay) } %>
+
+
+
+
+ <%= content_tag :label, l(:label_easy_gantt_critical_path) %>
+
+
+ <%= radio_button_tag 'settings[critical_path]', 'disabled', @settings['critical_path'] == 'disabled' %>
+ <%= l('easy_gantt.critical_path.disabled') %>
+
+
+
+ <%= radio_button_tag 'settings[critical_path]', 'last', @settings['critical_path'] == 'last' %>
+ <%= l('easy_gantt.critical_path.last') %>
+ (<%= l('easy_gantt.critical_path.last_text') %>)
+
+
+
+ <%= radio_button_tag 'settings[critical_path]', 'longest', @settings['critical_path'] == 'longest' %>
+ <%= l('easy_gantt.critical_path.longest') %>
+ (<%= l('easy_gantt.critical_path.longest_text') %>)
+
+
+
+
+
+ <%= label_tag 'settings_show_lowest_progress_tasks', l(:label_show_lowest_progress_tasks) %>
+ <%= check_box_tag 'settings[show_lowest_progress_tasks]', '1', @settings['show_lowest_progress_tasks'] == '1' %>
+
+ <%= l(:text_show_lowest_progress_tasks) %>
+
+
diff --git a/plugins/easy_gantt_pro/app/views/hooks/easy_gantt_pro/_view_easy_gantt_index_bottom.html.erb b/plugins/easy_gantt_pro/app/views/hooks/easy_gantt_pro/_view_easy_gantt_index_bottom.html.erb
new file mode 100644
index 0000000..537003c
--- /dev/null
+++ b/plugins/easy_gantt_pro/app/views/hooks/easy_gantt_pro/_view_easy_gantt_index_bottom.html.erb
@@ -0,0 +1,4 @@
+<%= content_for :header_tags do %>
+ <%= render 'easy_gantt_pro/includes', project: @project, query: query %>
+ <%= render 'easy_gantt_pro/js_prepare', project: @project, query: query %>
+<% end %>
diff --git a/plugins/easy_gantt_pro/app/views/hooks/easy_gantt_pro/_view_easy_gantts_issues_toolbars.html.erb b/plugins/easy_gantt_pro/app/views/hooks/easy_gantt_pro/_view_easy_gantts_issues_toolbars.html.erb
new file mode 100644
index 0000000..707bc0c
--- /dev/null
+++ b/plugins/easy_gantt_pro/app/views/hooks/easy_gantt_pro/_view_easy_gantts_issues_toolbars.html.erb
@@ -0,0 +1,37 @@
+<% if @project && Redmine::Plugin.installed?(:easy_baseline) && @project.module_enabled?('easy_baselines') %>
+ <% baselines = Project.where(easy_baseline_for: @project) %>
+
+
+<% end %>
+
+
+
+
diff --git a/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/add_task.js b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/add_task.js
new file mode 100644
index 0000000..7972acd
--- /dev/null
+++ b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/add_task.js
@@ -0,0 +1,500 @@
+/**
+ * Created by Ringael on 5. 8. 2015.
+ */
+window.ysy = window.ysy || {};
+ysy.pro = ysy.pro || {};
+ysy.pro.addTask = {
+ _name: "AddTask",
+ initToolbar: function (ctx) {
+ var addTaskPanel = new ysy.view.AddTaskPanel();
+ addTaskPanel.init(ysy.settings.addTask);
+ ctx.children.push(addTaskPanel);
+ },
+ patch: function () {
+ ysy.proManager.register("initToolbar", this.initToolbar);
+ ysy.proManager.register("close", this.close);
+ var proManager = ysy.proManager;
+ var addTaskClass = ysy.pro.addTask;
+ ysy.view.AllButtons.prototype.extendees.add_task = {
+ bind: function () {
+ this.model = ysy.settings.addTask;
+ this._register(ysy.settings.resource);
+ },
+ func: function () {
+ proManager.closeAll(addTaskClass);
+ var addTask = ysy.settings.addTask;
+ addTask.setSilent("open", !addTask.open);
+ //if(!addTask.open){ysy.view.addTask.clear();}
+ addTask._fireChanges(this, "toggle");
+ },
+ isOn: function () {
+ return ysy.settings.addTask.open
+ },
+ isHidden: function () {
+ return ysy.settings.resource.open;
+ // return !ysy.settings.permissions.allowed("add_issues")
+ }
+ };
+ dhtmlx.dragScroll = function () {
+ var $background = $(".gantt_task_bg");
+ if (!$background.hasClass("inited")) {
+ $background.addClass("inited");
+ var dnd = new dhtmlxDnD($background[0], {marker: true});
+ var temp;
+ /*var lastScroll = null;
+ var addTask = false;
+ var startDate=null;
+ var endDate=null;*/
+ dnd.attachEvent("onDragStart", function () {
+ temp = {};
+ temp.addTask = ysy.settings.addTask.open;
+ if (temp.addTask) {
+ temp.addType = ysy.settings.addTask.type;
+ temp.startDate = gantt.dateFromPos(dnd.getRelativePos().x);
+ temp.lastScroll = gantt.getCachedScroll();
+ } else {
+ dnd.destroyMarker();
+ temp.lastScroll = gantt.getCachedScroll();
+ }
+ });
+ dnd.attachEvent("onDragMove", function () {
+ var diff = dnd.getDiff();
+ if (temp.addTask) {
+ //ysy.log.debug("POS="+(dnd.getRelativePos().x),"taskModal");
+ temp.endDate = gantt.dateFromPos(dnd.getRelativePos().x);
+ if (temp.addType === "milestone") {
+ temp.line = addTaskClass.modifyMileMarker(
+ dnd.config.marker,
+ {start_date: moment(temp.endDate)},
+ dnd.config.offset,
+ temp.lastScroll
+ );
+ } else {
+ temp.line = addTaskClass.modifyIssueMarker(
+ dnd.config.marker,
+ {start_date: moment(temp.startDate), end_date: moment(temp.endDate), type: temp.addType},
+ dnd.config.offset,
+ temp.lastScroll
+ );
+ }
+ } else {
+ gantt.scrollTo(Math.max(temp.lastScroll.x - diff.x, 0), undefined);
+ }
+ });
+ dnd.attachEvent("onDragEnd", function () {
+ if (temp.addTask) {
+ if (dnd.config.started) {
+ ysy.log.debug("start: " + temp.startDate.toString() + " end: " + temp.endDate.toString(), "taskModal");
+ var task = {start_date: moment(temp.startDate), end_date: moment(temp.endDate)};
+ addTaskClass.roundDates(task, temp.addType !== "milestone");
+ var preFill = {
+ start_date: task.start_date.format("YYYY-MM-DD"),
+ due_date: task.end_date.format("YYYY-MM-DD"),
+ project_id: ysy.settings.projectID
+ };
+ ysy.log.debug("line=" + temp.line, "taskModal");
+ //preFill.parent=ysy.pro.addTask.getMilestoneByLine(temp.line);
+ preFill.parent = addTaskClass.getIdByLine(temp.line, temp.addType);
+ addTaskClass.openModal(temp.addType, preFill);
+ }
+ }
+ });
+ }
+ };
+ },
+ close: function () {
+ var addTask = ysy.settings.addTask;
+ if (addTask.setSilent("open", false)) {
+ addTask._fireChanges(this, "close");
+ }
+ }
+};
+//#############################################################################################
+ysy.view.AddTaskPanel = function () {
+ ysy.view.Widget.call(this);
+};
+ysy.main.extender(ysy.view.Widget, ysy.view.AddTaskPanel, {
+ name: "AddTaskPanelWidget",
+ templateName: "AddTaskPanel",
+ buttons: ["issue", "milestone"],
+ _repaintCore: function () {
+ var sett = ysy.settings.addTask;
+ var target = this.$target;
+ if (sett.open) {
+ target.show();
+ } else {
+ target.hide();
+ return;
+ }
+ target.find(".add_task_type").removeClass("active");
+ target.find("#add_task_" + sett.type).addClass("active");
+ this.tideFunctionality();
+ },
+ tideFunctionality: function () {
+ var types = this.buttons;
+ var $target = this.$target;
+ var model = this.model;
+ var self = this;
+ var bind = function (type) {
+ $target.find("#add_task_" + type).off("click").on("click", function () {
+ //ysy.log.debug("AddTask issue button pressed","taskModal");
+ if (model.type === type) {
+ ysy.pro.addTask.openModal(type);
+ } else {
+ model.setSilent("type", type);
+ model._fireChanges(self, "toggle");
+ }
+ });
+
+ };
+ for (var i = 0; i < types.length; i++) {
+ bind(types[i]);
+ }
+ this.$target.find("#button_add_task_help").off("click").on("click", ysy.proManager.showHelp);
+ }
+});
+//#############################################################
+$.extend(ysy.pro.addTask, {
+ openModal: function (addType, preFill) {
+ if (preFill === undefined) {
+ preFill = {project_id: ysy.settings.projectID};
+ }
+ if (addType === "milestone") {
+ preFill.due_date = moment(preFill.due_date).add(1, "days").format("YYYY-MM-DD");
+ }
+ if (preFill.parent) {
+ var parent = preFill.parent;
+ if (parent.id > 1000000000000) {
+ dhtmlx.message(ysy.settings.labels.errors2.unsaved_parent, "error");
+ return;
+ }
+ preFill.project_id = parent.project_id;
+ preFill.fixed_version_id = parent.type === 'milestone' ? parent.id : parent.fixed_version_id;
+ if (parent.type === 'task') {
+ preFill.parent_issue_id = parent.id;
+ }
+ delete preFill["parent"];
+ }
+ var $target = ysy.main.getModal("form-modal", "90%");
+ var submitFunc = function (e) {
+ var addTaskClass = ysy.pro.addTask;
+ if (window.fillFormTextAreaFromCKEditor) {
+ window.fillFormTextAreaFromCKEditor("issue_description");
+ window.fillFormTextAreaFromCKEditor("version_description");
+ }
+ if ($(this).is("form")) {
+ var data = $(this).serializeArray();
+ } else {
+ data = $target.find("form").serializeArray();
+ }
+ var errors = addTaskClass.collectErrors($target, data);
+ if (errors.length) {
+ dhtmlx.message(errors.join(" "), "error");
+ $("#content").find(".flash").appendTo('body');
+ return false;
+ }
+ var transformed = addTaskClass.transformData(data, addType);
+ if (addType === "milestone") {
+ addTaskClass.createMilestone(transformed);
+ } else {
+ addTaskClass.createIssue(transformed);
+ }
+ $target.dialog("close");
+ return false;
+ };
+ if (addType === "milestone") {
+ ysy.gateway.polymorficGet(ysy.settings.paths.newMilestonePath.replace(":projectID", preFill.project_id), {
+ version: preFill
+ }, function (data) {
+ var $content = $(data).find("#content");
+ if ($content.length) {
+ $target.html($content.html());
+ } else {
+ $target.html(data);
+ }
+ var project_id = $target.find("#version_project_id").val();
+ var title = $target.find("h2");
+ title.replaceWith($(" ").html(title.html()));
+ showModal("form-modal");
+ $target.find("input[type=submit], .form-actions").hide();
+ $target.find("#new_version").submit(submitFunc);
+ $target.dialog({
+ buttons: [
+ {
+ id: "add_milestone_modal_submit",
+ class: "button-1 button-positive",
+ text: ysy.settings.labels.buttons.create,
+ click: submitFunc
+ }
+ ]
+ });
+ $target.find("#version_name").focus();
+ });
+ } else {
+ ysy.gateway.polymorficGet(ysy.settings.paths.newIssuePath, {
+ issue: preFill
+ }, function (data) {
+ $target.html(data);
+ var title = $target.find("h2");
+ title.replaceWith($(" ").html(title.html()));
+ showModal("form-modal");
+ $target.find("input[type=submit], .form-actions").hide();
+ $target.dialog({
+ buttons: [
+ {
+ id: "add_issue_modal_submit",
+ class: "button-1 button-positive",
+ text: ysy.settings.labels.buttons.create,
+ click: submitFunc
+ }
+ ]
+ });
+ $target.find("#issue-form").submit(submitFunc);
+ if ($target.find("#project_id").length === 0) {
+ // because there may be no project field in EasyRedmine New issue form
+ $target.find("#issue-form").append($(' '));
+ }
+ window.initEasyAutocomplete();
+ $target.find("#issue_subject").focus();
+ });
+ }
+
+ },
+ collectErrors: function ($target, data) {
+ var errors = [];
+ var required = {};
+ $target.find("label > span.required").each(function () {
+ // finder for classic Redmine and Redmine-like inputs
+ var $label = $(this).parent("label");
+ var $input = $label.parent().find("#" + $label.attr("for"));
+ var label = $label.text();
+ var name = $input.attr("name");
+ if (name) {
+ required[name] = label.substring(0, label.length - 2);
+ }
+ });
+ for (var key in required) {
+ if (!required.hasOwnProperty(key)) continue;
+ var valid = false;
+ for (var i = 0; i < data.length; i++) {
+ if (data[i].name === key) {
+ if (data[i].value !== "") {
+ valid = true;
+ }
+ break;
+ }
+ }
+ if (!valid) {
+ errors.push(required[key] + " " + ysy.view.getLabel("addTask", "error_blank"));
+ }
+ }
+ return errors;
+ },
+ transformData: function (data, addType) {
+ var structured = ysy.main.formToJson(data);
+ if (addType == "issue") {
+ var entityStructured = structured.issue;
+ } else if (addType == "milestone") {
+ entityStructured = structured.version;
+ } else {
+ entityStructured = {};
+ }
+ var transformed = {
+ project_id: ysy.settings.project ? ysy.settings.project.id : null
+ };
+ var parseInteger = function (number) {
+ if (number === "") return null;
+ return parseInt(number);
+ };
+ var parseDecimal = function (number) {
+ if (number === "") return null;
+ return parseFloat(number);
+ };
+ var functionMap = {
+ // name: nothing,
+ is_private: parseInteger,
+ tracker_id: parseInteger,
+ status_id: parseInteger,
+ // status: nothing,
+ // sharing: nothing,
+ // subject: nothing,
+ // description: nothing,
+ priority_id: parseInteger,
+ project_id: parseInteger,
+ assigned_to_id: parseInteger,
+ fixed_version_id: parseInteger,
+ easy_version_category_id: parseInteger,
+ old_fixed_version_id: parseInteger,
+ parent_issue_id: parseInteger,
+ // start_date: nothing,
+ // due_date: nothing,
+ effective_date: function (value) {
+ transformed.start_date = value;
+ return null;
+ },
+ estimated_hours: parseDecimal,
+ done_ratio: parseInteger,
+ // custom_field_values: nothing,
+ // easy_distributed_tasks: nothing,
+ // easy_repeat_settings: nothing,
+ // easy_repeat_simple_repeat_end_at: nothing,
+ // watcher_user_ids: nothing,
+ // easy_ldap_entity_mapping: nothing,
+ // skip_estimated_hours_validation: nothing,
+ activity_id: parseInteger
+ };
+ var entityKeys = Object.getOwnPropertyNames(entityStructured);
+ for (var i = 0; i < entityKeys.length; i++) {
+ var key = entityKeys[i];
+ if (functionMap.hasOwnProperty(key)) {
+ var parsed = functionMap[key](entityStructured[key], key);
+ } else {
+ parsed = entityStructured[key];
+ }
+ transformed[key] = parsed;
+ }
+ return transformed;
+ },
+ roundDates: function (task, sort) {
+ if (task.end_date) {
+ if (sort && task.end_date < task.start_date) {
+ task.end_date.add(12, "hours");
+ var end = task.end_date;
+ task.end_date = task.start_date;
+ task.start_date = end;
+ } else {
+ task.end_date.add(-12, "hours");
+ }
+ task.end_date._isEndDate = true;
+ gantt.date.date_part(task.end_date);
+ }
+ gantt.date.date_part(task.start_date);
+ },
+ createIssue: function (jissue) {
+ ysy.log.debug("creating issue " + JSON.stringify(jissue), "taskModal");
+ $.extend(jissue, {
+ id: dhtmlx.uid(),
+ name: jissue.subject,
+ //progress:0,
+ columns: {
+ subject: jissue.subject
+ },
+ permissions: {
+ editable: true
+ },
+ css: "fresh"
+ });
+ var issue = new ysy.data.Issue();
+ issue.init(jissue);
+ ysy.data.issues.push(issue);
+ gantt._selected_task = issue.getID();
+ },
+ createMilestone: function (jmile) {
+ ysy.log.debug("creating milestone " + JSON.stringify(jmile), "taskModal");
+ $.extend(jmile, {
+ id: dhtmlx.uid(),
+ permissions: {
+ editable: true
+ },
+ css: "fresh"
+ });
+ var mile = new ysy.data.Milestone();
+ mile.init(jmile);
+ ysy.data.milestones.push(mile);
+ gantt._selected_task = mile.getID();
+ },
+ modifyIssueMarker: function ($marker, task, offset, lastScroll) {
+ this.roundDates(task, true);
+ //var pos = gantt._get_task_pos(task);
+ var posx = gantt.posFromDate(task.start_date);
+ var cfg = gantt.config;
+ var height = gantt._get_task_height();
+ var row_height = cfg.row_height;
+ var padd = Math.floor((row_height - height) / 2);
+
+ var top = parseFloat($marker.style.top) - offset.top;
+ top = Math.max(top, lastScroll.y);
+ var line = Math.floor(top / row_height);
+ var clampedLine = Math.min(Math.max(line, 0), gantt._order.length - 1);
+
+ //ysy.log.debug("offset: "+offset.top+" scroll: "+lastScroll.y+" line: "+line,"add_task_marker");
+
+ var roundedTop = clampedLine * row_height + padd;
+ var width = gantt.posFromDate(task.end_date) - posx;
+ //var div = document.createElement("div");
+ //var width = gantt._get_task_width(task);
+ $marker.className = "gantt_task_line planned gantt_" + task.type + "-type";
+ $marker.innerHTML = '
';
+ var styles = [
+ "left:" + (posx + offset.left) + "px",
+ "top:" + (roundedTop + offset.top) + "px",
+ "height:" + height + 'px',
+ //"line-height:" + height + 'px',
+ "width:" + width + 'px'
+ ];
+
+ $marker.style.cssText = styles.join(";");
+ return line;
+ },
+ modifyMileMarker: function ($marker, task, offset, lastScroll) {
+ gantt._working_time_helper.round_date(task.start_date);
+ //var pos = gantt._get_task_pos(task);
+ var posx = gantt.posFromDate(task.start_date);
+ var cfg = gantt.config;
+ var row_height = cfg.row_height;
+ var height = gantt._get_task_height();
+
+ var padd = Math.floor((row_height - height) / 2);
+ var top = parseFloat($marker.style.top) - offset.top;
+ top = Math.max(top, lastScroll.y);
+ var line = Math.floor(top / row_height);
+ var clampedLine = Math.min(Math.max(line, 0), gantt._order.length - 1);
+ var roundedTop = clampedLine * row_height + padd;
+ //ysy.log.debug("top="+top+", rTop="+roundedTop);
+ $marker.className = "gantt_task_line planned gantt_milestone-type";
+ $marker.innerHTML = '
';
+ var styles = [
+ "left:" + (posx + offset.left - Math.floor(height / 2) - 1) + "px",
+ "top:" + (roundedTop + offset.top) + "px",
+ "height:" + height + 'px',
+ "line-height:" + height + 'px',
+ "width:" + height + 'px'
+ ];
+
+ $marker.style.cssText = styles.join(";");
+ return line;
+ },
+ allowedParent: {
+ issue: ["task", "milestone", "project"],
+ milestone: ["project"]
+ },
+ getIdByLine: function (line, type) {
+ var allowed = this.allowedParent[type];
+ var order = gantt._order;
+ if (line == order.length - 1) {
+ // empty line
+ return null;
+ }
+ if (line < 0 || line >= order.length) {
+ ysy.log.debug("wrong line number", "taskModal");
+ return null;
+ }
+ var targetID = order[line];
+ var task = gantt.getTask(targetID);
+ if (!task) {
+ ysy.log.debug("task not found", "taskModal");
+ return null;
+ }
+ for (var i = 0; i < allowed.length; i++) {
+ if (gantt._get_safe_type(task.type) === allowed[i]) {
+ return {
+ id: task.real_id,
+ type: task.type,
+ project_id: task.widget.model.project_id,
+ fixed_version_id: task.widget.model.fixed_version_id
+ };
+ }
+ }
+ return this.getIdByLine(line - 1, type);
+ }
+});
diff --git a/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/baseline.js b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/baseline.js
new file mode 100644
index 0000000..37f478b
--- /dev/null
+++ b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/baseline.js
@@ -0,0 +1,427 @@
+/**
+ * Created by Ringael on 5. 8. 2015.
+ */
+window.ysy = window.ysy || {};
+ysy.pro = ysy.pro || {};
+ysy.pro.baseline = {
+ name: "Baseline PRO",
+ initToolbar: function (ctx) {
+ var baselinePanel = new ysy.view.BaselinePanel();
+ baselinePanel.init(ysy.data.baselines, ysy.settings.baseline);
+ ctx.children.push(baselinePanel);
+ },
+ patch: function () {
+ var baselineClass = ysy.pro.baseline;
+ ysy.proManager.register("initToolbar", this.initToolbar);
+ ysy.proManager.register("close", this.close);
+ ysy.proManager.register("ganttConfig", this.ganttConfig);
+
+
+ ysy.view.AllButtons.prototype.extendees.baseline = {
+ bind: function () {
+ this.model = ysy.settings.baseline;
+ this._register(ysy.settings.resource);
+ },
+ func: function () {
+ ysy.proManager.closeAll(baselineClass);
+ var sett = ysy.settings.baseline;
+ sett.setSilent("open", !sett.open);
+ sett._fireChanges(this, "toggle");
+ },
+ isOn: function () {
+ return ysy.settings.baseline.open;
+ },
+ isHidden: function () {
+ return ysy.settings.resource.open;
+ },
+ //model:ysy.settings.baseline,
+ icon: "projects"
+ };
+ ysy.view.columnBuilders = ysy.view.columnBuilders || {};
+ ysy.view.columnBuilders.baseline_start_date = function (task) {
+ var base = ysy.pro.baseline._getBaselineForTask(task);
+ if (!base || !base.start_date) return;
+ if (base.start_date.isSame(task.start_date))
+ return '' + ysy.settings.labels.baselines.label_same + ' ';
+ return '' + base.start_date.format(gantt.config.date_format) + ' ';
+ };
+ ysy.view.columnBuilders.baseline_end_date = function (task) {
+ var base = ysy.pro.baseline._getBaselineForTask(task);
+ if (!base || !base.end_date) return;
+ if (base.end_date.isSame(task.end_date))
+ return '' + ysy.settings.labels.baselines.label_same + ' ';
+ return '' + base.end_date.format(gantt.config.date_format) + ' ';
+ };
+ ysy.view.Gantt.prototype.addBaselineLayer = function (ctx) {
+ baselineClass.addLayer();
+ };
+ ysy.settings.baseline.register(this.settingWatcher, this);
+ },
+ settingWatcher: function () {
+ var settings = ysy.settings.baseline;
+ //ysy.log.debug("settings.baseline onChange ["+settings.open+","+settings.active+"]","baseline");
+ // GET ACTIVE BASELINE
+ if (settings.open && settings.active) {
+ var active = settings.active;
+ var baseline = ysy.data.baselines.getByID(active);
+ if (!baseline.loaded) {
+ ysy.log.debug("loadBaseline " + active, "baseline");
+ ysy.data.baselines.getByID(active).fetch();
+ return;
+ }
+ }
+ // GET BASELINE HEADER
+ //ysy.log.debug("settings.baseline onChange ["+settings.open+","+settings.active+"]","baseline");
+ if (settings.open && !settings.headerLoaded) {
+ ysy.log.debug("loadBaselineHeader", "baseline");
+ ysy.gateway.loadBaselineHeader(function (data) {
+ var baselines = ysy.data.baselines;
+ //baselines.clearSilent();
+ var base_array = baselines.getArray();
+ for (var i = 0; i < base_array.length; i++) {
+ base_array[i]._deleted = true;
+ }
+ baselines.clearCache();
+ var array = data.easy_baselines;
+ for (i = 0; i < array.length; i++) {
+ var base_data = array[i];
+ var baseline = baselines.getByID(base_data.id);
+ if (!baseline) baseline = new ysy.data.Baseline();
+ baseline.init(base_data, ysy.data.baselines);
+ baseline._deleted = false;
+ baselines.pushSilent(baseline);
+ }
+ //ysy.log.debug("header loaded","baseline");
+ baselines._fireChanges(ysy.settings.baseline, "header loaded");
+ if (!settings.active && baselines.getArray().length) {
+ var arr = baselines.getArray();
+ var last = arr[arr.length - 1];
+ settings.setSilent("active", last.id);
+ ysy.log.debug("last baseline ID=" + last.id + " active", "baseline");
+ last.fetch();
+ //settings._fireChanges(this,"first baseline active");
+ }
+ });
+ settings.headerLoaded = true;
+ return;
+ }
+ ysy.log.debug("Baseline: gantt.render()", "baseline");
+ ysy.view.initGantt();
+ if (ysy.settings.baseline.open) {
+ $("#gantt_cont").addClass("gantt-baselines");
+ } else {
+ $("#gantt_cont").removeClass("gantt-baselines");
+ }
+ //ysy.pro.baseline.addLayer();
+ gantt.render();
+ },
+ close: function () {
+ var sett = ysy.settings.baseline;
+ if (sett.setSilent("open", false)) {
+ sett._fireChanges(this, "close");
+ }
+ },
+ resetHeader: function () {
+ ysy.settings.baseline.setSilent("headerLoaded", false);
+ ysy.settings.baseline.setSilent("active", false);
+ ysy.settings.baseline._fireChanges(this, "reload after saveBaseline");
+ },
+ _getBaselineForTask: function (task) {
+ var baseline = ysy.data.baselines.getByID(ysy.settings.baseline.active);
+ if (!baseline || !baseline.loaded) return;
+ //ysy.log.debug("baseline drawn for task "+task.id,"baseline");
+ ysy.log.debug("baseline drawn", "baseline_render");
+ if (task.type === gantt.config.types.milestone) {
+ var base = baseline.versions[task.real_id];
+ } else if (gantt._get_safe_type(task.type) === gantt.config.types.task) {
+ base = baseline.issues[task.real_id];
+ }
+ return base;
+ },
+ addLayer: function () {
+ if (!ysy.settings.baseline.open) return;
+ var layer = gantt.addTaskLayer(function draw_planned(task) {
+ if (!ysy.settings.baseline.open) return;
+ if (!ysy.settings.baseline.active) return;
+ var base = ysy.pro.baseline._getBaselineForTask(task);
+ if (!base) return;
+ var base_start = base.start_date;
+ var base_end = base.end_date;
+ ysy.log.debug("start=" + task.start_date.format("DD.MM.YYYY") + " bstart=" + base.start_date.format("DD.MM.YYYY"), "baseline_render");
+ /*if (!task.base_start){
+ task.base_start=moment(task.start_date);
+ }
+ if(!task.base_end) {
+ task.base_end=gantt.date.Date(task.end_date);
+ }*/
+ var sizes = gantt.getTaskPosition(task, base_start, base_end);
+ var className = 'gantt-baseline';
+ if (task.type === "milestone") {
+ var side = sizes.height;
+ sizes.width = side;
+ sizes.left -= side / 2 + 1;
+ className += " gantt_milestone-type";
+ } else {
+ sizes.width -= 2;
+ delete sizes.height;
+ }
+ var el = document.createElement('div');
+ el.className = className;
+ el.style.left = sizes.left + 'px';
+ if (sizes.height) {
+ el.style.height = sizes.height + 'px';
+ }
+ el.style.width = sizes.width + 'px';
+ el.style.top = sizes.top + gantt.config.task_height + 13 + 'px';
+ return el;
+ });
+ ysy.log.debug("TaskLayer ID=" + layer + " created", "baseline");
+ },
+ ganttConfig: function (config) {
+ if (!ysy.settings.baseline.open) return;
+ var labels = ysy.settings.labels.baselines;
+ var baselineColumns = [
+ {
+ name: "baseline_start_date",
+ title: labels.baseline + ' ' + labels.startDate
+ },
+ {
+ name: "baseline_end_date",
+ title: labels.baseline + ' ' + labels.dueDate
+ }
+ ];
+ var columns = gantt.config.columns;
+ columns = columns.concat(ysy.view.leftGrid.constructColumns(baselineColumns));
+ $.extend(config, {
+ columns: columns,
+ task_height: 16,
+ row_height: 40
+ });
+ }
+};
+//#############################################################################################
+ysy.view.BaselinePanel = function () {
+ ysy.view.Widget.call(this);
+};
+ysy.main.extender(ysy.view.Widget, ysy.view.BaselinePanel, {
+ name: "BaselinePanelWidget",
+ templateName: "BaselineOption",
+ _repaintCore: function () {
+ var sett = ysy.settings.baseline;
+ var target = this.$target;
+ if (sett.open) {
+ target.show();
+ } else {
+ target.hide();
+ return;
+ }
+ if (!this.template) {
+ var templ = ysy.view.getTemplate(this.templateName);
+ if (templ) {
+ this.template = templ;
+ } else {
+ return true;
+ }
+ }
+ var baseOut = [
+ //{name:"None selected",id:"none"}
+ ];
+ var model = this.model.getArray();
+ if (model.length === 0) {
+ target.find("#baseline_select").hide();
+ target.find("#baseline_delete").hide();
+ } else {
+ for (var i = 0; i < model.length; i++) {
+ baseOut.push({name: model[i].name, id: model[i].id, selected: model[i].id === sett.active ? " selected" : ""});
+ }
+ var rendered = Mustache.render(this.template, {baselines: baseOut});
+ target.find("#baseline_select").show().html(rendered);
+ target.find("#baseline_delete").show();
+ }
+
+ this.tideFunctionality();
+ },
+ tideFunctionality: function () {
+ var baselineClass = ysy.pro.baseline;
+ this.$target.find("#baseline_select").off("change").on("change", function (event) {
+ var baseID = parseInt($(this).val());
+ ysy.settings.baseline.setSilent("active", baseID);
+ ysy.settings.baseline._fireChanges(ysy.view.BaselinePanel, "select")
+ });
+ this.$target.find("#baseline_create:not(.disabled)").off("click").on("click", function () {
+ ysy.log.debug("Create baseline button pressed", "baseline");
+ if (!ysy.history.isEmpty()) {
+ dhtmlx.message(ysy.settings.labels.baselines.error_not_saved, "error");
+ return;
+ }
+ baselineClass.openCreateModal();
+ });
+ this.$target.find("#baseline_delete:not(.disabled)").off("click").on("click", function () {
+ ysy.log.debug("Delete baseline button pressed", "baseline");
+ var baseline = ysy.data.baselines.getByID(ysy.settings.baseline.active);
+ if (!baseline) return;
+ var confirmLabel = $(this).data("confirmation");
+ var confirmation = window.confirm(confirmLabel);
+ if (!confirmation) return;
+ ysy.gateway.deleteBaseline(baseline.id, function () {
+ ysy.log.debug("deleteBaseline callback", "baseline");
+ baselineClass.resetHeader();
+ },
+ function (response) {
+ // FAIL
+ var responseJSON = response.responseJSON;
+ if (responseJSON && responseJSON.errors) {
+ var errors = responseJSON.errors.join(", ");
+ }
+ dhtmlx.message(ysy.view.getLabel("baseline", "delete_failed") + ": " + errors, "error");
+ });
+ });
+ this.$target.find("#button_baseline_help").off("click").on("click", ysy.proManager.showHelp);
+ }
+});
+//##################################################################################################
+ysy.pro.baseline.openCreateModal = function () {
+
+ var generic = moment().format(gantt.config.date_format + " HH:mm") + " " + ysy.settings.project.name;
+ var $target = ysy.main.getModal("form-modal", "50%");
+ var submitFce = function () {
+ var name = $target.find("#baseline_modal_name").val();
+ ysy.gateway.saveBaseline(name, function (data) {
+ ysy.log.debug("saveBaseline callback", "baseline");
+ ysy.pro.baseline.resetHeader();
+ //var baselines = ysy.data.baselines;
+ //var baseline = new ysy.data.Baseline();
+ //baseline.init({
+ // name: data.easy_baseline.name || name || generic,
+ // id: data.easy_baseline.id,
+ // mapping: data
+ //}, baselines);
+ //baselines.pushSilent(baseline);
+ //baselines.clearCache();
+ //ysy.settings.baseline.setSilent("active", baseline.id);
+ //ysy.settings.baseline._fireChanges(ysy.pro.baseline, "baseline saved");
+ },
+ function (response) {
+ // FAIL
+ var responseText = response.responseText;
+ try {
+ var json = JSON.parse(responseText);
+ if (json.errors.length) {
+ responseText = json.errors.join(", ");
+ }
+ } catch (e) {
+ }
+ dhtmlx.message(ysy.view.getLabel("baselineCreateModal").request_failed + ": " + responseText, "error");
+ });
+ $target.dialog("close");
+ };
+
+ var template = ysy.view.getTemplate("baselineCreateModal");
+ //var labels=
+ var obj = $.extend({}, ysy.view.getLabel("baselineCreateModal"), {generic: generic});
+ var rendered = Mustache.render(template, obj);
+ $target.html(rendered);
+ showModal("form-modal");
+ $target.dialog({
+ buttons: [
+ {
+ id: "baseline_modal_submit",
+ text: ysy.settings.labels.buttons.button_submit,
+ class: "button-1 button-positive",
+ click: submitFce
+ },
+ {
+ id: "baseline_modal_cancel",
+ text: ysy.settings.labels.buttons.button_cancel,
+ class: "button-2",
+ click: function () {
+ $target.dialog("close");
+ }
+ }
+ ]
+ });
+};
+//##################################################################################################
+ysy.data.Baseline = function () {
+ ysy.data.Data.call(this);
+};
+ysy.main.extender(ysy.data.Data, ysy.data.Baseline, {
+ _name: "Baseline",
+ fetch: function () {
+ var thiss = this;
+ ysy.log.debug("baseline " + this.id + " fetch", "baseline");
+ if (this.loaded) {
+ ysy.settings.baseline._fireChanges(this, "baseline active and loaded");
+ return;
+ } else if (!this.isLoading) {
+ ysy.gateway.loadBaselineData(this.id, function (data) {
+ thiss.construct(data.easy_baseline_gantt);
+ thiss.loaded = true;
+ thiss.isLoading = false;
+ //ysy.log.debug("SourceData of baseline " + thiss.id + " loaded", "baseline");
+ thiss.fetch();
+ });
+ }
+ this.isLoading = true;
+ },
+ construct: function (data) {
+ this.issues = {};
+ for (var i = 0; i < data.issues.length; i++) {
+ var source = data.issues[i];
+ var target = {
+ start_date: source.start_date ? moment(source.start_date, "YYYY-MM-DD") : moment().startOf("day"),
+ end_date: source.due_date ? moment(source.due_date, "YYYY-MM-DD") : moment().startOf("day"),
+ done_ratio: source.done_ratio,
+ id: source.connected_to_issue_id
+ };
+ if (target.start_date.isAfter(target.end_date)) {
+ if (source.start_date) {
+ target.end_date = moment(target.start_date);
+ } else {
+ target.start_date = moment(target.end_date);
+ }
+ }
+ target.end_date._isEndDate = true;
+ this.issues[target.id] = target;
+ }
+ this.versions = {};
+ for (i = 0; i < data.versions.length; i++) {
+ source = data.versions[i];
+ target = {
+ start_date: moment(source.start_date, "YYYY-MM_DD"),
+ id: source.connected_to_version_id
+ };
+ target.start_date._isEndDate = true;
+ this.versions[target.id] = target;
+ }
+ }
+});
+if (ysy.gateway === undefined) {
+ ysy.gateway = {};
+}
+$.extend(ysy.gateway, {
+ loadBaselineHeader: function (callback) {
+ var urlTemplate = ysy.settings.paths.baselineRoot;
+ this.polymorficGetJSON(urlTemplate, null, callback);
+ },
+ loadBaselineData: function (baselineID, callback) {
+ var urlTemplate = ysy.settings.paths.baselineGET.replace(":baselineID", baselineID);
+ this.polymorficGetJSON(urlTemplate, null, callback);
+ },
+ saveBaseline: function (name, callback, fail) {
+ ysy.log.debug("Create baseline request", "baseline");
+ //return callback();
+ var data = null;
+ if (name) {
+ data = {easy_baseline: {name: name}};
+ }
+ var urlTemplate = ysy.settings.paths.baselineRoot;
+ this.polymorficPost(urlTemplate, null, data, callback, fail);
+ },
+ deleteBaseline: function (baselineID, callback) {
+ ysy.log.debug("Delete baseline ID=" + baselineID + " request", "baseline");
+ //return callback();
+ var urlTemplate = ysy.settings.paths.baselineDELETE.replace(":baselineID", baselineID);
+ this.polymorficDelete(urlTemplate, null, callback);
+ }
+});
diff --git a/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/common.js b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/common.js
new file mode 100644
index 0000000..c87729e
--- /dev/null
+++ b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/common.js
@@ -0,0 +1,79 @@
+/**
+ * Created by Ringael on 2. 11. 2015.
+ */
+window.ysy = window.ysy || {};
+ysy.pro = ysy.pro || {};
+ysy.pro.common = ysy.pro.common || {};
+$.extend(ysy.pro.common, {
+ patch: function () {
+ ysy.proManager.register("ganttConfig", this.ganttConfig);
+ ysy.view.columnBuilders = ysy.view.columnBuilders || {};
+ ysy.view.columnBuilders.name = function (obj) {
+ var id = parseInt(obj.real_id);
+ if (isNaN(id) || id > 1000000000000) return obj.text;
+ if (obj.type === "project") {
+ var nonLoadedIssues = obj.widget && obj.widget.model.issues_count;
+ var path = ysy.settings.paths.rootPath + "projects/";
+ return "" + obj.text + " "
+ + (nonLoadedIssues ? "" + nonLoadedIssues + " " : "");
+ }
+ };
+ $.extend(ysy.data.loader, {
+ loadProject: function (projectID) {
+ var self = this;
+ ysy.gateway.polymorficGetJSON(
+ ysy.settings.paths.subprojectGantt
+ .replace(new RegExp('(:|\%3A)projectID', 'g'), projectID),
+ null,
+ function (data) {
+ self._handleProjectData(data, projectID);
+ },
+ function () {
+ ysy.log.error("Error: Unable to load data");
+ }
+ );
+ return true;
+ },
+ _handleProjectData: function (data, projectID) {
+ var json = data.easy_gantt_data;
+ // -- PROJECTS --
+ this._loadProjects(json.projects);
+ // -- ISSUES --
+ this._loadIssues(json.issues, projectID);
+ // -- RELATIONS --
+ this._loadRelations(json.relations);
+ // -- MILESTONES --
+ this._loadMilestones(json.versions);
+ ysy.log.debug("minor data loaded", "load");
+ this._fireChanges();
+ },
+ loadProjectIssues: function (projectID) {
+ ysy.gateway.polymorficGetJSON(
+ ysy.settings.paths.projectOpenedIssues
+ .replace(new RegExp('(:|\%3A)projectID', 'g'), projectID),
+ null,
+ $.proxy(this._handleProjectData, this),
+ function () {
+ ysy.log.error("Error: Unable to load data");
+ }
+ );
+ return true;
+ },
+ openIssuesOfProject: function (projectID) {
+ var project = ysy.data.projects.getByID(projectID);
+ if (!project) return;
+ ysy.data.limits.openings["s" + projectID] = true;
+ if (!project.issues_count) return;
+ delete project.issues_count;
+ gantt.open(project.getID());
+ this.loadProjectIssues(projectID);
+ }
+ });
+ },
+ ganttConfig: function (config) {
+ $.extend(config, {
+ allowedParent_task: ["project", "milestone", "task", "empty"],
+ allowedParent_task_global: ["project", "milestone", "task"]
+ });
+ }
+});
diff --git a/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/critical.js b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/critical.js
new file mode 100644
index 0000000..83d57a7
--- /dev/null
+++ b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/critical.js
@@ -0,0 +1,337 @@
+window.ysy = window.ysy || {};
+ysy.pro = ysy.pro || {};
+ysy.pro.critical = {
+ name: "CriticalPath",
+ patch: function () {
+ if(ysy.settings.criticalType === 'disabled') {
+ ysy.pro.critical = null;
+ return;
+ }
+ ysy.proManager.register("extendGanttTask", this.extendGanttTask);
+ ysy.proManager.register("close", this.close);
+ ysy.proManager.register("initToolbar", this.initToolbar);
+ $.extend(ysy.view.AllButtons.prototype.extendees, {
+ critical: {
+ bind: function () {
+ this.model = ysy.settings.critical;
+ this._register(ysy.settings.resource);
+ },
+ func: function () {
+ ysy.proManager.closeAll(ysy.pro.critical);
+ var critical = ysy.settings.critical;
+ critical.setSilent("open", !critical.open);
+ ysy.pro.critical.toggle(critical.open);
+ //critical._fireChanges(this, "toggle");
+ },
+ isOn: function () {
+ return ysy.settings.critical.open
+ },
+ isHidden: function () {
+ return ysy.settings.resource.open;
+ }
+ },
+ show_only_critical: {
+ bind: function () {
+ this.model = ysy.settings.critical;
+ },
+ func: function () {
+ this.model.show_only_critical = !this.model.show_only_critical;
+ ysy.pro.critical.updateRegistration(this.model.show_only_critical);
+ this.model._fireChanges(this, "click");
+ },
+ isOn: function () {
+ return this.model.show_only_critical;
+ }
+ }
+ });
+ },
+ byLongestPath: {
+ critie_arr: null,
+ crities: null,
+ _construct: function () {
+ var issues = ysy.data.issues.getArray();
+ var relations = ysy.data.relations.getArray();
+ var crities = {};
+ var critie_arr = [];
+ for (var i = 0; i < issues.length; i++) {
+ var issue = issues[i];
+ var critie = {
+ issue: issue,
+ duration: issue.getDuration("days"),
+ source: [],
+ target: [],
+ longest: null
+ };
+ crities[issue.id] = critie;
+ critie_arr.push(critie);
+ }
+ for (i = 0; i < relations.length; i++) {
+ var relation = relations[i];
+ if (relation.isSimple) continue;
+ var source_critie = crities[relation.source_id];
+ var target_critie = crities[relation.target_id];
+ if (source_critie && target_critie) {
+ source_critie.source.push(relation);
+ target_critie.target.push(relation);
+ } else {
+ if (!source_critie) {
+ ysy.log.debug("source_critie " + relation.source_id + " missing", "critical");
+ }
+ if (!target_critie) {
+ ysy.log.debug("target_critie " + relation.target_id + " missing", "critical");
+ }
+ }
+ }
+ this.crities = crities;
+ this.critie_arr = critie_arr;
+ for (i = 0; i < critie_arr.length; i++) {
+ critie = critie_arr[i];
+ this._resolve(critie);
+ }
+ return this.crities;
+ },
+ _resolve: function (critie) {
+ if (critie.longest !== null) return;
+ var bestLongest = 0;
+ for (var i = 0; i < critie.target.length; i++) { // iterate over relations which targets critie
+ var relation = critie.target[i];
+ var prevCritie = this.crities[relation.source_id];
+ if (!prevCritie) {
+ ysy.log.warning("nextCritie missing");
+ continue;
+ }
+ this._resolve(prevCritie);
+ var longest = prevCritie.longest
+ + relation.delay
+ - (relation.type === "start_to_finish" || relation.type === "finish_to_finish" ? critie.duration : 0)
+ - (relation.type === "start_to_start" || relation.type === "start_to_finish" ? prevCritie.duration : 0);
+
+ if (longest > bestLongest) {
+ critie.prevMain = prevCritie;
+ bestLongest = longest;
+ }
+ }
+ critie.longest = bestLongest + critie.duration;
+ },
+ findPath: function () {
+ if (!this.critie_arr) {
+ this._construct();
+ }
+ var looser = null;
+ var longest = 0;
+ for (var i = 0; i < this.critie_arr.length; i++) {
+ var critie = this.critie_arr[i];
+ if (longest < critie.longest) {
+ longest = critie.longest;
+ looser = critie;
+ }
+ }
+ var path = {};
+ var last = null;
+ if (looser) {
+ while (looser.prevMain) {
+ last = looser.issue.id;
+ path[last] = true;
+ looser = looser.prevMain;
+ }
+ last = looser.issue.id;
+ path[last] = true;
+ path["last"] = last;
+ }
+ this.reset();
+ ysy.log.debug("findPath() path=" + JSON.stringify(path), "critical");
+ return path;
+ //this.path=path;
+ //gantt.selectTask(path[path.length-1]);
+ },
+ reset: function () {
+ this.critie_arr = null;
+ this.crities = null;
+ this.path = null;
+ }
+ },
+ byLastIssue: {
+ findPath: function () {
+ var issues = ysy.data.issues.getArray();
+
+ var lastIssues = [];
+ var lastDate = null;
+ for (var i = 0; i < issues.length; i++) {
+ var issue = issues[i];
+ if (!issue._end_date.isValid()) continue;
+ if (lastDate !== null) {
+ if (lastDate.isAfter(issue._end_date)) continue;
+ if (lastDate.isBefore(issue._end_date)) {
+ //lastDate = issue.end_date;
+ lastIssues = [];
+ }
+ }
+ lastDate = issue._end_date;
+ lastIssues.push(issue);
+ }
+ if (lastIssues.length === 0) {
+ return {};
+ }
+ var path = {};
+ var soonestIssue = lastIssues[0];
+ for (i = 0; i < lastIssues.length; i++) {
+ issue = lastIssues[i];
+ path[issue.id] = issue;
+ if (soonestIssue._start_date.isAfter(issue._start_date)) {
+ soonestIssue = issue;
+ }
+ var predecessor = this._resolve(issue, path);
+ if (predecessor !== null && predecessor._start_date.isBefore(soonestIssue._start_date)) {
+ soonestIssue = predecessor;
+ }
+ }
+ path["last"] = soonestIssue.id;
+ return path;
+ },
+ _resolve: function (issue, path) {
+ var relations = ysy.data.relations.getArray();
+ var soonestIssue = null;
+ for (var i = 0; i < relations.length; i++) {
+ var relation = relations[i];
+ if (relation.isSimple) continue;
+ if (relation.getTarget() !== issue) continue;
+ //if (relation.type !== "precedes") continue;
+
+ var diff = relation.getActDelay() - relation.delay;
+ var source = relation.getSource();
+ if (diff > 0) continue;
+ // var gapStart = relation.getSourceDate(source);
+ // var gapEnd = moment(gapStart).add(diff, "days");
+ // gapEnd._isEndDate = gapStart._isEndDate;
+ // if (gantt._working_time_helper.is_work_units_between(gapStart, gapEnd, "day")) continue;
+ path[source.id] = source;
+ if (soonestIssue === null || source._start_date.isBefore(soonestIssue._start_date)) {
+ soonestIssue = source;
+ }
+ var predecessor = this._resolve(source, path);
+ if (predecessor !== null
+ && (soonestIssue === null
+ || predecessor._start_date.isBefore(soonestIssue._start_date)
+ )) {
+ soonestIssue = predecessor;
+ }
+ }
+ return soonestIssue;
+ }
+
+ },
+ findPath: function () {
+ if (ysy.settings.criticalType === "last") return this.byLastIssue.findPath();
+ if (ysy.settings.criticalType === "longest") return this.byLongestPath.findPath();
+ return {};
+ },
+ getPath: function () {
+ var critical = ysy.settings.critical;
+ if (critical.open === false) return null;
+ if (critical.active === false) return null;
+ var path;
+ if (critical._cache) {
+ return critical._cache;
+ }
+ path = ysy.pro.critical.findPath();
+ critical._cache = path;
+ if (critical._prevCache) {
+ for (var key in critical._prevCache) {
+ if (!critical._prevCache.hasOwnProperty(key)) continue;
+ if (!path[key]) {
+ gantt.refreshTask(key);
+ }
+ }
+ for (key in path) {
+ if (!path.hasOwnProperty(key)) continue;
+ if (!critical._prevCache[key]) {
+ gantt.refreshTask(key);
+ }
+ }
+ }
+ critical._prevCache = path;
+ window.setTimeout(function () {
+ critical._cache = null;
+ }, 0);
+ return path;
+ },
+ updateRegistration: function (isOn) {
+ if (isOn) {
+ ysy.proManager.register("filterTask", this.filterTask);
+ } else {
+ ysy.proManager.unregister("filterTask", this.filterTask);
+ }
+ }
+ ,
+ filterTask: function (id, task) {
+ if (task.type === "task") {
+ var path = ysy.pro.critical.getPath();
+ return !!(path && path[task.real_id]);
+ }
+ return true;
+ },
+ toggle: function (state) {
+ var critical = ysy.settings.critical;
+ critical.setSilent("active", state === undefined ? !critical.active : state);
+ if (critical.active) {
+ var last = ysy.pro.critical.getPath()["last"];
+ if (gantt.isTaskExists(last)) {
+ gantt.selectTask(last);
+ } else {
+ gantt._selected_task = last;
+ }
+ }
+ critical._fireChanges(this, "toggle");
+ },
+ close: function () {
+ var sett = ysy.settings.critical;
+ if (sett.setSilent("open", false)) {
+ ysy.pro.critical.updateRegistration(false);
+ sett._fireChanges(this, "close");
+ }
+ },
+ initToolbar: function (ctx) {
+ var criticalPanel = new ysy.view.CriticalPanel();
+ criticalPanel.init(ysy.settings.critical);
+ ctx.children.push(criticalPanel);
+ },
+ extendGanttTask: function (issue, gantt_issue) {
+ var path = ysy.pro.critical.getPath();
+ if (path && path[issue.id]) {
+ gantt_issue.css += " critical";
+ }
+ }
+
+
+};
+//#############################################################################################
+ysy.view = ysy.view || {};
+ysy.view.CriticalPanel = function () {
+ ysy.view.Widget.call(this);
+};
+ysy.main.extender(ysy.view.Widget, ysy.view.CriticalPanel, {
+ name: "CriticalPanelWidget",
+ templateName: "CriticalPanel",
+ _repaintCore: function () {
+ var sett = ysy.settings.critical;
+ var target = this.$target;
+ if (sett.open) {
+ target.show();
+ } else {
+ target.hide();
+ }
+ if (sett.active) {
+ target.find("#critical_show").addClass("active");
+ } else {
+ target.find("#critical_show").removeClass("active");
+ }
+ this.tideFunctionality();
+ },
+ tideFunctionality: function () {
+ this.$target.find("#critical_show").off("click").on("click", function (event) {
+ ysy.log.debug("Show Critical path button pressed", "critical");
+ ysy.pro.critical.toggle();
+ });
+ this.$target.find("#button_critical_help").off("click").on("click", ysy.proManager.showHelp);
+ }
+});
diff --git a/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/delayed_issues.js b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/delayed_issues.js
new file mode 100644
index 0000000..475f2a6
--- /dev/null
+++ b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/delayed_issues.js
@@ -0,0 +1,66 @@
+window.ysy = window.ysy || {};
+ysy.pro = ysy.pro || {};
+ysy.pro.delayed_issues = {
+ delayStates: null,
+ patch: function () {
+
+ ysy.pro.toolPanel.registerButton(
+ {
+ id: "delayed_issue_filter",
+ bind: function () {
+ this.model = ysy.data.limits;
+ },
+ func: function () {
+ this.model.filter_delayed_issues = !this.model.filter_delayed_issues;
+ ysy.pro.delayed_issues.updateRegistration(this.model.filter_delayed_issues);
+ if (this.model.filter_delayed_issues) {
+ ysy.pro.delayed_issues.decideDelayState();
+ }
+ this.model._fireChanges(this, "click");
+ },
+ isOn: function () {
+ return this.model.filter_delayed_issues;
+ },
+ isHidden: function () {
+ return ysy.settings.resource.open;
+ }
+ });
+ },
+ updateRegistration: function (isOn) {
+ if (isOn) {
+ ysy.proManager.register("filterTask", this.filterTask);
+ } else {
+ ysy.proManager.unregister("filterTask", this.filterTask);
+ }
+ },
+ decideDelayState: function () {
+ this.delayStates = {}; // true if delayed
+ for (var id in gantt._pull) {
+ if (!gantt._pull.hasOwnProperty(id)) continue;
+ this.decideIfTaskDelayed(id);
+ }
+ },
+ decideIfTaskDelayed: function (taskId) {
+ if (this.delayStates[taskId] !== undefined) return this.delayStates[taskId];
+ var task = gantt._pull[taskId];
+ if (task.type === "task") {
+ if (gantt._branches[task.id]) {
+ var branch = gantt._branches[task.id];
+ for (var i = 0; i < branch.length; i++) {
+ var childId = branch[i];
+ if (this.decideIfTaskDelayed(childId)) {
+ return this.delayStates[task.id] = true;
+ }
+ }
+ return this.delayStates[task.id] = false;
+ } else {
+ var diff = (moment() - task.start_date) / (86400000 + task.end_date - task.start_date);
+ return this.delayStates[task.id] = task.progress !== 1 && task.progress < diff;
+ }
+ }
+ return this.delayStates[task.id] = true;
+ },
+ filterTask: function (id, task) {
+ return ysy.pro.delayed_issues.delayStates[id];
+ }
+};
\ No newline at end of file
diff --git a/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/delayed_projects.js b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/delayed_projects.js
new file mode 100644
index 0000000..aa20474
--- /dev/null
+++ b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/delayed_projects.js
@@ -0,0 +1,53 @@
+window.ysy = window.ysy || {};
+ysy.pro = ysy.pro || {};
+ysy.pro.delayed_projects = {
+ patch: function () {
+ if (!ysy.settings.global) return;
+ if (!ysy.settings.showProjectProgress) return;
+ ysy.pro.toolPanel.registerButton(
+ {
+ id: "delayed_project_filter",
+ bind: function () {
+ this.model = ysy.data.limits;
+ },
+ func: function () {
+ this.model.filter_delayed_projects = !this.model.filter_delayed_projects;
+ ysy.pro.delayed_projects.updateRegistration(this.model.filter_delayed_projects);
+ this.model._fireChanges(this, "click");
+ },
+ isOn: function () {
+ return this.model.filter_delayed_projects;
+ },
+ isRemoved: function () {
+ return !ysy.settings.global;
+ }
+ });
+ var today = moment();
+ ysy.data.Project.prototype.problems = $.extend(ysy.data.Project.prototype.problems, {
+ overDue: function () {
+ if (this.done_ratio === 100) return;
+ if (!this.start_date) return;
+ if (!this.end_date) return;
+ // if (this.end_date.isBefore(today)) return ysy.settings.labels.problems.progressDateOverdue;
+ var progressDate = this.start_date + this.done_ratio / 100.0 * (this.end_date - this.start_date);
+ if (progressDate < today) {
+ return ysy.settings.labels.problems.progressDateOverdue.replace("%{days}",today.diff(progressDate,"days"));
+ }
+ }
+ });
+ },
+ updateRegistration: function (isOn) {
+ if (isOn) {
+ ysy.proManager.register("filterTask", this.filterTask);
+ } else {
+ ysy.proManager.unregister("filterTask", this.filterTask);
+ }
+ },
+ filterTask: function (id, task) {
+ if (task.type === "project") {
+ if (task.progress === 1) return false;
+ if (task.progress >= (moment() - task.start_date) / (task.end_date - task.start_date)) return false;
+ }
+ return true;
+ }
+};
\ No newline at end of file
diff --git a/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/easy_gantt_pro.js b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/easy_gantt_pro.js
new file mode 100644
index 0000000..559b47a
--- /dev/null
+++ b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/easy_gantt_pro.js
@@ -0,0 +1,12 @@
+/*
+ * COMMON
+ * = require easy_gantt_pro/common
+ * = require easy_gantt_pro/sorting
+ * = require easy_gantt_pro/email_silencer
+ * = require easy_gantt_pro/delayed_issues
+ *
+ * PROJECT SPECIFIC
+ * = require easy_gantt_pro/baseline
+ * = require easy_gantt_pro/add_task
+ * = require easy_gantt_pro/critical
+*/
diff --git a/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/easy_gantt_pro_global.js b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/easy_gantt_pro_global.js
new file mode 100644
index 0000000..87c7f12
--- /dev/null
+++ b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/easy_gantt_pro_global.js
@@ -0,0 +1,13 @@
+/*
+ * COMMON
+ * = require easy_gantt_pro/common
+ * = require easy_gantt_pro/sorting
+ * = require easy_gantt_pro/email_silencer
+ * = require easy_gantt_pro/delayed_issues
+ *
+ * GLOBAL SPECIFIC
+ * = require easy_gantt_pro/project_move
+ * = require easy_gantt_pro/lowest_progress
+ * = require easy_gantt_pro/delayed_projects
+ * = require easy_gantt_pro/gg_resource
+ */
diff --git a/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/email_silencer.js b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/email_silencer.js
new file mode 100644
index 0000000..cc39803
--- /dev/null
+++ b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/email_silencer.js
@@ -0,0 +1,32 @@
+window.ysy = window.ysy || {};
+ysy.pro = ysy.pro || {};
+ysy.pro.silencer = ysy.pro.silencer || {};
+$.extend(ysy.pro.silencer, {
+ setting: null,
+ name: "Silencer",
+ patch: function () {
+ ysy.proManager.register("beforeSaveIssue", this.updateSaveData);
+ this.setting = new ysy.data.Data();
+ this.setting.init({name: this.name, turnedOn: false});
+ var $checkBox = $(' '
+ + '' + ysy.settings.labels.silencer.label_disable_notifications + ' ');
+ $("#button_year_zoom").after($checkBox);
+ ysy.view.AllButtons.prototype.extendees.silencer = {
+ widget: ysy.view.CheckBox,
+ bind: function () {
+ this.model = ysy.pro.silencer.setting;
+ },
+ func: function () {
+ this.model.turnedOn = this.$target.is(":checked");
+ this.model._fireChanges(this, "click");
+ },
+ isOn: function () {
+ return this.model.turnedOn;
+ }
+ };
+ },
+ updateSaveData: function (data) {
+ if (ysy.pro.silencer.setting.turnedOn)
+ data.easy_gantt_suppress_notification = true;
+ }
+});
\ No newline at end of file
diff --git a/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/gg_resource.js b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/gg_resource.js
new file mode 100644
index 0000000..1db881b
--- /dev/null
+++ b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/gg_resource.js
@@ -0,0 +1,158 @@
+window.ysy = window.ysy || {};
+ysy.pro = ysy.pro || {};
+ysy.pro.ggrm = {
+ _name: "GGRM",
+ patch: function () {
+ if (!ysy.pro.resource || !ysy.pro.resource.project_canvas_renderer) {
+ ysy.pro.ggrm = null;
+ return;
+ }
+
+ ysy.pro.ggrm = {
+ patch: function () {
+ ysy.proManager.register("close", this.close);
+ var ggrmClass = ysy.pro.ggrm;
+ ysy.view.AllButtons.prototype.extendees.ggrm = {
+ bind: function () {
+ this.model = ysy.settings.resource;
+ },
+ func: function () {
+ var resource = ysy.settings.resource;
+ if (resource.ggrm) {
+ ggrmClass.close();
+ } else {
+ ggrmClass.open();
+ }
+ },
+ isOn: function () {
+ return ysy.settings.resource.ggrm;
+ }
+ };
+ ysy.pro.resource.compileStyles();
+ ysy.pro.sumRow.summers.ggrm = {
+ day: function (date, project) {
+ if (project.start_date.isAfter(date)) return 0;
+ if (project.end_date.isBefore(date)) return 0;
+ if (!project._ganttResources) return 0;
+ var allocation = project._ganttResources[date.format("YYYY-MM-DD")];
+ if (allocation > 0) return allocation;
+ return 0;
+ },
+ week: function (first_date, last_date, project) {
+ if (project.start_date.isAfter(last_date)) return 0;
+ if (project.end_date.isBefore(first_date)) return 0;
+ if (!project._ganttResources) return 0;
+ var sum = 0;
+ var mover = moment(first_date);
+ while (mover.isBefore(last_date)) {
+ var allocation = project._ganttResources[mover.format("YYYY-MM-DD")];
+ if (allocation > 0) sum += allocation;
+ mover.add(1, "day");
+ }
+ return sum;
+ },
+ entities: ["projects"],
+ title: "GGRM"
+ };
+ },
+ open: function () {
+ var resource = ysy.settings.resource;
+ if (resource.setSilent("ggrm", true)) {
+ this.loadResources();
+ ysy.settings.sumRow.setSummer("ggrm");
+ ysy.view.bars.registerRenderer("project", this.outerRenderer);
+ ysy.proManager.closeAll(this);
+ resource._fireChanges(this, "toggle");
+ }
+ },
+ close: function (except) {
+ var resource = ysy.settings.resource;
+ if (resource.setSilent("ggrm", false)) {
+ ysy.settings.sumRow.removeSummer("ggrm");
+ ysy.view.bars.removeRenderer("project", ysy.pro.ggrm.outerRenderer);
+ resource._fireChanges(this, "toggle");
+ }
+ },
+ loadResources: function (projectId) {
+ var ids = [];
+ var start_date;
+ var end_date;
+ var project;
+ if (projectId) {
+ ids.push(projectId);
+ project = ysy.data.projects.getByID(projectId);
+ start_date = project.start_date;
+ end_date = project.end_date;
+ } else {
+ var projects = ysy.data.projects.getArray();
+ for (var i = 0; i < projects.length; i++) {
+ project = projects[i];
+ ids.push(project.id);
+ if (!start_date || project.start_date.isBefore(start_date)) {
+ start_date = project.start_date;
+ }
+ if (!end_date || project.end_date.isAfter(end_date)) {
+ end_date = project.end_date;
+ }
+ }
+ }
+ ysy.gateway.polymorficPostJSON(
+ ysy.settings.paths.globalGanttResources
+ .replace(":start", start_date.format("YYYY-MM-DD"))
+ .replace(":end", end_date.format("YYYY-MM-DD")),
+ {
+ project_ids: ids
+ },
+ $.proxy(this._handleResourcesData, this),
+ function () {
+ ysy.log.error("Error: Unable to load data");
+ //ysy.pro.resource.loader.loading = false;
+ }
+ );
+ },
+ _handleResourcesData: function (data) {
+ var json = data.easy_resource_data;
+ if (!json) return;
+ this._resetProjects();
+ this._loadProjects(json.projects);
+ },
+ _resetProjects: function () {
+ var projects = ysy.data.projects.getArray();
+ for (var i = 0; i < projects.length; i++) {
+ delete projects[i]._ganttResources;
+ }
+ },
+ _loadProjects: function (json) {
+ var projects = ysy.data.projects;
+ for (var i = 0; i < json.length; i++) {
+ var project = projects.getByID(json[i].id);
+ if (!project) continue;
+ project._ganttResources = json[i].resources_sums;
+ project._fireChanges(this, "load resources");
+ }
+ },
+ outerRenderer: function (task, next) {
+ var div = next().call(this, task, next);
+ var allodiv = ysy.pro.ggrm._projectRenderer.call(gantt, task);
+ div.appendChild(allodiv);
+ return div;
+ },
+ _projectRenderer: function (task) {
+ var resourceClass = ysy.pro.resource;
+ var project = task.widget && task.widget.model;
+ var allocPack = {allocations: project._ganttResources || {}, types: {}};
+ var canvasList = ysy.view.bars.canvasListBuilder();
+ canvasList.build(task, this);
+ if (ysy.settings.zoom.zoom !== "day") {
+ $.proxy(resourceClass.issue_week_renderer, this)(task, allocPack, canvasList);
+ } else {
+ $.proxy(resourceClass.issue_day_renderer, this)(task, allocPack, canvasList);
+ }
+ var element = canvasList.getElement();
+ element.className += " project";
+ return element;
+ }
+ };
+ ysy.pro.ggrm.patch();
+ }
+};
\ No newline at end of file
diff --git a/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/lowest_progress.js b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/lowest_progress.js
new file mode 100644
index 0000000..9ee2706
--- /dev/null
+++ b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/lowest_progress.js
@@ -0,0 +1,150 @@
+window.ysy = window.ysy || {};
+ysy.pro = ysy.pro || {};
+ysy.pro.lowestProgress = {
+ patch: function () {
+ if (!ysy.settings.showLowestProgress) {
+ ysy.pro.lowestProgress = null;
+ return;
+ }
+
+ ysy.pro.lowestProgress = {
+ name: "LowestProgressIssue",
+ data: {},
+ laggies: {},
+ loaded: false,
+ setting: null,
+ className: " gantt-issue-lagging",
+ patch: function () {
+ var lowestClass = ysy.pro.lowestProgress;
+ this.setting = new ysy.data.Data();
+ this.setting.init({name: this.name, turnedOn: false});
+ ysy.pro.toolPanel.registerButton({
+ id: "show_lowest_progress_tasks",
+ bind: function () {
+ this.model = lowestClass.setting;
+ },
+ func: function () {
+ this.model.turnedOn = !this.model.turnedOn;
+ this.model._fireChanges(this, "click");
+ if (this.model.turnedOn) {
+ var send = lowestClass.load();
+ if (!send) {
+ lowestClass.colorizeLaggies();
+ }
+ } else {
+ lowestClass.resetLaggies();
+ lowestClass.decolorizeLaggies();
+ }
+ },
+ isOn: function () {
+ return this.model.turnedOn;
+ }
+ });
+ gantt.templates.task_text = function (start, end, task) {
+ if (!lowestClass.setting.turnedOn) return "";
+ if (task.type === "project") {
+ if (task.widget && task.widget.model) {
+ var id = task.widget.model.id;
+ var issuePack = lowestClass.data[id];
+ if (issuePack) {
+ return Mustache.render(
+ ysy.view.templates.lowestProgressText, issuePack
+ ).replace(/,\s+#\$@&/, "");
+ }
+ }
+ }
+ return "";
+ };
+ ysy.data.loader.register(function () {
+ if (!this.setting.turnedOn) return;
+ if (!ysy.data.loader.loaded) {
+ this.resetLaggies();
+ }
+ var send = this.load();
+ if (!send) {
+ this.colorizeLaggies();
+ }
+ }, this);
+ },
+ load: function () {
+ var ids = [];
+ var projects = ysy.data.projects.getArray();
+ for (var i = 0; i < projects.length; i++) {
+ var id = projects[i].id;
+ if (this.data[id] === undefined) {
+ ids.push(id);
+ }
+ }
+ if (!ids.length) return false;
+ ysy.gateway.polymorficPostJSON(
+ ysy.settings.paths.lowestProgressTasks,
+ {project_ids: ids},
+ $.proxy(ysy.pro.lowestProgress._loadLaggies, this),
+ ysy.pro.lowestProgress._handleError
+ );
+ return true;
+ },
+ _handleError: function (e) {
+ console.error(e);
+ },
+ _loadLaggies: function (data) {
+ if (!data || !data.easy_gantt_data) return;
+ var issues = data.easy_gantt_data.issues;
+ for (var i = 0; i < issues.length; i++) {
+ var issue = issues[i];
+ this.laggies[issue.id] = issue;
+ var projectId = issue.project_id;
+ if (!this.data[projectId]) {
+ this.data[projectId] = {progress_date: issue.progress_date, issues: []};
+ }
+ this.data[projectId].issues.push(issue);
+ }
+ var projects = ysy.data.projects.getArray();
+ for (i = 0; i < projects.length; i++) {
+ projectId = projects[i].id;
+ if (this.data[projectId] === undefined) {
+ this.data[projectId] = false;
+ }
+ }
+ this._redrawAllProjects("loaded");
+ this.colorizeLaggies();
+ this.loaded = true;
+ },
+ resetLaggies: function () {
+ this.data = {};
+ this.laggies = {};
+ this.loaded = false;
+ this._redrawAllProjects("reset");
+ },
+ _redrawAllProjects: function (reason) {
+ var projects = ysy.data.projects.getArray();
+ for (var i = 0; i < projects.length; i++) {
+ projects[i]._fireChanges(this, reason);
+ }
+ },
+ colorizeLaggies: function () {
+ var issues = ysy.data.issues;
+ for (var id in this.laggies) {
+ if (!this.laggies.hasOwnProperty(id)) continue;
+ var laggie = this.laggies[id];
+ var issue = issues.getByID(laggie.id);
+ if (!issue) continue;
+ if (issue.css && issue.css.indexOf(this.className) > -1) continue;
+ if (issue.css === undefined) issue.css = "";
+ issue.css += this.className;
+ issue._fireChanges(this, "colorizeLaggies");
+ }
+ },
+ decolorizeLaggies: function () {
+ var issues = ysy.data.issues.getArray();
+ for (var i = 0; i < issues.length; i++) {
+ var issue = issues[i];
+ if (!issue.css || issue.css.indexOf(this.className) === -1) continue;
+ issue.css = issue.css.replace(this.className, "");
+ issue._fireChanges(this, "decolorizeLaggies");
+ }
+ }
+ };
+ ysy.pro.lowestProgress.patch();
+ }
+};
\ No newline at end of file
diff --git a/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/project_move.js b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/project_move.js
new file mode 100644
index 0000000..3662c8b
--- /dev/null
+++ b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/project_move.js
@@ -0,0 +1,51 @@
+window.ysy = window.ysy || {};
+ysy.pro = ysy.pro || {};
+ysy.pro.projectMove = {
+ patch: function () {
+ ysy.proManager.register("extendGanttTask", this.extendGanttTask);
+ //var proManager = ysy.proManager;
+ //var projectMoveClass = ysy.pro.projectMove;
+ ysy.data.Project.prototype._shift = 0;
+ gantt.attachEvent("onBeforeTaskOpened", function (id) {
+ var task = gantt._pull[id];
+ if (!task || !task.widget) return true;
+ if (task.type !== "project") return true;
+ var project = task.widget.model;
+ if (project._shift) {
+ dhtmlx.message(ysy.settings.labels.projectMove.error_opening_unsaved, "error");
+ return false;
+ }
+ return true;
+ });
+ gantt.attachEvent("onTaskOpened", function (id) {
+ var task = gantt._pull[id];
+ if (!task || !task.widget) return true;
+ if (task.type === "project") {
+ task.editable = false;
+ }
+ });
+ ysy.data.saver.sendProjects = function () {
+ var j, data;
+ if (!ysy.data.projects) return;
+ var projects = ysy.data.projects.array;
+ for (j = 0; j < projects.length; j++) {
+ var project = projects[j];
+ if (!project._changed) continue;
+ //if (project._deleted && project._created) continue;
+ data = {
+ days: project._shift
+ //project: {
+ //}
+ };
+ ysy.gateway.sendProject("PUT", project, data, ysy.data.saver.callbackBuilder(project));
+ }
+ };
+ },
+ extendGanttTask: function (project, gantt_issue) {
+ if (gantt_issue.type !== "project") return;
+ if (project.needLoad || project.issues_count && !project.has_subprojects){
+ gantt_issue.editable = true;
+ gantt_issue.shift = project._shift * (60 * 60 * 24);
+ }
+ }
+};
diff --git a/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/sorting.js b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/sorting.js
new file mode 100644
index 0000000..dd6a8e0
--- /dev/null
+++ b/plugins/easy_gantt_pro/assets/javascripts/easy_gantt_pro/sorting.js
@@ -0,0 +1,80 @@
+window.ysy = window.ysy || {};
+ysy.pro = ysy.pro || {};
+ysy.pro.sorting = $.extend(ysy.pro.sorting, {
+ name:"Sorter",
+ patch: function () {
+ var setting = new ysy.data.Data();
+ setting.init({_name: "Sorting", sortBy: null});
+ ysy.settings.sorting = setting;
+
+ gantt.attachEvent("onGanttReady", $.proxy(this.bindClick, gantt));
+
+ },
+ columnCompares: {
+ start_date: function (a, b) {
+ return (a._start_date || a.start_date) - (b._start_date || b.start_date);
+ },
+ end_date: function (a, b) {
+ return (a._end_date || a.end_date) - (b._end_date || b.end_date);
+ },
+ subject: function (a, b) {
+ return a.text.localeCompare(b.text);
+ }
+ },
+ getCompareFunction: function (column, sort) {
+ var sortCoefficient = sort ? -1 : 1;
+ if (this.columnCompares[column]) {
+ var func = this.columnCompares[column];
+ return function (a, b) {
+ var result = func(a, b);
+ if (result === 0) result = a.order - b.order;
+ return sortCoefficient * result;
+ }
+ }
+ return function (a, b) {
+ var result = ysy.pro.sorting.columnsValidation(a, b);
+ if (result === undefined) {
+ result = a.columns[column].toString().localeCompare(b.columns[column].toString());
+ if (result === 0) result = a.order - b.order;
+ }
+ return sortCoefficient * result;
+ }
+ },
+ columnsValidation: function (a, b) {
+ if (!a.columns) {
+ if (!b.columns) return a.order - b.order;
+ return -1
+ }
+ if (!b.columns) return 1;
+ return undefined;
+ },
+ bindClick: function () {
+ this._click.gantt_grid_head_cell = dhtmlx.bind(function (e, id, trg) {
+ var column = trg.getAttribute("column_id");
+
+ if (!this.callEvent("onGridHeaderClick", [column, e]))
+ return;
+
+ if (this._sort && this._sort.direction && this._sort.name == column) {
+ var sort = this._sort.direction;
+ if (sort === "desc") {
+ // remove sorting by column (on third click)
+ this._sort = null;
+ this.sort();
+ return;
+ }
+ // invert sort direction
+ sort = (sort == "desc") ? "asc" : "desc";
+ } else {
+ sort = "asc";
+ }
+ var sortFunction = ysy.pro.sorting.getCompareFunction(column, sort == "desc");
+ this._sort = {
+ name: column,
+ criteria: sortFunction,
+ direction: sort
+ };
+ this.sort(sortFunction);
+ }, this);
+ }
+});
\ No newline at end of file
diff --git a/plugins/easy_gantt_pro/assets/stylesheets/easy_gantt_pro/easy_gantt_pro.css b/plugins/easy_gantt_pro/assets/stylesheets/easy_gantt_pro/easy_gantt_pro.css
new file mode 100644
index 0000000..3a70d4f
--- /dev/null
+++ b/plugins/easy_gantt_pro/assets/stylesheets/easy_gantt_pro/easy_gantt_pro.css
@@ -0,0 +1,93 @@
+.gantt_grid_head_cell .gantt_sort.gantt_none {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAANCAYAAABlyXS1AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AcbExA7CgFb8AAAAHFJREFUGNNjYEAC9f1T/zNgA/X9U/9vv3jrP7ICRpiEhbMrXOGJvbsZGguzGRnr+6f+t3ByxTDpxL7dDIz////Hbg/tACNOvzEwQBy04/JtDAkPXVWIP9EVeOiqMjAyMjLCBf7///9/+6Vb/3F6DV0CADA7O+B8p/IiAAAAAElFTkSuQmCC)
+}
+
+
+/* BASELINE CSS (start)*/
+.gantt-baseline {
+ position: absolute;
+ border-radius: 2px;
+ opacity: 0.6;
+ margin-top: -7px;
+ height: 12px;
+ background: #ffd180;
+ border: 1px solid rgb(255, 153, 0);
+}
+
+.gantt-baselines .gantt_task_line{
+ margin-top: -9px;
+}
+.gantt-baselines .gantt_line_wrapper {
+ margin-top: -9px;
+}
+.gantt-baselines .gantt_task_link .gantt_link_arrow {
+ margin-top: -10px
+}
+/* BASELINE CSS (end)*/
+/*.gantt_task_line.planned.gantt_milestone-type, */
+.gantt-baseline.gantt_milestone-type {
+ -webkit-transform: scale(0.75) rotate(45deg);
+ -moz-transform: scale(0.75) rotate(45deg);
+ -ms-transform: scale(0.75) rotate(45deg);
+ -o-transform: scale(0.75) rotate(45deg);
+ transform: scale(0.75) rotate(45deg);
+ visibility: visible;
+}
+
+.gantt_task_line.gantt-scheme-project-status-15 .gantt_task_content {
+ /* planned project */
+ background: rgba(78, 191, 103, 0.1);
+ border-color: rgba(58, 160, 81, 1) !important;
+}
+
+.gantt-scheme-project-status-15 {
+ background: rgba(78, 191, 103, 0.1);
+ border-color: rgba(58, 160, 81, 0.1);
+ color: #4ebf67;
+}
+
+.gantt-scheme-project-status-15 a {
+ color: #4ebf67;
+}
+
+.gantt_task_line .gantt_task_content {
+ overflow: hidden;
+}
+.gantt-grid-row-project{
+ font-weight: bold;
+}
+.task-type .gantt_grid_superitem{
+ font-weight: normal;
+}
+.gantt-grid-project-issues-expand{
+ /*display: inline-block;*/
+ border: 1px solid #eeeeaa;
+ background-color: #ffffcc;
+ min-width: 15px;
+ margin: 5px;
+ font-size: 10px;
+ padding: 3px 6px;
+ vertical-align: bottom;
+ border-radius: 3px;
+ color:#888888;
+}
+
+.gantt-issue-lagging, .gantt-issue-lagging .gantt_task_content {
+ background-color: #ffaa44;
+}
+input[type="checkbox"].gantt-grid-checkbox{
+ margin: 5px;
+}
+.gantt-grid-checkbox-cont{
+ display: none;
+ cursor: pointer;
+ position: absolute;
+ left: 0;
+ top: 0;
+}
+.bulk-edit-mode .gantt-grid-checkbox-cont{
+ display: block;
+}
+.bulk-edit-mode .gantt_grid_body_subject{
+ padding-left: 5px;
+}
diff --git a/plugins/easy_gantt_pro/config/locales/ar.yml b/plugins/easy_gantt_pro/config/locales/ar.yml
new file mode 100644
index 0000000..b93c21a
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/ar.yml
@@ -0,0 +1,2 @@
+---
+ar:
diff --git a/plugins/easy_gantt_pro/config/locales/cs.yml b/plugins/easy_gantt_pro/config/locales/cs.yml
new file mode 100644
index 0000000..8b97b98
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/cs.yml
@@ -0,0 +1,76 @@
+---
+cs:
+ easy_gantt_pro:
+ add_task_modal:
+ no_parent: ''
+ title: Přidat úkol
+ add_task:
+ body: Nový úkol verze můžete vytvořit kliknutím na tlačítko Úkol (nebo tlačítko
+ Verze) nebo přetažením kamkoliv do grafu
+ title: Nápověda k přidání úkolu
+ baselines:
+ confirm_delete: Opravdu chcete smazat tuto baseline
+ create_failed: Nová baseline nemohla být vytvořena
+ delete_failed: Baseline nemohla být odstraněna
+ error_not_saved: Musíte uložit všechny změny v projektu před vytvořením baseline
+ label_baseline: Baseline
+ label_same: "-stejný-"
+ off_desc: Zapnout Baseline modul k zobrazení a vytváření baselines.
+ off_link: Nastavení modulu
+ off_title: Baseline modul je vypnutý
+ cashflow:
+ label_cashflow: Peněžní tok
+ critical:
+ hide_button: Skrýt Kritickou cestu
+ legend_issues: Úkol na Kritické cestě
+ show_button: Zobrazit Kritickou cestu
+ lowest_progress:
+ label_progress_date: Datum průběhu
+ project_move:
+ error_opening_unsaved: Musíte nejprve uložit změny před otevřením projektu
+ resources:
+ label_resources: Zdroje
+ easy_gantt:
+ button:
+ bulk_edit: Hromadná úprava
+ delayed_issue_filter: Filtrovat opožděné úkoly
+ show_lowest_progress_tasks: Zobrazit úkoly s nejnižším datem průběhu
+ show_only_critical: Filtrovat kritické
+ popup:
+ add_task:
+ heading: Pomoc s přidáním úkolu
+ text: Nový úkol nebo milník může být vytvořen kliknutím na tlačítko úkolu
+ (respektive tlačítko milníku) nebo přetažením kdekoli v grafu
+ baseline:
+ heading: Popis baseline
+ heading_new_baseline: Nová baseline
+ text: Vytvoří kopii projektu pro další porovnání
+ critical:
+ heading: Popis Kritické cesty
+ text: Nejdelší sled činností v plánu projektu, který musí být dokončen včas,
+ aby byl daný projekt dokončen v řádném termínu. Aktivitu na kritické cestě
+ nelze zahájit, dokud aktivita jejího předchůdce není dokončena; pokud je
+ odložena o jeden den, bude celý projekt odložen o jeden den, ledaže by aktivita
+ navazující na opožděnou aktivitu byla dokončena o den dříve. Pro správnou
+ funkci kritické cesty by projekt měl mít jen jeden počáteční a jeden koncový
+ úkol a tyto úkoly by měly být spojeny vazbami.
+ scheme_by:
+ label_by_priority: Priority
+ label_by_status: Stavu
+ label_by_tracker: Trackeru
+ label_color_by: Barva dle
+ title:
+ delayed_issue_filter: Zobrazit pouze úkoly, jejichž datum průběhu je v minulosti
+ show_only_critical: Zobrazit pouze úkoly na kritické cestě
+ easy_pages:
+ modules:
+ easy_global_gantt: Easy gantt
+ easy_proposer:
+ easy_gantt:
+ index:
+ caption: Easy Gantt PRO
+ description: Přejít na Easy Gantt PRO
+ heading_easy_gantts_issues: Easy Gantt PRO
+ label_show_lowest_progress_tasks: Úkoly s nejpomalejším průběhem
+ text_show_lowest_progress_tasks: Zobrazit úkoly s nejhorším datem průběhu (= datum
+ odpovídající poměru % Hotovo v ganttu)
diff --git a/plugins/easy_gantt_pro/config/locales/da.yml b/plugins/easy_gantt_pro/config/locales/da.yml
new file mode 100644
index 0000000..d3dcd59
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/da.yml
@@ -0,0 +1,2 @@
+---
+da:
diff --git a/plugins/easy_gantt_pro/config/locales/de.yml b/plugins/easy_gantt_pro/config/locales/de.yml
new file mode 100644
index 0000000..639dee9
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/de.yml
@@ -0,0 +1,78 @@
+---
+de:
+ easy_gantt_pro:
+ add_task_modal:
+ no_parent: ''
+ title: Aufgabe hinzufügen
+ baselines:
+ confirm_delete: Möchten Sie wirklich dieses Basisplan löschen
+ create_failed: Neuer Basisplan konnte nicht erstellt werden
+ delete_failed: Der Basisplan konnte nicht gelöscht werden
+ error_not_saved: Sie müssen erst mal alle Veränderungen im Projekt abspeichern
+ bevor Sie einen Basisplan erstellen können
+ label_baseline: Basisplan
+ label_same: "-gleich-"
+ cashflow:
+ label_cashflow: Cashflow
+ critical:
+ hide_button: Versteckter kritischer Weg
+ legend_issues: Aufgabe auf dem kritischen Weg
+ show_button: Den kritischen Weg anzeigen
+ lowest_progress:
+ label_progress_date: Das Fortschrittsdatum
+ project_move:
+ error_opening_unsaved: Sie müssen erst mal alle Veränderungen abspeichern bevor
+ das Projekt eröffnen
+ resources:
+ label_resources: Die Ressourcen
+ easy_gantt:
+ button:
+ bulk_edit: Menge bearbeiten
+ delayed_issue_filter: Verzögerte Probleme filtern
+ show_lowest_progress_tasks: Die Aufgaben mit der niedrigsten Verhältnis Fortschritt/Datum anzeigen
+ show_only_critical: Kritisch Filtern
+ popup:
+ add_task:
+ heading: Hilfe für die Aufgabe hinzufügen
+ text: Neue Aufgabe oder Meilenstein können erstellt werden in dem Sie auf
+ die Aufgabe Taste (entsprechen Meilenstein Taste) klicken oder in dem Sie
+ es überall in dem Graph ziehen.
+ baseline:
+ heading: Basisplan Beschreibung
+ heading_new_baseline: Neuer Basisplan
+ text: Kopie des Projekts für den weiteren Vergleich erstellen
+ critical:
+ heading: Kritischer Weg Beschreibung
+ text: Längste Sequenz der Aktivitäten in der Projekt Planung, soll fristgemäß
+ beendet werden um den Projekt am Stichtag fertigzustellen. Eine Aktivität
+ auf dem kritischen Weg kann solang nicht erstell werden solang die vorherigen
+ Aktivitäten nicht abgeschlossen sind; falls es sich doch verspätet um einen
+ Tag, der ganzer Projekt wird sich um einen Tag verspäten, es sei denn die
+ Aktivitäten die verspäteten Aktivitäten folgen ein Tag früher fertig gestellt
+ werden. Um eine ordnungsgemäße Funktionalität des kritischen Weges zu sichern,
+ soll der Projekt 1 Startaufgabe und 1 Endaufgabe beinhalten und die Aufgaben
+ sollen mit Relationen verbunden sein
+ scheme_by:
+ label_by_priority: nach Priorität
+ label_by_status: nach Status
+ label_by_tracker: nach Verflogung
+ label_color_by: Färben nach
+ title:
+ delayed_issue_filter: Nur Probleme anzeigen dessen Fortschrittsdatum liegt hinter
+ heute
+ show_only_critical: Nur die Aufgaben anzeigen die sich derzeit auf dem kritischen
+ Weg befinden
+ easy_pages:
+ modules:
+ easy_global_gantt: Easy Gantt
+ easy_project_gantt: Easy Gantt
+ easy_proposer:
+ easy_gantt:
+ index:
+ caption: Easy Gantt PRO
+ description: Gehen Sie zu Easy Gantt PRO
+ heading_easy_gantts_issues: Easy Gantt PRO
+ label_show_lowest_progress_tasks: Aufgaben mit dem kleinstem Fortschritt
+ text_show_lowest_progress_tasks: Die Aufgabe mit der schlechtesten Fortschritt/Datum
+ Relation anzeigen (=das Datum , das korrespondiert mit der Fertigstellung der
+ Aufgabe in dem Verhältnis-Balken in Gantt)
diff --git a/plugins/easy_gantt_pro/config/locales/en-AU.yml b/plugins/easy_gantt_pro/config/locales/en-AU.yml
new file mode 100644
index 0000000..56b80b3
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/en-AU.yml
@@ -0,0 +1,2 @@
+---
+en-AU:
diff --git a/plugins/easy_gantt_pro/config/locales/en-GB.yml b/plugins/easy_gantt_pro/config/locales/en-GB.yml
new file mode 100644
index 0000000..a32c228
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/en-GB.yml
@@ -0,0 +1,2 @@
+---
+en-GB:
diff --git a/plugins/easy_gantt_pro/config/locales/en-US.yml b/plugins/easy_gantt_pro/config/locales/en-US.yml
new file mode 100644
index 0000000..54b3be8
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/en-US.yml
@@ -0,0 +1,2 @@
+---
+en-US:
diff --git a/plugins/easy_gantt_pro/config/locales/en.yml b/plugins/easy_gantt_pro/config/locales/en.yml
new file mode 100644
index 0000000..5b44d86
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/en.yml
@@ -0,0 +1,72 @@
+---
+en:
+ easy_gantt_pro:
+ add_task_modal:
+ no_parent: ''
+ title: Add task
+ baselines:
+ confirm_delete: Do you really want to delete this baseline
+ create_failed: New baseline could not be created
+ delete_failed: Baseline could not be deleted
+ error_not_saved: You have to save all changes in project before creating its
+ baseline
+ label_baseline: Baseline
+ label_same: "-same-"
+ cashflow:
+ label_cashflow: Cash Flow
+ critical:
+ hide_button: Hide Critical path
+ legend_issues: Task on Critical path
+ show_button: Show Critical path
+ lowest_progress:
+ label_progress_date: Progress date
+ project_move:
+ error_opening_unsaved: You have to save changes first before opening the project
+ resources:
+ label_resources: Resources
+ easy_gantt:
+ button:
+ bulk_edit: Bulk edit
+ delayed_issue_filter: Filter Delayed Issues
+ show_lowest_progress_tasks: Show tasks with lowest progress date
+ show_only_critical: Filter Critical
+ popup:
+ add_task:
+ heading: Add task help
+ text: New task or milestone can be created by a click on Task button (respective
+ Milestone button) or by dragging anywhere in graph
+ baseline:
+ heading: Baseline description
+ heading_new_baseline: New baseline
+ text: Creates copy of the project for further comparisons
+ critical:
+ heading: Critical path description
+ text: Longest sequence of activities in a project plan which must be completed
+ on time for the project to complete on due date. An activity on the critical
+ path cannot be started until its predecessor activity is complete; if it
+ is delayed for a day, the entire project will be delayed for a day unless
+ the activity following the delayed activity is completed a day earlier.
+ For proper function of a critical path, the project should have just 1 starting
+ and 1 ending task and the tasks should be connected with relations.
+ scheme_by:
+ label_by_priority: by Priority
+ label_by_status: by Status
+ label_by_tracker: by Tracker
+ label_color_by: Color by
+ title:
+ delayed_issue_filter: Show only issues which progress date is behind today
+ show_only_critical: Show only tasks on Critical path
+ easy_pages:
+ modules:
+ easy_global_gantt: Easy gantt
+ easy_project_gantt: Easy gantt
+ easy_proposer:
+ easy_gantt:
+ index:
+ caption: Easy Gantt PRO
+ description: Go to Easy Gantt PRO
+ heading_easy_gantts_issues: Easy Gantt PRO
+ label_show_lowest_progress_tasks: Lowest progress tasks
+ text_show_lowest_progress_tasks: Display tasks with the worst progress date (= date
+ corresponding to task's done ratio bar in gantt)
+ warning_easy_gantt_recalculate_fixed_delay: This count affect relations delay on every task in the system. Are you sure to continue?
diff --git a/plugins/easy_gantt_pro/config/locales/es.yml b/plugins/easy_gantt_pro/config/locales/es.yml
new file mode 100644
index 0000000..e42e485
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/es.yml
@@ -0,0 +1,75 @@
+---
+es:
+ easy_gantt_pro:
+ add_task_modal:
+ no_parent: ''
+ title: Añadir tarea
+ baselines:
+ confirm_delete: Seguro que deseas eliminar esta referencia
+ create_failed: No se ha podido crear la nueva referencia
+ delete_failed: No se ha podido eliminar la referencia
+ error_not_saved: Para crear la referencia del proyecto, debes guardar todos
+ los cambios
+ label_baseline: Referencia
+ label_same: "-igual-"
+ cashflow:
+ label_cashflow: Flujo de liquidez
+ critical:
+ hide_button: Ocultar senda Crítica
+ legend_issues: Tarea en senda Crítica
+ show_button: Mostrar senda Crítica
+ lowest_progress:
+ label_progress_date: Fecha de progreso
+ project_move:
+ error_opening_unsaved: Debes guardar los cambios antes de abrir el proyecto
+ resources:
+ label_resources: Recursos
+ easy_gantt:
+ button:
+ bulk_edit: Edición de volumen
+ delayed_issue_filter: Filtrar Asuntos Pendientes
+ show_lowest_progress_tasks: Mostrar tareas con la fecha de progreso más corta
+ show_only_critical: Filtrar Críticos
+ popup:
+ add_task:
+ heading: Añadir ayuda de tarea
+ text: Se puede crear una nueva tarea u objetivo haciendo clic en el botón
+ de Tarea (o en el botón respectivo de Objetivo) o arrastrándolo a cualquier
+ lugar del gráfico
+ baseline:
+ heading: Descripción de referencia
+ heading_new_baseline: Nueva referencia
+ text: Crea una copia del proyecto para futuras comparaciones
+ critical:
+ heading: Descripción de la senda crítica
+ text: Es la secuencia más extensa de actividades en un plan de proyecto que
+ debe realizarse a tiempo para que el proyecto se finalice en fecha. No se
+ puede iniciar una actividad en la senda crítica hasta que la actividad anterior
+ se haya realizado; si se retrasa durante un día, el proyecto completo se
+ retrasará durante un día, a menos que la actividad correspondiente a la
+ actividad con retraso se realice un día antes. Para que la senda crítica
+ funcione correctamente, el proyecto debería tener solamente 1 tarea de inicio
+ y 1 tarea de finalización, y las tareas deben estar conectadas mediante
+ relaciones.
+ scheme_by:
+ label_by_priority: por Prioridad
+ label_by_status: por Estado
+ label_by_tracker: por Rastreador
+ label_color_by: Color por
+ title:
+ delayed_issue_filter: Mostrar sólo asuntos cuya fecha de progreso es posterior
+ a hoy
+ show_only_critical: Mostrar sólo tareas en senda Crítica
+ easy_pages:
+ modules:
+ easy_global_gantt: Easy gantt
+ easy_project_gantt: Easy Gantt
+ easy_proposer:
+ easy_gantt:
+ index:
+ caption: Easy Gantt PRO
+ description: Ir a Easy Gant PRO
+ heading_easy_gantts_issues: Easy Gantt PRO
+ label_show_lowest_progress_tasks: Tareas con menor progreso
+ text_show_lowest_progress_tasks: Mostrar tareas con la peor fecha de progreso (=
+ fecha correspondiente al gráfico de relación de tareas realizadas en gantt)
diff --git a/plugins/easy_gantt_pro/config/locales/fi.yml b/plugins/easy_gantt_pro/config/locales/fi.yml
new file mode 100644
index 0000000..e173d18
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/fi.yml
@@ -0,0 +1,2 @@
+---
+fi:
diff --git a/plugins/easy_gantt_pro/config/locales/fr.yml b/plugins/easy_gantt_pro/config/locales/fr.yml
new file mode 100644
index 0000000..4992cad
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/fr.yml
@@ -0,0 +1,77 @@
+---
+fr:
+ easy_gantt_pro:
+ add_task_modal:
+ no_parent: ''
+ title: Ajouter tâche
+ baselines:
+ confirm_delete: Souhaitez-vous réellement effacer cette ligne de base
+ create_failed: La nouvelle ligne de base n'a pas pu être créée
+ delete_failed: La ligne de base n'a pas pu être supprimée
+ error_not_saved: Vous devez enregistrer toutes les modifications dans le projet
+ avant de créer sa ligne de base
+ label_baseline: Ligne de base
+ label_same: "-idem-"
+ cashflow:
+ label_cashflow: Flux de Trésorerie
+ critical:
+ hide_button: Masquer chemin critique
+ legend_issues: Tâche sur chemin critique
+ show_button: Afficher chemin critique
+ lowest_progress:
+ label_progress_date: Date progrès
+ project_move:
+ error_opening_unsaved: Vous devez d'abord sauvegarder les modifications avant
+ d'ouvrir le projet
+ resources:
+ label_resources: Ressources
+ easy_gantt:
+ button:
+ bulk_edit: Modifier en bloc
+ delayed_issue_filter: Filtrer les Publications Retardées
+ show_lowest_progress_tasks: Afficher les tâches avec la date de progrès la plus
+ basse
+ show_only_critical: Filtre critique
+ popup:
+ add_task:
+ heading: Ajouter tâche aide
+ text: Une nouvelle tâche ou un jalon peuvent être créés par un clic sur le
+ bouton Tâche (bouton Jalon correspondant) ou en faisant glisser partout
+ dans le graphique
+ baseline:
+ heading: Description ligne de base
+ heading_new_baseline: Nouvelle ligne de base
+ text: Crée une copie du projet pour d'autres comparaisons
+ critical:
+ heading: Description du chemin critique
+ text: La plus longue séquence d'activités dans un plan de projet qui doivent
+ être achevées à temps pour que le projet se termine à la date d'échéance.
+ Une activité sur le chemin critique ne peut pas être démarrée jusqu'à ce
+ que l'activité qui l'a précède soit terminée ; si elle est retardée d'une
+ journée, l'ensemble du projet sera retardé d'une journée, à moins que l'activité
+ faisant suite à l'activité retardée se termine un jour plus tôt. Pour qu'un
+ chemin critique fonctionne correctement, le projet doit avoir seulement
+ 1 départ et 1 tâche de fin, et les tâches doivent être connectées avec des
+ relations .
+ scheme_by:
+ label_by_priority: par Priorité
+ label_by_status: par statut
+ label_by_tracker: par tracker
+ label_color_by: Couleur par
+ title:
+ delayed_issue_filter: Affiche uniquement les publications dont la date d'avancement
+ est antérieure à aujourd'hui
+ show_only_critical: Afficher uniquement les tâches sur Chemin critique
+ easy_pages:
+ modules:
+ easy_global_gantt: Easy gantt
+ easy_project_gantt: Easy gantt
+ easy_proposer:
+ easy_gantt:
+ index:
+ caption: Easy Gantt PRO
+ description: Rendez-vous sur Easy Gantt PRO
+ heading_easy_gantts_issues: Easy Gantt PRO
+ label_show_lowest_progress_tasks: Tâches les moins avancées
+ text_show_lowest_progress_tasks: Affiche les tâches avec la pire date d'avancement
+ (= date correspondant à la barre de ratio de la tâche effectuée dans gantt)
diff --git a/plugins/easy_gantt_pro/config/locales/he.yml b/plugins/easy_gantt_pro/config/locales/he.yml
new file mode 100644
index 0000000..de35edf
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/he.yml
@@ -0,0 +1,2 @@
+---
+he:
diff --git a/plugins/easy_gantt_pro/config/locales/hr.yml b/plugins/easy_gantt_pro/config/locales/hr.yml
new file mode 100644
index 0000000..662a199
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/hr.yml
@@ -0,0 +1,2 @@
+---
+hr:
diff --git a/plugins/easy_gantt_pro/config/locales/hu.yml b/plugins/easy_gantt_pro/config/locales/hu.yml
new file mode 100644
index 0000000..ba0f4ca
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/hu.yml
@@ -0,0 +1,73 @@
+---
+hu:
+ easy_gantt_pro:
+ add_task_modal:
+ no_parent: Kritikus végrehajtási útvonal elrejtése
+ title: Feladat hozzáadása
+ baselines:
+ confirm_delete: Tényleg törölni szeretné az alapvonalat (baseline)?
+ create_failed: Nem sikerült új alapvonalat (baseline) létrehozni
+ delete_failed: Alapvonal (baseline) nem törölhető
+ error_not_saved: A projekt minden változását menteni kell az alapvonal (baseline)
+ létrehozása előtt
+ label_baseline: Baseline
+ label_same: "-ugyanaz-"
+ cashflow:
+ label_cashflow: Cash Flow
+ critical:
+ hide_button: Kritikus végrehajtási útvonal elrejtése
+ legend_issues: Feladata a kritikus elérési útvonalon
+ show_button: Kritikus elérési útvonal megjelenítése
+ lowest_progress:
+ label_progress_date: Haladási dátum
+ project_move:
+ error_opening_unsaved: Mielőtt megnyitja a projektet a változásokat kell elmenteni
+ resources:
+ label_resources: Források
+ easy_gantt:
+ button:
+ bulk_edit: Többszörös szerkesztés
+ delayed_issue_filter: Szűrés késleltetett feladatokra
+ show_lowest_progress_tasks: A leglassabban haladó feladatok mutatása
+ show_only_critical: Kritikusak szűrése
+ popup:
+ add_task:
+ heading: Feladathoz tartozó segítség hozzáadása
+ text: Új feladat vagy új mérföldkő létrehozása a Feladat gommbal (illetve
+ a Mérföldkő gombal) vagy ezen feladatok grafikonra történő ráhelyezésével
+ lehetséges.
+ baseline:
+ heading: Alapvonal (baseline) leírása
+ heading_new_baseline: Új alapvonal (baseline)
+ text: Másolatot készít a projektről további összehasonlítás céljából
+ critical:
+ heading: Kritikus végrehajtási útvonal leírása
+ text: "Olyan tevékenységek leghosszabb sorozata a projekt tervben, amelyeket
+ időben kell teljesíteni, a projekt határidőre történő befejezése érdekében.\r\nEgy
+ tevékenység a kritikus útvonalon nem kezdhető el addig, amíg a megelőző
+ tevékenység nem fejeződött be; ha késik egy nappal, az egész projekt késni
+ fog egy napot, kivéve ha a következő tevékenység egy nappal korábban fejeződik
+ be. \r\nA kritikus útvonal funkció megfelelő használatához a projektnek
+ csak 1 kezdő és 1 befejező feladat kell hogy legyen és kapcsolatokkal kell
+ összekötni azokat."
+ scheme_by:
+ label_by_priority: Prioritás alapján
+ label_by_status: Állapot alapján
+ label_by_tracker: Tracker (Feladattípus) alapján
+ label_color_by: Színkódolás
+ title:
+ delayed_issue_filter: Azoknak a feladatoknak a megjelenítése, amelyek haladási
+ dátuma a mai napnál későbbre esik
+ show_only_critical: Csak a kritikus útvonal feladatainak megjelenítése
+ easy_pages:
+ modules:
+ easy_global_gantt: Easy gantt
+ easy_project_gantt: Easy gantt
+ easy_proposer:
+ easy_gantt:
+ index:
+ caption: Easy Gantt PRO
+ description: Easy Gantt PRO-hoz
+ heading_easy_gantts_issues: Easy Gantt PRO
+ label_show_lowest_progress_tasks: Leglassabban haladó feladatok
+ text_show_lowest_progress_tasks: A leglassabban haladó feladatok kilistázása
diff --git a/plugins/easy_gantt_pro/config/locales/it.yml b/plugins/easy_gantt_pro/config/locales/it.yml
new file mode 100644
index 0000000..0d2530c
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/it.yml
@@ -0,0 +1,73 @@
+---
+it:
+ easy_gantt_pro:
+ add_task_modal:
+ no_parent: ''
+ title: Aggiungi task
+ baselines:
+ confirm_delete: Sei sicuro di voler cancellare questa baseline?
+ create_failed: Non è possbile creare una nuova baseline
+ delete_failed: La baseline non può essere cancellata
+ error_not_saved: Devi salvare tutte le modifiche al progetto prima di crearne
+ la baseline
+ label_baseline: Baseline
+ label_same: "-uguale-"
+ cashflow:
+ label_cashflow: Flussi di Cassa
+ critical:
+ hide_button: Nascondi Percorso critico
+ legend_issues: Task nel Percorso critico
+ show_button: Mostra Percorso critico
+ lowest_progress:
+ label_progress_date: Data avanzamento
+ project_move:
+ error_opening_unsaved: Devi salvare le modifiche prima di aprire il progetto
+ resources:
+ label_resources: Risorse
+ easy_gantt:
+ button:
+ bulk_edit: Modifica massiccia
+ delayed_issue_filter: Filtra Questioni Posticipate
+ show_lowest_progress_tasks: Mostra i task con tempo di avanzamento minore
+ show_only_critical: Filtra Criticità
+ popup:
+ add_task:
+ heading: Aggiungi indicazione al task
+ text: Puoi creare nuove task o milestone cliccando rispettivamente i pulsanti
+ Task o Milestone, oppure tramite trascinamento in ogni punto del grafico.
+ baseline:
+ heading: Descrizione baseline
+ heading_new_baseline: Nuova baseline
+ text: Crea una copia del progetto per ulteriori confronti
+ critical:
+ heading: Descrizione percorso critico
+ text: La più lunga sequenza di attività che deve essere portata a termine
+ in tempo affinché il progetto venga completato alla data stabilita. Un'attività
+ nel percorso critico non può avere inizio finché il suo predecessore non
+ sia stato completato; se viene rinviata di un giorno, l'intero progetto
+ subirà questo ritardo, a meno che l'attività seguente non venga ultimata
+ con un giorno di anticipo. Per un corretto funzionamento del percorso critico,
+ il progetto dovrebbe avere un solo task iniziale e uno finale e tutti dovrebbero
+ essere legati da relazioni.
+ scheme_by:
+ label_by_priority: per Priorità
+ label_by_status: per Stato
+ label_by_tracker: per Tracker
+ label_color_by: Colora di
+ title:
+ delayed_issue_filter: Mostra solo questioni con data di completamento precedente
+ a quella attuale
+ show_only_critical: Mostra solo i task sul Percorso critico
+ easy_pages:
+ modules:
+ easy_global_gantt: Easy Gantt
+ easy_project_gantt: Easy Gantt
+ easy_proposer:
+ easy_gantt:
+ index:
+ caption: Easy Gantt PRO
+ description: Vai a Easy Gantt PRO
+ heading_easy_gantts_issues: Easy Gantt PRO
+ label_show_lowest_progress_tasks: Task con avanzamento minore
+ text_show_lowest_progress_tasks: Mostra task con lo stato di avanzamento minore
+ (corrispondente alla barra di completamento del Gantt)
diff --git a/plugins/easy_gantt_pro/config/locales/ja.yml b/plugins/easy_gantt_pro/config/locales/ja.yml
new file mode 100644
index 0000000..f7016f8
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/ja.yml
@@ -0,0 +1,62 @@
+---
+ja:
+ easy_gantt_pro:
+ add_task_modal:
+ no_parent: ''
+ title: チケットの追加
+ baselines:
+ confirm_delete: 本当にこのベースラインを削除してもよろしいですか?
+ create_failed: 新しいベースラインを作成できませんでした
+ delete_failed: ベースラインを削除できませんでした
+ error_not_saved: ベースラインを作成する前に変更を保存してください。
+ label_baseline: ベースライン
+ label_same: "-同じ-"
+ cashflow:
+ label_cashflow: キャッシュフロー
+ critical:
+ hide_button: クリティカルパスを隠す
+ legend_issues: クリティカルパス上のチケット
+ show_button: クリティカルパスを表示
+ lowest_progress:
+ label_progress_date: 進捗日
+ project_move:
+ error_opening_unsaved: プロジェクトを開く前に変更内容を保存してください。
+ resources:
+ label_resources: リソース
+ easy_gantt:
+ button:
+ bulk_edit: 一括編集
+ delayed_issue_filter: 遅延したタスクをフィルタする
+ show_lowest_progress_tasks: 最も遅れているチケットを表示
+ show_only_critical: クリティカルのみ表示
+ popup:
+ add_task:
+ heading: ヘルプ - チケットの追加
+ text: 新しいチケットを作成するには、'新しいチケット'ボタンをクリックするか、ガントチャート内の余白をドラッグしてください。
+ baseline:
+ heading: ベースラインの説明
+ heading_new_baseline: 新しいベースライン
+ text: 比較のためにプロジェクトのコピーを作成します
+ critical:
+ heading: クリティカルパスの説明
+ text: プロジェクトを期日までに完了させるにあたって、所要時間が最長となる経路を指します。 先行するチケットが完了しないと、後続のチケットを開始できません。 つまり、先行するチケットが1日遅れた場合、後続のチケットを一日前倒しで完了させないと、プロジェクト全体が1日遅延します。 クリティカルパスを正しく機能させるためには、プロジェクト内のすべてのチケットが、1つのチケットを開始、終了するよう、関連付ける必要があります。
+ scheme_by:
+ label_by_priority: 優先度別
+ label_by_status: ステータス別
+ label_by_tracker: トラッカー別
+ label_color_by: 色別
+ title:
+ delayed_issue_filter: 本日時点で遅延しているタスクのみを表示
+ show_only_critical: クリティカルパス上のタスクのみ表示
+ easy_pages:
+ modules:
+ easy_global_gantt: Easyガントチャート
+ easy_project_gantt: 簡単なガントチャート
+ easy_proposer:
+ easy_gantt:
+ index:
+ caption: EasyガントチャートPRO
+ description: EasyガントチャートPROに移動
+ heading_easy_gantts_issues: EasyガントチャートPRO
+ label_show_lowest_progress_tasks: 進捗遅れのチケット
+ text_show_lowest_progress_tasks: 最も進捗率の低いチケットを表示する(チケットの進捗に対応する日付)
diff --git a/plugins/easy_gantt_pro/config/locales/ko.yml b/plugins/easy_gantt_pro/config/locales/ko.yml
new file mode 100644
index 0000000..32f5815
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/ko.yml
@@ -0,0 +1,65 @@
+---
+ko:
+ easy_gantt_pro:
+ add_task_modal:
+ no_parent: ''
+ title: 작업 추가
+ baselines:
+ confirm_delete: 이 기초항목을 삭제하시겠습니까
+ create_failed: 새로운 기준치가 생성될 수 없습니다
+ delete_failed: 기준치를 삭제할 수 없습니다
+ error_not_saved: 기준치를 생성하기 전에 프로젝트의 모든 변경사항을 저장하셔야 합니다
+ label_baseline: 기초
+ label_same: "-동일한-"
+ cashflow:
+ label_cashflow: 현금 흐름
+ critical:
+ hide_button: 중요한 경로 숨기기
+ legend_issues: 중요한 경로의 작업
+ show_button: 중요한 경로 보이기
+ lowest_progress:
+ label_progress_date: 진행일
+ project_move:
+ error_opening_unsaved: 이 프로젝트를 실행하기 전에 먼저 변경사항을 저장해야합니다
+ resources:
+ label_resources: 리소스
+ easy_gantt:
+ button:
+ bulk_edit: 단체 수정
+ delayed_issue_filter: 지연된 문제 필터
+ show_lowest_progress_tasks: 가장 느린 진행 날짜를 가진 작업 보기
+ show_only_critical: 중요 필터
+ popup:
+ add_task:
+ heading: 작업 도우미 추가
+ text: 작업 버튼 (각 중요 시점 버튼)을 클릭하거나 그래프의 아무 곳이나 드래그하여 새로운 작업 혹은 마일스톤을 만들 수 있습니다
+ baseline:
+ heading: 기준치 설명
+ heading_new_baseline: 새로운 기준치
+ text: 더 많은 비교를 위해 프로젝트 사본 만들기
+ critical:
+ heading: 중요한 경로 설명
+ text: 마감일에 프로젝트가 완성 될 때까지 완료해야하는 프로젝트 계획에서 가장 길게 지속되는 활동입니다. 중요 경로의 활동은 이전
+ 활동이 완료 될 때까지 시작할 수 없습니다. 하루 동안 지연 될 경우, 지연된 작업의 다음 작업이 완료되지 않는 이상, 전체 프로젝트는
+ 하루 지연되게 됩니다. 중요한 경로의 적절한 기능을 위해서, 프로젝트가 단지 1 개의 시작 작업과 1 개의 종료 작업을 가지고 있어야
+ 합니다. 또한, 작업의 관계는 연결되어야합니다.
+ scheme_by:
+ label_by_priority: 우선순위 별
+ label_by_status: 상태 별
+ label_by_tracker: 추적기 별로
+ label_color_by: 색으로 칠함
+ title:
+ delayed_issue_filter: 진행날짜가 오늘 이후에 있는 문제만 표시
+ show_only_critical: 중요 필터의 작업만 보기
+ easy_pages:
+ modules:
+ easy_global_gantt: 쉬운 간트
+ easy_project_gantt: 쉬운 간트
+ easy_proposer:
+ easy_gantt:
+ index:
+ caption: 쉬운 간트 PRO
+ description: 쉬운 간트 PRO로 가기
+ heading_easy_gantts_issues: 쉬운 간트 PRO
+ label_show_lowest_progress_tasks: 가장 적게 진행된 작업
+ text_show_lowest_progress_tasks: 가장 느린 진행날짜로 진행되는 작업 보기 (=작업의 완료비율이 간트 막대에 표시됨)
diff --git a/plugins/easy_gantt_pro/config/locales/mk.yml b/plugins/easy_gantt_pro/config/locales/mk.yml
new file mode 100644
index 0000000..0ae1092
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/mk.yml
@@ -0,0 +1,2 @@
+---
+mk:
diff --git a/plugins/easy_gantt_pro/config/locales/nl.yml b/plugins/easy_gantt_pro/config/locales/nl.yml
new file mode 100644
index 0000000..fb97186
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/nl.yml
@@ -0,0 +1,74 @@
+---
+nl:
+ easy_gantt_pro:
+ add_task_modal:
+ no_parent: ''
+ title: Voeg taak toe
+ baselines:
+ confirm_delete: Wilt u deze baseline echt verwijderen
+ create_failed: Er kon geen nieuwe baseline worden aangemaakt
+ delete_failed: Baseline kon niet worden verwijderd
+ error_not_saved: U moet alle wijzigingen in het project opslaan voor het aanmaken
+ van zijn baseline
+ label_baseline: Baseline
+ label_same: "-hetzelfde-"
+ cashflow:
+ label_cashflow: Cash Flow
+ critical:
+ hide_button: Verberg Kritiek pad
+ legend_issues: Taak op Kritiek pad
+ show_button: Toon Kritiek pad
+ lowest_progress:
+ label_progress_date: Voortgangsdatum
+ project_move:
+ error_opening_unsaved: U moet eerst de wijzigingen opslaan voor het openen van
+ het project
+ resources:
+ label_resources: Resources
+ easy_gantt:
+ button:
+ bulk_edit: Bulk bewerken
+ delayed_issue_filter: Filter Vertraagde Issues
+ show_lowest_progress_tasks: Toon taken met de laagste voortgangsdatum
+ show_only_critical: Filter Kritiek
+ popup:
+ add_task:
+ heading: Voeg taak hulp toe
+ text: Nieuwe taak of mijlpaal kan aangemaakt worden door te klikken op de
+ Taak button (respectievelijke Mijlpaal button) of door deze naar een willekeurige
+ plek in de grafiek te slepen.
+ baseline:
+ heading: Baseline beschrijving
+ heading_new_baseline: Nieuwe baseline
+ text: Maakt kopie van het project voor verdere vergelijkingen
+ critical:
+ heading: Kritiek pad beschrijving
+ text: Langste opeenvolging van activiteiten in een projectplan dat op tijd
+ moet worden afgerond om het project te voltooien op de vervaldag. Een activiteit
+ op het kritieke pad kan niet worden gestart tot de voorgaande activiteit
+ is voltooid; als deze een dag is uitgesteld, zal het gehele project een
+ dag worden uitgesteld, tenzij de activiteit na de vertraagde activiteit
+ een dag eerder is voltooid. Voor een goede werking van het kritieke pad,
+ moet het project slechts 1 begin- en 1 eindtaak hebben en de taken moeten
+ zijn verbonden met relaties.
+ scheme_by:
+ label_by_priority: op Prioriteit
+ label_by_status: op Status
+ label_by_tracker: op Tracker
+ label_color_by: Kleur op
+ title:
+ delayed_issue_filter: Toon alleen issues met een voortgangsdatum na vandaag
+ show_only_critical: Toon alleen taken op Kritiek pad
+ easy_pages:
+ modules:
+ easy_global_gantt: Easy gantt
+ easy_project_gantt: Easy gantt
+ easy_proposer:
+ easy_gantt:
+ index:
+ caption: Easy Gantt PRO
+ description: Ga naar Easy Gantt PRO
+ heading_easy_gantts_issues: Easy Gantt PRO
+ label_show_lowest_progress_tasks: Taken met laagste voortgang
+ text_show_lowest_progress_tasks: Toon taken met de slechtste voortgangsdatum (=datum
+ die overeenkomt met de voortgangsbalk van de taak in gantt)
diff --git a/plugins/easy_gantt_pro/config/locales/no.yml b/plugins/easy_gantt_pro/config/locales/no.yml
new file mode 100644
index 0000000..38901c6
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/no.yml
@@ -0,0 +1,2 @@
+---
+'no':
diff --git a/plugins/easy_gantt_pro/config/locales/pl.yml b/plugins/easy_gantt_pro/config/locales/pl.yml
new file mode 100644
index 0000000..46baa4c
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/pl.yml
@@ -0,0 +1,74 @@
+---
+pl:
+ easy_gantt_pro:
+ add_task_modal:
+ no_parent: ''
+ title: Dodaj zadanie
+ baselines:
+ confirm_delete: Czy na pewno chcesz usunąć tę bazę?
+ create_failed: Nowa baza nie mogła zostać utworzona
+ delete_failed: Baza nie mogła zostać usunięta
+ error_not_saved: Musisz zapisać wszystkie zmiany w projekcie przez utworzeniem
+ jego bazy
+ label_baseline: Baza
+ label_same: "-tak samo-"
+ cashflow:
+ label_cashflow: Przepływy środków pieniężnych
+ critical:
+ hide_button: Ukryj ścieżkę krytyczną
+ legend_issues: Zadanie na ścieżce krytycznej
+ show_button: Pokaż ścieżkę krytyczną
+ lowest_progress:
+ label_progress_date: Data postępu
+ project_move:
+ error_opening_unsaved: Musisz zapisać zmiany przed otworzeniem projektu
+ resources:
+ label_resources: Zasoby
+ easy_gantt:
+ button:
+ bulk_edit: Edycja seryjna
+ delayed_issue_filter: Filtruj opóźnione problemy
+ show_lowest_progress_tasks: Pokaż zadania z najbliższą datą postępu
+ show_only_critical: Filtruj krytyczne
+ popup:
+ add_task:
+ heading: Dodaj zadanie pomocy
+ text: Nowe zadanie lub krok milowy mogą zostać utworzone poprzez kliknięcie
+ przycisku Zadanie (indywidualnego przycisku Krok milowy) lub poprzez przesunięcie
+ ich w dowolne miejsce na grafie
+ baseline:
+ heading: Opis bazy
+ heading_new_baseline: Nowa baza
+ text: Twórzy kopię projektu dla późniejszych porównań
+ critical:
+ heading: Opis ścieżki krytycznej
+ text: Najdłuższa sekwencja działań w planie projektu, które muszą być ukończone
+ na czas, aby zakończyć projekt w terminie. Działanie na ścieżce krytycznej
+ nie może zostać uruchomione, dopóki poprzedzające ją działanie nie zostało
+ zakończone. Jeśli jest ono opóźnione o jeden dzień, cały projekt będzie
+ opóźniony o jeden dzień, chyba że działanie następujące po opóźnionym działaniu
+ zostanie zakończone dzień wcześniej. Dla prawidłowego funkcjonowania ścieżki
+ krytycznej, projekt powinien mieć tylko 1 zadanie początkowe i 1 zadanie
+ końcowe, które to zadania powinny być połączone relacjami.
+ scheme_by:
+ label_by_priority: wg Ważności
+ label_by_status: wg Statusu
+ label_by_tracker: wg Narzędzia śledzenia
+ label_color_by: Kolor wg
+ title:
+ delayed_issue_filter: Pokaż wyłącznie problemy, których data postępu jest poza
+ dzisiejszą
+ show_only_critical: Pokaż wyłącznie zadania na ścieżce krytycznej
+ easy_pages:
+ modules:
+ easy_global_gantt: Easy gantt
+ easy_project_gantt: Easy gantt
+ easy_proposer:
+ easy_gantt:
+ index:
+ caption: Easy Gantt PRO
+ description: Idź do Easy Gantt PRO
+ heading_easy_gantts_issues: Easy Gantt PRO
+ label_show_lowest_progress_tasks: Najbliższe zadania postępu
+ text_show_lowest_progress_tasks: Wyświetl zadania z najgorszą datą postępu (= datą
+ odpowiadającą wskaźnikowi wykonania zadania w Gantt)
diff --git a/plugins/easy_gantt_pro/config/locales/pt-BR.yml b/plugins/easy_gantt_pro/config/locales/pt-BR.yml
new file mode 100644
index 0000000..096612b
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/pt-BR.yml
@@ -0,0 +1,73 @@
+---
+pt-BR:
+ easy_gantt_pro:
+ add_task_modal:
+ no_parent: ''
+ title: Adicionar tarefa
+ baselines:
+ confirm_delete: Você realmente quer apagar essa linha de base?
+ create_failed: Linha de base não pode ser criada
+ delete_failed: Linha de base não pode ser apagada
+ error_not_saved: Você deve salvar todas as alterações no projeto antes de criar
+ sua linha de base
+ label_baseline: Linha de base
+ label_same: "-mesmo-"
+ cashflow:
+ label_cashflow: Fluxo de caixa
+ critical:
+ hide_button: Esconder trajeto crítico
+ legend_issues: Tarefas em trajeto crítico
+ show_button: Mostrar trajeto crítico
+ lowest_progress:
+ label_progress_date: Data progresso
+ project_move:
+ error_opening_unsaved: Você deve salvar as alterações antes de abrir o projeto
+ resources:
+ label_resources: Funcionalidade
+ easy_gantt:
+ button:
+ bulk_edit: Edição em massa
+ delayed_issue_filter: Filtrar Problemas de Atraso
+ show_lowest_progress_tasks: Mostrar tarefas com menor data de progresso
+ show_only_critical: Filtro crucial
+ popup:
+ add_task:
+ heading: Adicionar tarefa ajuda
+ text: Nova tarefa ou marco pode ser criado ao clicar o botão de tarefas (ou
+ no caso o botão Marco) ou arrastando em qualquer lugar no gráfico
+ baseline:
+ heading: Descrição da linha de base
+ heading_new_baseline: Linha de base nova
+ text: Cria cópia do projeto para futuras comparações
+ critical:
+ heading: Descrição de trajeto crítico
+ text: A sequência de atividades mais longa em um plano de projeto que deve
+ ser concluída a tempo para o projeto ser concluído na data devida. Uma atividade
+ no trajeto crítico não pode ser iniciada até que a sua atividade antecessora
+ for completada; se for adiada por um dia, todo o projeto será adiado por
+ um dia a menos que a atividade após a atividade retardada seja concluída
+ um dia antes. Para o bom funcionamento de um trajeto crítico, o projeto
+ deve ter apenas 1 tarefa ínicial e uma tarefa final e as tarefas devem ser
+ conectadas com relações.
+ scheme_by:
+ label_by_priority: por Prioridade
+ label_by_status: por Situação
+ label_by_tracker: por Rastreador
+ label_color_by: Coloridos por
+ title:
+ delayed_issue_filter: Mostrar apenas as problemas os qual a data de progresso
+ estiver atrasada hoje
+ show_only_critical: Mostrar somente tarefas no Trajeto crítico
+ easy_pages:
+ modules:
+ easy_global_gantt: Easy Gantt
+ easy_project_gantt: Easy Gantt
+ easy_proposer:
+ easy_gantt:
+ index:
+ caption: Easy Gantt PRO
+ description: Vá para Easy Gantt PRO
+ heading_easy_gantts_issues: Easy Gantt PRO
+ label_show_lowest_progress_tasks: Tarefas de menor progresso
+ text_show_lowest_progress_tasks: Tarefas de exibição com o pior progresso em relação
+ data (= relação entre data correspondente às tarefas feitas em gantt)
diff --git a/plugins/easy_gantt_pro/config/locales/pt.yml b/plugins/easy_gantt_pro/config/locales/pt.yml
new file mode 100644
index 0000000..e40c485
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/pt.yml
@@ -0,0 +1,2 @@
+---
+pt:
diff --git a/plugins/easy_gantt_pro/config/locales/ro.yml b/plugins/easy_gantt_pro/config/locales/ro.yml
new file mode 100644
index 0000000..0df6ab3
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/ro.yml
@@ -0,0 +1,2 @@
+---
+ro:
diff --git a/plugins/easy_gantt_pro/config/locales/ru.yml b/plugins/easy_gantt_pro/config/locales/ru.yml
new file mode 100644
index 0000000..168082b
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/ru.yml
@@ -0,0 +1,72 @@
+---
+ru:
+ easy_gantt_pro:
+ add_task_modal:
+ no_parent: ''
+ title: Добавить задачу
+ baselines:
+ confirm_delete: Вы действительно хотите удалить этот базовый план
+ create_failed: Новый базовый план не может быть создан
+ delete_failed: Базовый план не может быть удален
+ error_not_saved: Вы должны сохранить все изменения в проекте перед созданием
+ базового плана.
+ label_baseline: Базовый план
+ label_same: "-то же-"
+ cashflow:
+ label_cashflow: Cash Flow
+ critical:
+ hide_button: Скрыть критический путь
+ legend_issues: Задача на критическом пути
+ show_button: Показать критический путь
+ lowest_progress:
+ label_progress_date: сроки по прогрессу
+ project_move:
+ error_opening_unsaved: Сохраните, пожалуйста, все изменения в в проекте перед
+ его открытием.
+ resources:
+ label_resources: Ресурсы
+ easy_gantt:
+ button:
+ bulk_edit: Групповое редактирование
+ delayed_issue_filter: Фильтр по просроченным задчам
+ show_lowest_progress_tasks: Показать задачи с самой ранней датой по прогрессу
+ show_only_critical: Фильтр критических задач
+ popup:
+ add_task:
+ heading: Add Issue help
+ text: New Issue of milestone can be created by a click on Issue button (respective
+ Milestone button) or by dragging anywhere in graph
+ baseline:
+ heading: Базовый план - Описание
+ heading_new_baseline: Новый базовый план
+ text: Создание копии изначального проекта для дальнейшиго сравнения
+ critical:
+ heading: Критический Путь - описание
+ text: Длинные последовательности задач, которые должны выполняться своевременно,
+ для соблюдения Дедлайна проекта. Новые задачи на критическом пути не могут
+ уходить в работу, пока предыдущая задача не будет завершена.Если хотябы
+ на одной из задач возникнет задержка, хотябы на день, то и дедлайн проекта
+ будет передвинут на один день вперед, до тех пор, пока одна из задач не
+ будет выполненна на день раньше.
+ scheme_by:
+ label_by_priority: по приоритету
+ label_by_status: по статусу
+ label_by_tracker: по задачам
+ label_color_by: Цвет
+ title:
+ delayed_issue_filter: Показать только задачи, дата по прогрессу которых ранее
+ сегодня
+ show_only_critical: Показать только задачи на Критическом пути
+ easy_pages:
+ modules:
+ easy_global_gantt: Easy gantt
+ easy_project_gantt: Easy gantt
+ easy_proposer:
+ easy_gantt:
+ index:
+ caption: Easy Gantt PRO
+ description: Перейти в Easy Gantt PRO
+ heading_easy_gantts_issues: Easy Gantt PRO
+ label_show_lowest_progress_tasks: Задачи с наименьшим прогрессом
+ text_show_lowest_progress_tasks: Показывать задачи с самой большой задержкой (отношение
+ длительности на диаграмме Ганта к проценту выполения)
diff --git a/plugins/easy_gantt_pro/config/locales/sk.yml b/plugins/easy_gantt_pro/config/locales/sk.yml
new file mode 100644
index 0000000..354e579
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/sk.yml
@@ -0,0 +1,2 @@
+---
+sk:
diff --git a/plugins/easy_gantt_pro/config/locales/sl.yml b/plugins/easy_gantt_pro/config/locales/sl.yml
new file mode 100644
index 0000000..31bb26c
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/sl.yml
@@ -0,0 +1,2 @@
+---
+sl:
diff --git a/plugins/easy_gantt_pro/config/locales/sq.yml b/plugins/easy_gantt_pro/config/locales/sq.yml
new file mode 100644
index 0000000..9c092f0
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/sq.yml
@@ -0,0 +1,2 @@
+---
+sq:
diff --git a/plugins/easy_gantt_pro/config/locales/sr-YU.yml b/plugins/easy_gantt_pro/config/locales/sr-YU.yml
new file mode 100644
index 0000000..24e1796
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/sr-YU.yml
@@ -0,0 +1,2 @@
+---
+sr-YU:
diff --git a/plugins/easy_gantt_pro/config/locales/sr.yml b/plugins/easy_gantt_pro/config/locales/sr.yml
new file mode 100644
index 0000000..43a1014
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/sr.yml
@@ -0,0 +1,2 @@
+---
+sr:
diff --git a/plugins/easy_gantt_pro/config/locales/sv.yml b/plugins/easy_gantt_pro/config/locales/sv.yml
new file mode 100644
index 0000000..ed425ea
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/sv.yml
@@ -0,0 +1,2 @@
+---
+sv:
diff --git a/plugins/easy_gantt_pro/config/locales/th.yml b/plugins/easy_gantt_pro/config/locales/th.yml
new file mode 100644
index 0000000..3596914
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/th.yml
@@ -0,0 +1,2 @@
+---
+th:
diff --git a/plugins/easy_gantt_pro/config/locales/tr.yml b/plugins/easy_gantt_pro/config/locales/tr.yml
new file mode 100644
index 0000000..3be79e7
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/tr.yml
@@ -0,0 +1,2 @@
+---
+tr:
diff --git a/plugins/easy_gantt_pro/config/locales/zh-TW.yml b/plugins/easy_gantt_pro/config/locales/zh-TW.yml
new file mode 100644
index 0000000..44cf0f8
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/zh-TW.yml
@@ -0,0 +1,2 @@
+---
+zh-TW:
diff --git a/plugins/easy_gantt_pro/config/locales/zh.yml b/plugins/easy_gantt_pro/config/locales/zh.yml
new file mode 100644
index 0000000..acfb082
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/locales/zh.yml
@@ -0,0 +1,63 @@
+---
+zh:
+ easy_gantt_pro:
+ add_task_modal:
+ no_parent: ''
+ title: 添加任务
+ baselines:
+ confirm_delete: 确定要删除这个原始时间线?
+ create_failed: 不能创建新的 原时间线(Baseline)
+ delete_failed: 该Baseline不能被删除
+ error_not_saved: 在创建Baseline前必须先保存项目中所有变更
+ label_baseline: 原时间线
+ label_same: "- 相同 -"
+ cashflow:
+ label_cashflow: 显示资金
+ critical:
+ hide_button: 不显示关键路径
+ legend_issues: 关键路径上的任务
+ show_button: 显示关键路径
+ lowest_progress:
+ label_progress_date: 进度日期
+ project_move:
+ error_opening_unsaved: 在打开此项目前请先保存变更
+ resources:
+ label_resources: 资源
+ easy_gantt:
+ button:
+ bulk_edit: 批量编辑
+ delayed_issue_filter: 延误原因筛选
+ show_lowest_progress_tasks: 显示各任务最近的进度更新日期
+ show_only_critical: 筛选出关键的
+ popup:
+ add_task:
+ heading: 添加任务帮助
+ text: 通过点击任务(里程碑)按钮, 或在图形中拖放创建新的任务(里程碑)
+ baseline:
+ heading: 原时间线的描述
+ heading_new_baseline: 新建Baseline
+ text: 创建该项目的复本来进行比较
+ critical:
+ heading: 关键路径的描述
+ text: 项目中最长用时的路线上的工作必须在预定时间内完成. 关键路径上的工作只有在其前一个工作完成后才能启动; 如果其中一个工作延误了一天, 则整个项目会延误一天(除非后续有工作提前[完成).
+ 一个关键路径只能有一个开始和一个结束任务, 且这些任务之间用关系(Relation)连接
+ scheme_by:
+ label_by_priority: 按优先级
+ label_by_status: 按状态
+ label_by_tracker: 按状态
+ label_color_by: 按颜色
+ title:
+ delayed_issue_filter: 显示原因是进度日期在今天之后的
+ show_only_critical: 仅显示关键路径上的任务
+ easy_pages:
+ modules:
+ easy_global_gantt: Easy gantt(甘特图)
+ easy_project_gantt: Easy 甘特图
+ easy_proposer:
+ easy_gantt:
+ index:
+ caption: Easy 甘特图专业版
+ description: 转到Easy 甘特图专业版
+ heading_easy_gantts_issues: Easy Gantt PRO
+ label_show_lowest_progress_tasks: 进度最慢的任务
+ text_show_lowest_progress_tasks: 显示任务最差的更新日期( 对应任务完成比例的日期, 显示在任务进度条上)
diff --git a/plugins/easy_gantt_pro/config/routes.rb b/plugins/easy_gantt_pro/config/routes.rb
new file mode 100644
index 0000000..df48a2b
--- /dev/null
+++ b/plugins/easy_gantt_pro/config/routes.rb
@@ -0,0 +1,11 @@
+# Because of plugin deactivations
+if Redmine::Plugin.installed?(:easy_gantt_pro)
+ scope format: true, defaults: { format: 'json' }, constraints: { format: 'json' } do
+ put 'easy_gantt/reschedule_project/:id', to: 'easy_gantt#reschedule_project', as: 'easy_gantt_reschedule_project'
+ post 'easy_gantt/lowest_progress_tasks', to: 'easy_gantt_pro#lowest_progress_tasks', as: 'easy_gantt_lowest_progress_tasks'
+ end
+
+ scope 'easy_gantt', controller: 'easy_gantt_pro', as: 'easy_gantt' do
+ get 'recalculate_fixed_delay'
+ end
+end
diff --git a/plugins/easy_gantt_pro/init.rb b/plugins/easy_gantt_pro/init.rb
new file mode 100644
index 0000000..827e2d4
--- /dev/null
+++ b/plugins/easy_gantt_pro/init.rb
@@ -0,0 +1,13 @@
+Redmine::Plugin.register :easy_gantt_pro do
+ name 'PRO Easy Gantt'
+ author 'Easy Software Ltd'
+ url 'https://www.easysoftware.com'
+ author_url 'https://www.easysoftware.com'
+ description 'PRO version'
+ version '2.0'
+
+ requires_redmine_plugin :easy_gantt, version_or_higher: '2.0'
+end
+
+require_relative 'after_init'
+
diff --git a/plugins/easy_gantt_pro/lib/easy_gantt_pro.rb b/plugins/easy_gantt_pro/lib/easy_gantt_pro.rb
new file mode 100644
index 0000000..dab20c1
--- /dev/null
+++ b/plugins/easy_gantt_pro/lib/easy_gantt_pro.rb
@@ -0,0 +1,2 @@
+module EasyGanttPro
+end
\ No newline at end of file
diff --git a/plugins/easy_gantt_pro/lib/easy_gantt_pro/hooks.rb b/plugins/easy_gantt_pro/lib/easy_gantt_pro/hooks.rb
new file mode 100644
index 0000000..05e3d62
--- /dev/null
+++ b/plugins/easy_gantt_pro/lib/easy_gantt_pro/hooks.rb
@@ -0,0 +1,7 @@
+module EasyGanttPro
+ class Hooks < Redmine::Hook::ViewListener
+ render_on :view_easy_gantt_index_bottom, partial: 'hooks/easy_gantt_pro/view_easy_gantt_index_bottom'
+ render_on :view_easy_gantts_issues_toolbars, partial: 'hooks/easy_gantt_pro/view_easy_gantts_issues_toolbars'
+ render_on :view_easy_gantt_settings, partial: 'easy_settings/easy_gantt_pro'
+ end
+end
diff --git a/plugins/easy_gantt_pro/lib/easy_gantt_pro/issues_controller_patch.rb b/plugins/easy_gantt_pro/lib/easy_gantt_pro/issues_controller_patch.rb
new file mode 100644
index 0000000..721353d
--- /dev/null
+++ b/plugins/easy_gantt_pro/lib/easy_gantt_pro/issues_controller_patch.rb
@@ -0,0 +1,24 @@
+module EasyGanttPro
+ module IssuesControllerPatch
+
+ def self.prepended(base)
+ base.include InstanceMethods
+
+ base.class_eval do
+ before_action :easy_gantt_suppress_notification
+ end
+ end
+
+ module InstanceMethods
+
+ private
+
+ def easy_gantt_suppress_notification
+ RequestStore.store[:easy_gantt_suppress_notification] = (params[:issue] && params[:issue][:easy_gantt_suppress_notification] == 'true')
+ end
+
+ end
+ end
+end
+IssuesController.prepend EasyGanttPro::IssuesControllerPatch
+
diff --git a/plugins/easy_gantt_pro/lib/easy_gantt_pro/suppress_notification.rb b/plugins/easy_gantt_pro/lib/easy_gantt_pro/suppress_notification.rb
new file mode 100644
index 0000000..07d39f4
--- /dev/null
+++ b/plugins/easy_gantt_pro/lib/easy_gantt_pro/suppress_notification.rb
@@ -0,0 +1,25 @@
+module EasyGanttPro
+ module SuppressNotification
+
+ def self.prepended(base)
+ base.prepend(InstanceMethods)
+ end
+
+ module InstanceMethods
+
+ def notify?
+ if RequestStore.store[:easy_gantt_suppress_notification] == true
+ false
+ else
+ super
+ end
+ end
+
+ end
+
+ end
+end
+
+Issue.prepend EasyGanttPro::SuppressNotification
+Journal.prepend EasyGanttPro::SuppressNotification
+
diff --git a/plugins/easy_gantt_pro/spec/features/add_task_spec.rb b/plugins/easy_gantt_pro/spec/features/add_task_spec.rb
new file mode 100644
index 0000000..59c15f3
--- /dev/null
+++ b/plugins/easy_gantt_pro/spec/features/add_task_spec.rb
@@ -0,0 +1,91 @@
+require File.expand_path('../../../../easyproject/easy_plugins/easy_extensions/test/spec/spec_helper', __FILE__)
+
+RSpec.feature 'Add task', logged: :admin, js: true, js_wait: :long do
+ let!(:project) { FactoryGirl.create(:project, add_modules: ['easy_gantt']) }
+
+ around(:each) do |example|
+ with_settings(rest_api_enabled: 1, text_formatting: 'textile') { example.run }
+ end
+
+ def open_add_toolbar
+ find('.easy-gantt__menu-tools').hover
+ click_link(I18n.t(:label_new))
+ find('#button_jump_today').hover
+ end
+
+ describe 'toolbar' do
+
+ it 'should prevent submitting invalid task' do
+ # TODO: Remove this conditions
+ skip if EasyGantt.platform == 'easyproject'
+
+ visit easy_gantt_path(project)
+ wait_for_ajax
+ within('#content') do
+ open_add_toolbar
+ click_link(I18n.t(:label_issue_new))
+ end
+ wait_for_ajax
+ find('#add_issue_modal_submit').click
+ expect(page).to have_selector('.flash.error')
+ expect(find('.flash.error')).to have_text(I18n.t(:field_subject))
+ end
+
+ it 'should create valid task' do
+ # TODO: Remove this conditions
+ skip if EasyGantt.platform == 'easyproject'
+
+ visit easy_gantt_path(project)
+ wait_for_ajax
+ within('#content') do
+ open_add_toolbar
+ click_link(I18n.t(:label_issue_new))
+ end
+ wait_for_ajax
+ within('#form-modal') do
+ fill_in(I18n.t(:field_subject), with: 'Issue256')
+ end
+ find('#add_issue_modal_submit').click
+ expect(page).to have_selector('.gantt_row.fresh.task-type', text: 'Issue256')
+ accept_confirm { visit('about:blank') }
+ end
+
+ it 'should prevent submitting invalid milestone' do
+ # TODO: Remove this conditions
+ skip if EasyGantt.platform == 'easyproject'
+
+ visit easy_gantt_path(project)
+ wait_for_ajax
+ within('#content') do
+ open_add_toolbar
+ click_link(I18n.t(:label_version_new))
+ click_link(I18n.t(:label_version_new))
+ end
+ wait_for_ajax
+ find('#add_milestone_modal_submit').click
+ expect(page).to have_selector('.flash.error')
+ expect(find('.flash.error')).to have_text(I18n.t(:field_name))
+ end
+
+ it 'should create valid milestone' do
+ # TODO: Remove this conditions
+ skip if EasyGantt.platform == 'easyproject'
+
+ visit easy_gantt_path(project)
+ wait_for_ajax
+ within('#content') do
+ open_add_toolbar
+ click_link(I18n.t(:label_version_new))
+ click_link(I18n.t(:label_version_new))
+ end
+ wait_for_ajax
+ within('#form-modal') do
+ fill_in(I18n.t(:field_name), with: 'Milestone256')
+ end
+ find('#add_milestone_modal_submit').click
+ expect(page).to have_selector('.gantt_row.fresh.milestone-type', text: 'Milestone256')
+ accept_confirm { visit('about:blank') }
+ end
+
+ end
+end
diff --git a/plugins/easy_gantt_pro/spec/features/baseline_spec.rb b/plugins/easy_gantt_pro/spec/features/baseline_spec.rb
new file mode 100644
index 0000000..dee1be3
--- /dev/null
+++ b/plugins/easy_gantt_pro/spec/features/baseline_spec.rb
@@ -0,0 +1,68 @@
+require File.expand_path('../../../../easyproject/easy_plugins/easy_extensions/test/spec/spec_helper', __FILE__)
+
+RSpec.feature 'Baseline', :logged => :admin, :js => true do
+ let!(:project_no_baseline) { FactoryGirl.create(:project, add_modules: %w(easy_gantt)) }
+ let!(:project) { FactoryGirl.create(:project, add_modules: %w(easy_gantt easy_baselines)) }
+
+ around(:each) do |example|
+ with_settings(rest_api_enabled: 1) do
+ example.run
+ end
+ end
+
+ def open_baseline_toolbar
+ find('.easy-gantt__menu-tools').hover
+ expect(page).to have_selector('#button_baseline')
+ find('#button_baseline').click
+ find('#button_jump_today').hover
+ end
+
+ it 'should not be displayed if module is turned off' do
+ visit easy_gantt_path(project_no_baseline)
+ wait_for_ajax
+ page.find('.easy-gantt__menu-tools').hover
+ expect(page).to have_no_selector('#button_baseline')
+ end
+
+ it 'should load empty header' do
+ # TODO: Remove this conditions
+ skip if EasyGantt.platform == 'easyproject'
+
+ visit easy_gantt_path(project)
+ wait_for_ajax
+ within('#content') do
+ find('.easy-gantt__menu-tools').hover
+ open_baseline_toolbar
+ expect(page).to have_selector('#baseline_create')
+ expect(page).to have_no_selector('#baseline_select')
+ end
+ end
+
+ it 'create, load and delete new baseline' do
+ # TODO: Remove this conditions
+ skip if EasyGantt.platform == 'easyproject'
+
+ visit easy_gantt_path(project)
+ wait_for_ajax
+ within('#content') do
+ open_baseline_toolbar
+ expect(page).to have_no_selector('.gantt-baseline')
+ find('#baseline_create').click
+ end
+ within('#form-modal') do
+ fill_in(I18n.t(:field_name), :with => 'Baseline of '+project.name)
+ end
+ find('#baseline_modal_submit').click
+ wait_for_ajax 20
+ expect(page).to have_selector('#baseline_select') #.to have_content('Baseline of '+project.name)
+ expect(page).to have_selector('.gantt-baselines')
+ expect(page).to have_selector('.gantt-baseline')
+ message = accept_confirm do
+ find('#baseline_delete').click
+ end
+ expect(message).to eq(I18n.t(:text_are_you_sure))
+ expect(page).to have_no_selector('.gantt-baseline')
+ expect(page).to have_no_selector('#baseline_select')
+ end
+
+end
diff --git a/plugins/easy_gantt_pro/spec/features/correct_tree_spec.rb b/plugins/easy_gantt_pro/spec/features/correct_tree_spec.rb
new file mode 100644
index 0000000..56966e2
--- /dev/null
+++ b/plugins/easy_gantt_pro/spec/features/correct_tree_spec.rb
@@ -0,0 +1,57 @@
+require File.expand_path('../../../../easyproject/easy_plugins/easy_extensions/test/spec/spec_helper', __FILE__)
+
+RSpec.feature 'Correct tree', logged: :admin, js: true do
+
+ let(:subproject) {
+ FactoryGirl.create(:project, parent_id: superproject.id, add_modules: ['easy_gantt'], number_of_issues: 0)
+ }
+ let(:superproject) {
+ FactoryGirl.create(:project, add_modules: ['easy_gantt'], number_of_issues: 0)
+ }
+ let(:superproject_issues) {
+ FactoryGirl.create_list(:issue, 3, fixed_version_id: milestone_superproject.id, project_id: superproject.id)
+ }
+ let(:subproject_issues) {
+ FactoryGirl.create_list(:issue, 3, fixed_version_id: milestone_subproject.id, project_id: subproject.id)
+ }
+ let(:milestone_subproject) {
+ FactoryGirl.create(:version, project_id: subproject.id)
+ }
+ let(:milestone_superproject) {
+ FactoryGirl.create(:version, project_id: superproject.id)
+ }
+ let(:subissues) {
+ FactoryGirl.create_list(:issue, 3, parent_issue_id: superproject_issues[0].id, project_id: superproject.id)
+ }
+
+ around(:each) do |example|
+ with_settings(rest_api_enabled: 1) { example.run }
+ end
+
+ it 'should show superproject items and hide subproject items and show them after open' do
+ superproject_issues
+ subproject_issues
+ milestone_subproject
+ visit easy_gantt_path(superproject)
+ wait_for_ajax
+ # superproject items are shown
+ expect(page).to have_text(superproject.name)
+ expect(page).to have_text(milestone_superproject.name)
+ superproject_issues.each do |issue|
+ expect(page).to have_text(issue.subject)
+ end
+ # subproject items are hidden
+ expect(page).to have_text(subproject.name)
+ expect(page).not_to have_text(milestone_subproject.name)
+ subproject_issues.each do |issue|
+ expect(page).not_to have_text(issue.subject)
+ end
+ # open subproject to show its items
+ page.find("div[task_id='p#{subproject.id}'] .gantt_open").click
+ wait_for_ajax
+ expect(page).to have_text(milestone_subproject.name)
+ subproject_issues.each do |issue|
+ expect(page).to have_text(issue.subject)
+ end
+ end
+end
diff --git a/plugins/easy_gantt_pro/spec/features/critical_spec.rb b/plugins/easy_gantt_pro/spec/features/critical_spec.rb
new file mode 100644
index 0000000..c933ec3
--- /dev/null
+++ b/plugins/easy_gantt_pro/spec/features/critical_spec.rb
@@ -0,0 +1,53 @@
+require File.expand_path('../../../../easyproject/easy_plugins/easy_extensions/test/spec/spec_helper', __FILE__)
+
+RSpec.feature 'Critical', js: true, logged: :admin do
+
+ let!(:project) { FactoryGirl.create(:project, add_modules: ['easy_gantt']) }
+ #let!(:issue1) { FactoryGirl.create(:issue) }
+ #let!(:issue2) { FactoryGirl.create(:issue) }
+ #let!(:relation) { FactoryGirl.create(:issue_relation, source_id:issue1.id, target_id:issue2.id) }
+
+ around(:each) do |example|
+ with_settings(rest_api_enabled: 1) do
+ with_easy_settings(easy_gantt_critical_path: 'last') do
+ example.run
+ end
+ end
+ end
+
+ def open_critical_toolbar
+ find('.easy-gantt__menu-tools').hover
+ find('#button_critical').click
+ find('#button_jump_today').hover
+ end
+
+ # TODO: '.gantt_task_line.gantt_task-type.critical' is empty
+ #
+ # it 'should test draw critical path' do
+ # # TODO: Remove this conditions
+ # skip if EasyGantt.platform == 'easyproject'
+ #
+ # visit easy_gantt_path(project)
+ # wait_for_ajax
+ # within('#content') do
+ # open_critical_toolbar
+ # #click_link(l(:critical_path,:scope=>[:easy_gantt,:buttons]))
+ # expect(page).to have_css('#critical_show.active')
+ # expect(find('.gantt_task_line.gantt_task-type.critical')).to have_content(project.issues.first.subject)
+ # end
+ # end
+
+ it 'should open help' do
+ # TODO: Remove this conditions
+ skip if EasyGantt.platform == 'easyproject'
+
+ visit easy_gantt_path(project)
+ wait_for_ajax
+ within('#content') do
+ open_critical_toolbar
+ find('#button_critical_help').click
+ end
+ expect(page).to have_css('#critical_help_modal_popup')
+ end
+
+end
diff --git a/plugins/easy_gantt_pro/spec/features/easy_gantt_spec.rb b/plugins/easy_gantt_pro/spec/features/easy_gantt_spec.rb
new file mode 100644
index 0000000..f90cddd
--- /dev/null
+++ b/plugins/easy_gantt_pro/spec/features/easy_gantt_spec.rb
@@ -0,0 +1,21 @@
+require File.expand_path('../../../../easyproject/easy_plugins/easy_extensions/test/spec/spec_helper', __FILE__)
+
+feature 'easy gantt', :js => true, :logged => :admin do
+ let!(:project) { FactoryGirl.create(:project, add_modules: ['easy_gantt']) }
+ describe 'show gantt' do
+ around(:each) do |example|
+ with_settings(rest_api_enabled: 1) do
+ example.run
+ end
+ end
+
+ scenario 'show global easy gantt' do
+ visit easy_gantt_path
+ wait_for_ajax
+ expect(page).to have_css('#easy_gantt')
+ expect(page.find('.gantt_grid_data')).to have_content(project.name)
+ end
+
+ end
+
+end
diff --git a/plugins/easy_gantt_pro/spec/features/global_gantt_spec.rb b/plugins/easy_gantt_pro/spec/features/global_gantt_spec.rb
new file mode 100644
index 0000000..130fb85
--- /dev/null
+++ b/plugins/easy_gantt_pro/spec/features/global_gantt_spec.rb
@@ -0,0 +1,65 @@
+require File.expand_path('../../../../easyproject/easy_plugins/easy_extensions/test/spec/spec_helper', __FILE__)
+
+RSpec.feature 'Global gantt', logged: :admin, js: true do
+ let(:subproject) {
+ FactoryGirl.create(:project, :parent_id => superproject.id, add_modules: ['easy_gantt'], number_of_issues: 3)
+ }
+ let(:superproject) {
+ FactoryGirl.create(:project, add_modules: ['easy_gantt'], number_of_issues: 3)
+ }
+ let(:project2) {
+ FactoryGirl.create(:project, add_modules: ['easy_gantt'], number_of_issues: 3)
+ }
+ let(:milestone_issues) {
+ FactoryGirl.create_list(:issue, 3, :fixed_version_id => milestone_superproject.id, :project_id => superproject.id)
+ }
+ let(:milestone_superproject) {
+ FactoryGirl.create(:version, project_id: superproject.id)
+ }
+ around(:each) do |example|
+ with_settings(rest_api_enabled: 1) { example.run }
+ end
+ it 'should load projects' do
+ superproject
+ subproject
+ project2
+ visit easy_gantt_path
+ wait_for_ajax
+ expect(page).not_to have_text(subproject.name)
+ expect(page).to have_text(superproject.name)
+ expect(page).to have_text(project2.name)
+ end
+
+ it 'should load only subproject' do
+ superproject
+ subproject
+ visit easy_gantt_path
+ wait_for_ajax
+ expect(page).to have_text(superproject.name)
+ page.find("div[task_id='p#{superproject.id}'] .gantt_open").click
+ wait_for_ajax
+ superproject.issues.each do |issue|
+ expect(page).not_to have_text(issue.subject)
+ end
+ expect(page).to have_text(subproject.name)
+ end
+
+ it 'should load superproject\'s issues' do
+ superproject
+ subproject
+ visit easy_gantt_path
+ wait_for_ajax
+ expect(page).to have_text(superproject.name)
+ superproject.issues.each do |issue|
+ expect(page).not_to have_text(issue.subject)
+ end
+ page.find("div[task_id='p#{superproject.id}'] .gantt-grid-project-issues-expand").click
+ wait_for_ajax
+ expect(superproject.issues.length).to eq(3)
+ superproject.issues.each do |issue|
+ expect(page).to have_text(issue.subject)
+ end
+ expect(page).to have_text(subproject.name)
+ end
+
+end
\ No newline at end of file
diff --git a/plugins/easy_gantt_pro/test/test_helper.rb b/plugins/easy_gantt_pro/test/test_helper.rb
new file mode 100644
index 0000000..54685d3
--- /dev/null
+++ b/plugins/easy_gantt_pro/test/test_helper.rb
@@ -0,0 +1,2 @@
+# Load the Redmine helper
+require File.expand_path(File.dirname(__FILE__) + '/../../../test/test_helper')
diff --git a/plugins/easy_gantt_pro/version b/plugins/easy_gantt_pro/version
new file mode 100644
index 0000000..c97a1f2
--- /dev/null
+++ b/plugins/easy_gantt_pro/version
@@ -0,0 +1 @@
+2016.07.RC