diff --git a/README.md b/README.md index f4624d7..9b0ee13 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Webix UI v.10.3.0 +Webix UI v.10.3.1 ================ [![npm version](https://badge.fury.io/js/webix.svg)](https://badge.fury.io/js/webix) diff --git a/codebase/webix.js b/codebase/webix.js index 4814f49..440f096 100644 --- a/codebase/webix.js +++ b/codebase/webix.js @@ -1,6 +1,6 @@ /** * @license - * webix UI v.10.3.0 + * webix UI v.10.3.1 * This software is allowed to use under GPL or you need to obtain Commercial License * to use it in non-GPL project. Please contact sales@webix.com for details */ @@ -17628,7 +17628,7 @@ } }; - var version = "10.3.0"; + var version = "10.3.1"; var name = "core"; var errorMessage = "non-existing view for export"; @@ -18562,10 +18562,7 @@ } // set type based on cell's value - if (options.stubCells && stringValue === "") { - cell.t = "z"; - delete cell.v; - } else if (cell.v instanceof Date) { + if (options.stubCells && stringValue === "") cell.t = "z";else if (cell.v instanceof Date) { cell.t = cell.t || "n"; cell.z = cell.z || XLSX.SSF[table][14]; cell.v = excelDate(cell.v); @@ -18579,7 +18576,6 @@ cell.t = "s"; } } - ws[cell_ref] = cell; } } @@ -30958,7 +30954,7 @@ } else node = toNode(input); if (input != document.body) _event(node, "keydown", function (e) { - if (_this.isVisible() && (input.config ? !input.config.readonly : !node.getAttribute("readonly"))) _this._suggestions(e, node); + if (input.config ? !input.config.readonly : !node.getAttribute("readonly")) _this._suggestions(e, node); }); if (input._getInputDiv) node = input._getInputDiv(); node.setAttribute("aria-autocomplete", "list"); diff --git a/codebase/webix.min.js b/codebase/webix.min.js index cbec6db..4eeb456 100644 --- a/codebase/webix.min.js +++ b/codebase/webix.min.js @@ -1,6 +1,6 @@ /** * @license - * webix UI v.10.3.0 + * webix UI v.10.3.1 * This software is allowed to use under GPL or you need to obtain Commercial License * to use it in non-GPL project. Please contact sales@webix.com for details */ @@ -63,20 +63,20 @@ s=this.getItemNode(t),"update"===e?s&&($t(this.Ki[t]=this.Xu(i),s),x(s)):this.Sl null,null,"paint")},Al:function(t){var i=Math.max(t.count,this.N.datafetch||this.N.loadahead||0);this.Rr(t.count,t.start)||this.loadNext(i,t.start)},vo:function(){this.render(null,null,"drag-in")},So:function(){x(F.wn),this.render(null,null,"drag-out")}},ys="non-existing view for export";function Ss(t,i){var e=i.text;return((e=i.contentId&&(i=t.getHeaderContent(i.contentId))&&!i.type.$icon?i.getValue(!0):e)||"").toString().replace(/<[^>]*>/gi,"")}function Ms(t,i,e){return e[t]&&e[t][i]?e[t][i]:{}}function ks(t,i){var e,s,n=[],h=0,r=0,o=t.getColumnConfig,a=i.columns,u=!!i.rawValues,c="TreeStore"==t.data.name,l=i.treeLines;if(!0!==l&&!E(l)||(l="value"),n.heights={},(i.hidden||i.hide)&&(n.hiddenCols={},n.hiddenRows={}),a){if(!a.length){var f,d=[];for(f in a)d.push(R.extend({id:f},R.extend({},a[f])));a=d}}else if(a=[],o){var _=t.Or;if(i.hidden&&_.length)for(var v=0;v<_.length;v++){var p=t.getColumnConfig(_[v]);t.isColumnVisible(p.id)||(n.hiddenCols[p.id]=1),a.push(p)}else a=a.concat(t.Pl)}else for(e in t.data.pull[t.data.order[0]])"id"!==e&&"$"!=e[0]&&a.push({id:e,isTree:c&&e===l});if(i.ignore)for(var m=a.length-1;0<=m;m--)i.ignore[a[m].id]&&a.splice(m,1);if(i.id&&n.push({id:"id",width:50,header:" ",template:function(t){return t.id}}),i.flatTree){for(var b=i.flatTree.id,g=[].concat(i.flatTree.columns),w=[],V=!!i.flatTree.fill,x=1;x<=g.length;x++)g[x-1].template=function(i){return function(t){return t.$level==i?w[i]=t[b]:V&&i:*|"]/g,"").substring(0,150),"".concat(t||"Data",".").concat(i)}function $s(u,c,l){var t,f=!!c.filterHTML,d=/<[^>]*>/gi,_=[],v=c.export_mode;if("excel"!==v&&"csv"!=v||!c.docHeader||(_=[[(c.docHeader.text||c.docHeader).toString()],[""]],"excel"===v&&c.docHeader.height&&(l.heights[0]=c.docHeader.height)),!1!==c.header&&l.length)for(var i=0;i/gm,"\n"))),h&&(a={formula:h,value:a})),s.push(a)}"excel"==v&&u.Pl&&!1!==c.heights&&(t.$height&&t.$height!==A.rowHeight||"all"==c.heights)&&(l.heights[_.length]=t.$height||this.config.rowHeight),_.push(s)}},u,c.hidden),!1!==c.footer)for(var n=l[0].footer?l[0].footer.length:0,h=0;hA.text&&F.header({paddingBottom:10}).text(T.docHeader.text,T.docHeader),T.docHeaderImage?(e=B.defer(),pdfjs.load(T.docHeaderImage.url,function(t,i){t||(t=new pdfjs.Image(i),F.header({paddingBottom:10}).image(t,T.docHeaderImage),T.docHeader&&A.imageo&&(r.s.r=o),r.s.c>a&&(r.s.c=a),r.e.r11?i18n.pm[0]:i18n.am[0])+"';case"%A":return'"+(date.getHours()>11?i18n.pm[1]:i18n.am[1])+"';case"%s":return'"+wDate.toFixed(date.getSeconds())+"';case"%S":return'"+wDate.toFixed(date.getMilliseconds(), true)+"';case"%W":return'"+wDate.toFixed(wDate.getISOWeek(date))+"';case"%c":var i,e,s=(s=(s=(s='"+date.getFullYear()+"')+'-"+wDate.toFixed((date.getMonth()+1))+"'+'-"+wDate.toFixed(date.getDate())+"')+"T"+'"+wDate.toFixed(date.getHours())+"')+':"+wDate.toFixed(date.getMinutes())+"'+':"+wDate.toFixed(date.getSeconds())+"';return o?(i=(new Date).getTimezoneOffset())?(e=i<0?"+":"-",i=Math.abs(i),s+=e+((e=Math.floor(i/60))<10?"0":"")+e+":"+((e=i%60)<10?"0":"")+e):s+="Z":r&&(s+="Z"),s;default:return t}}),!0===r&&(h=h.replace(/date\.get/g,"date.getUTC"));var i=new Function("date","i18n","wDate","if (!date) return ''; if (!date.getMonth) date=i18n.parseFormatDate(date); return \""+h+'";');return function(t){return i(t,j,P)}},strToDate:function(t,n,h){if("function"==typeof t -)return t;var r,i,e,o=t.match(/%[a-zA-Z]/g),s="var temp=date.split(/[\\s\\./\\-\\:\\,]+/g); if(!temp.join('')){return ''}";if(!j.calendar.monthShort_hash){for(e=j.calendar.monthShort,i=j.calendar.monthShort_hash={},r=0;r30?1900:2000);";break;case"%g":case"%G":case"%h":case"%H":s+="set[3]=temp["+r+"]||0;";break;case"%i":s+="set[4]=temp["+r+"]||0;";break;case"%Y":s+="set[0]=(temp["+r+"]||0)*1; if (set[0]<30) set[0]+=2000;";break;case"%a":s+="set[3]=set[3]%12+(temp["+r+"]==i18n.am[0]?0:12);";break;case"%A":s+="set[3]=set[3]%12+(temp["+r+"]==i18n.am[1]?0:12);";break;case"%s":s+="set[5]=temp["+r+"]||0;";break;case"%S":s+="set[6]=temp["+r+"]||0;";break;case"%M":s+="set[1]=i18n.calendar.monthShort_hash[temp["+r+"]]||0;";break;case"%F":s+="set[1]=i18n.calendar.monthFull_hash[temp["+r+"]]||0;";break;case"%c":s+="\n\t\t\t\t\t\tconst reg = /(\\d{4})-?(\\d{2})?-?(\\d{2})?T?(\\d{2})?:?(\\d{2})?:?(\\d{2})?[,|.]?(\\d{3})?(Z|\\+|-)?(\\d{2})?:?(\\d{2})?/;\n\t\t\t\t\t\tconst res = reg.exec(date);\n\t\t\t\t\t\tset[0]= (res[1]||0)*1;\n\t\t\t\t\t\tset[1]= (res[2]||1)-1;\n\t\t\t\t\t\tset[2]= (res[3]||1)*1;\n\t\t\t\t\t\tset[3]= (res[4]||0)*1;\n\t\t\t\t\t\tset[4]= (res[5]||0)*1;\n\t\t\t\t\t\tset[5]= (res[6]||0)*1;\n\t\t\t\t\t\tset[6]= (res[7]||0)*1;\n\n\t\t\t\t\t\tif(".concat(h,' && res[8] && res[8] != "Z"){\n\t\t\t\t\t\t\tconst sign = res[8] == "-" ? -1 : 1;\n\t\t\t\t\t\t\tconst tzDifference = sign * ((res[9]||0)*60 + (res[10]||0)*1);\n\t\t\t\t\t\t\tif(tzDifference)\n\t\t\t\t\t\t\t\tset[4] += tzDifference + new Date().getTimezoneOffset();\n\t\t\t\t\t\t}')}var t="set[0],set[1],set[2],set[3],set[4],set[5],set[6]",a=(n&&(t=" Date.UTC("+t+")"),new Function("date","i18n","if (!date) return ''; if (typeof date == 'object') return date; var set=[0,0,1,0,0,0,0]; "+s+" return new Date("+t+");"));return function(t){return a(t,j)}},getISOWeek:function(t){var i,e;return!!t&&(0===(e=t.getDay())&&(e=7),(i=new Date(t.valueOf())).setDate(t.getDate()+(4-e)),t=i.getFullYear(),e=Math.floor((i.getTime()-new Date(t,0,1).getTime())/864e5),1+Math.floor(e/7))},getUTCISOWeek:function(t){return this.getISOWeek(t)},Bl:function(t,i,e,s){if(e){var n=s(t,i);if(n)for(var h=0"}},textFilter:{getInputNode:function(t){return t.querySelector("input")||{value:null}},getValue:function(t){return this.getInputNode(t).value},setValue:function(t,i){this.getInputNode(t).value=i},refresh:function(t,i,e){i.component=t.N.id,t.registerFilter(i,e,this),i.Zl=t.N.id,e.value&&this.getValue(i)!=e.value&&this.setValue(i,e.value),i.onclick=d,o(i,"keydown",this.Jl)},render:function(t,i){return this.init&&this.init(i),i.css=(i.css||"")+" webix_ss_filter",""},Jl:function(t){var i=this.Zl;9!=(t.which||t.keyCode)&&(this.Ql&&window.clearTimeout(this.Ql),this.Ql=window.setTimeout(function(){var t=v(i);t&&t.filterByAll()},sn.textWaitDelay))}},selectFilter:{getInputNode:function(t){return t.querySelector("select")||{value:null}},getValue:function(t){return this.getInputNode(t).value},setValue:function(t,i){this.getInputNode(t).value=i},refresh:function(t,i,e){e.compare=e.compare||function(t,i){return t==i},i.component=t.N.id,t.registerFilter(i,e,this);for(var s=sn.tf(t,e),n=(!1!==e.emptyOption&&s.unshift({id:"",value:e.emptyOption||""}),document.createElement("select")),h=0;h")?e=this.sf:-1!=t.indexOf("<")&&(e=this.nf),h.compare=e&&i?function(t,i){return s.hf(t,i)||e(t,i)}:e||this.hf,n)}}, -format:function(t){return t.replace(/[^\-.0-9]/g,"")},sf:function(t,i){return i<+t},nf:function(t,i){return""!==t&&+t< =]+/,""))}return i.valueOf()}},sn.numberFilter),(D.mobile||D.$customScroll)&&(D.scrollSize=0),Mi(function(){D.scrollSize=function(){var t=g("div"),i=(t.className="webix_skin_mark",t.style.cssText="position:absolute;left:-1000px;width:100px;padding:0px;margin:0px;min-height:100px;overflow-y:scroll;",document.body.appendChild(t),t.offsetWidth-t.clientWidth),e={200:"flat",210:"compact",220:"contrast",230:"material",240:"mini",250:"willow",260:"dark"}[10*Math.floor(t.offsetHeight/10)];document.body.removeChild(t),e&&Qi(e);return D.$customScroll?0:i}()});var nn=!1;q("fixHeight",function(){nn||(Mt("html, body{ height:100%; }"),document.body.className+=" webix_full_screen",I.limit(!1),nn=!0)}),a.animate=function(t,i,e){var s,n=v(i);if(n)return e=e||{type:"slide",direction:"left"},n=n.Bt.cloneNode(!0),(t=a(t,i)).Bt.parentNode.appendChild(n),s=k.formLine(t.Bt,n,e),e.callback=function(){k.breakLine(s)},k(s,e),t},a.animateView=function(i,t,e){if(i=v(i)){e=e||{type:"slide",direction:"left"};for(var s=function(t){var t=t.Bt,i=t.className,e=t.innerHTML;return"
"+e+"
"},n=[],h=0;hthis.di.length)&&(i=this.di.length),et.insertAt.call(this.di,t,i),t.N.hidden||this.pf(t,this.di[i])):(s=v(i),i=et.find.call(this.di,s),t.N.hidden||this.pf(t,s),s.destructor(),this.di[i]=t),this.lf||this._a(t);this._f(!0);var s=this.elements?this:this.getFormView();s&&!this.mf&&s.pe(),p("onReconstruct",[this])},_a:function(t){t.Bt.style.display="inline-block",t.Bt.style.verticalAlign="top"},addView:function(t,i){E(i)&&(i=this.di.length);var e=this.$$?this:this.getTopParentView(),e=(S.xt=this,e&&e.ui?e.ui(t,this,i):a(t,this,i));return S.xt=null,e.N.id},removeView:function(t){var i,t="object"!=w(t)?v(t)||(this.$$?this.$$(t):null):t,e=et.find.call(this.di,t);0<=e&&(this.df&&this.df(e,t),i=this.elements?this:this.getFormView(),this.di.splice(e,1),i&&yi(t,function(t){t.name&&delete i.getCleanValues()[t.config.name]},i,!0),t.destructor(),this._f(!0),i&&i.pe()),p("onReconstruct",[this])},reconstruct:function(){this.vf=0,this.zt(this.ff)},Wi:function(t,i,e){t.N.hidden||(t.N.hidden=!0,x(t.Bt),this.vf++,e||S.St||this.resizeChildren(!0))},He:function(t){t.callEvent&&t.callEvent("onViewShow",[])},resizeChildren:function(){if(!S.wt&&this.uf){var t=this.getParentView();if(t)return t.resizeChildren?t.resizeChildren():t.resize();var i,e,s=this.$getSize(0,0),n=i=this.uf[0]||0,h=e=this.uf[1]||0;(1e5<=s[1 -]||1e5<=s[3])&&this.Bt.parentNode&&(n=i=Math.max(s[0],this.N.width||this.Bt.parentNode.offsetWidth||i||0),h=e=Math.max(s[2],this.N.height||this.Bt.parentNode.offsetHeight||e||0)),t?this.ba(i,e):(s[0]>i&&(n=s[0]),s[2]>e&&(h=s[2]),!(t=this.Bt.parentNode==document.body&&!this.setPosition)&&i>s[1]&&(n=s[1]),!t&&e>s[3]&&(h=s[3]),this.$setSize(n,h)),S.bt&&(S.bt=!1,this.resizeChildren()),p("onResize",[])}},getChildViews:function(){return this.di},index:function(t){t.N&&(t=t.N.id);for(var i=0;is&&(s=e[0]),e[1]r&&(r=e[2]),e[3]11?i18n.pm[0]:i18n.am[0])+"';case"%A":return'"+(date.getHours()>11?i18n.pm[1]:i18n.am[1])+"';case"%s":return'"+wDate.toFixed(date.getSeconds())+"';case"%S":return'"+wDate.toFixed(date.getMilliseconds(), true)+"';case"%W":return'"+wDate.toFixed(wDate.getISOWeek(date))+"';case"%c":var i,e,s=(s=(s=(s='"+date.getFullYear()+"')+'-"+wDate.toFixed((date.getMonth()+1))+"'+'-"+wDate.toFixed(date.getDate())+"')+"T"+'"+wDate.toFixed(date.getHours())+"')+':"+wDate.toFixed(date.getMinutes())+"'+':"+wDate.toFixed(date.getSeconds())+"';return o?(i=(new Date).getTimezoneOffset())?(e=i<0?"+":"-",i=Math.abs(i),s+=e+((e=Math.floor(i/60))<10?"0":"")+e+":"+((e=i%60)<10?"0":"")+e):s+="Z":r&&(s+="Z"),s;default:return t}}),!0===r&&(h=h.replace(/date\.get/g,"date.getUTC"));var i=new Function("date","i18n","wDate","if (!date) return ''; if (!date.getMonth) date=i18n.parseFormatDate(date); return \""+h+'";');return function(t){return i(t,j,P)}},strToDate:function(t,n,h){if("function"==typeof t)return t;var r,i,e, +o=t.match(/%[a-zA-Z]/g),s="var temp=date.split(/[\\s\\./\\-\\:\\,]+/g); if(!temp.join('')){return ''}";if(!j.calendar.monthShort_hash){for(e=j.calendar.monthShort,i=j.calendar.monthShort_hash={},r=0;r30?1900:2000);";break;case"%g":case"%G":case"%h":case"%H":s+="set[3]=temp["+r+"]||0;";break;case"%i":s+="set[4]=temp["+r+"]||0;";break;case"%Y":s+="set[0]=(temp["+r+"]||0)*1; if (set[0]<30) set[0]+=2000;";break;case"%a":s+="set[3]=set[3]%12+(temp["+r+"]==i18n.am[0]?0:12);";break;case"%A":s+="set[3]=set[3]%12+(temp["+r+"]==i18n.am[1]?0:12);";break;case"%s":s+="set[5]=temp["+r+"]||0;";break;case"%S":s+="set[6]=temp["+r+"]||0;";break;case"%M":s+="set[1]=i18n.calendar.monthShort_hash[temp["+r+"]]||0;";break;case"%F":s+="set[1]=i18n.calendar.monthFull_hash[temp["+r+"]]||0;";break;case"%c":s+="\n\t\t\t\t\t\tconst reg = /(\\d{4})-?(\\d{2})?-?(\\d{2})?T?(\\d{2})?:?(\\d{2})?:?(\\d{2})?[,|.]?(\\d{3})?(Z|\\+|-)?(\\d{2})?:?(\\d{2})?/;\n\t\t\t\t\t\tconst res = reg.exec(date);\n\t\t\t\t\t\tset[0]= (res[1]||0)*1;\n\t\t\t\t\t\tset[1]= (res[2]||1)-1;\n\t\t\t\t\t\tset[2]= (res[3]||1)*1;\n\t\t\t\t\t\tset[3]= (res[4]||0)*1;\n\t\t\t\t\t\tset[4]= (res[5]||0)*1;\n\t\t\t\t\t\tset[5]= (res[6]||0)*1;\n\t\t\t\t\t\tset[6]= (res[7]||0)*1;\n\n\t\t\t\t\t\tif(".concat(h,' && res[8] && res[8] != "Z"){\n\t\t\t\t\t\t\tconst sign = res[8] == "-" ? -1 : 1;\n\t\t\t\t\t\t\tconst tzDifference = sign * ((res[9]||0)*60 + (res[10]||0)*1);\n\t\t\t\t\t\t\tif(tzDifference)\n\t\t\t\t\t\t\t\tset[4] += tzDifference + new Date().getTimezoneOffset();\n\t\t\t\t\t\t}')}var t="set[0],set[1],set[2],set[3],set[4],set[5],set[6]",a=(n&&(t=" Date.UTC("+t+")"),new Function("date","i18n","if (!date) return ''; if (typeof date == 'object') return date; var set=[0,0,1,0,0,0,0]; "+s+" return new Date("+t+");"));return function(t){return a(t,j)}},getISOWeek:function(t){var i,e;return!!t&&(0===(e=t.getDay())&&(e=7),(i=new Date(t.valueOf())).setDate(t.getDate()+(4-e)),t=i.getFullYear(),e=Math.floor((i.getTime()-new Date(t,0,1).getTime())/864e5),1+Math.floor(e/7))},getUTCISOWeek:function(t){return this.getISOWeek(t)},Bl:function(t,i,e,s){if(e){var n=s(t,i);if(n)for(var h=0"}},textFilter:{getInputNode:function(t){return t.querySelector("input")||{value:null}},getValue:function(t){return this.getInputNode(t).value},setValue:function(t,i){this.getInputNode(t).value=i},refresh:function(t,i,e){i.component=t.N.id,t.registerFilter(i,e,this),i.Zl=t.N.id,e.value&&this.getValue(i)!=e.value&&this.setValue(i,e.value),i.onclick=d,o(i,"keydown",this.Jl)},render:function(t,i){return this.init&&this.init(i),i.css=(i.css||"")+" webix_ss_filter",""},Jl:function(t){var i=this.Zl;9!=(t.which||t.keyCode)&&(this.Ql&&window.clearTimeout(this.Ql),this.Ql=window.setTimeout(function(){var t=v(i);t&&t.filterByAll()},sn.textWaitDelay))}},selectFilter:{getInputNode:function(t){return t.querySelector("select")||{value:null}},getValue:function(t){return this.getInputNode(t).value},setValue:function(t,i){this.getInputNode(t).value=i},refresh:function(t,i,e){e.compare=e.compare||function(t,i){return t==i},i.component=t.N.id,t.registerFilter(i,e,this);for(var s=sn.tf(t,e),n=(!1!==e.emptyOption&&s.unshift({id:"",value:e.emptyOption||""}),document.createElement("select")),h=0;h")?e=this.sf:-1!=t.indexOf("<")&&(e=this.nf),h.compare=e&&i?function(t,i){return s.hf(t,i)||e(t,i)}:e||this.hf,n)}},format:function(t){ +return t.replace(/[^\-.0-9]/g,"")},sf:function(t,i){return i<+t},nf:function(t,i){return""!==t&&+t< =]+/,""))}return i.valueOf()}},sn.numberFilter),(D.mobile||D.$customScroll)&&(D.scrollSize=0),Mi(function(){D.scrollSize=function(){var t=g("div"),i=(t.className="webix_skin_mark",t.style.cssText="position:absolute;left:-1000px;width:100px;padding:0px;margin:0px;min-height:100px;overflow-y:scroll;",document.body.appendChild(t),t.offsetWidth-t.clientWidth),e={200:"flat",210:"compact",220:"contrast",230:"material",240:"mini",250:"willow",260:"dark"}[10*Math.floor(t.offsetHeight/10)];document.body.removeChild(t),e&&Qi(e);return D.$customScroll?0:i}()});var nn=!1;q("fixHeight",function(){nn||(Mt("html, body{ height:100%; }"),document.body.className+=" webix_full_screen",I.limit(!1),nn=!0)}),a.animate=function(t,i,e){var s,n=v(i);if(n)return e=e||{type:"slide",direction:"left"},n=n.Bt.cloneNode(!0),(t=a(t,i)).Bt.parentNode.appendChild(n),s=k.formLine(t.Bt,n,e),e.callback=function(){k.breakLine(s)},k(s,e),t},a.animateView=function(i,t,e){if(i=v(i)){e=e||{type:"slide",direction:"left"};for(var s=function(t){var t=t.Bt,i=t.className,e=t.innerHTML;return"
"+e+"
"},n=[],h=0;hthis.di.length)&&(i=this.di.length),et.insertAt.call(this.di,t,i),t.N.hidden||this.pf(t,this.di[i])):(s=v(i),i=et.find.call(this.di,s),t.N.hidden||this.pf(t,s),s.destructor(),this.di[i]=t),this.lf||this._a(t);this._f(!0);var s=this.elements?this:this.getFormView();s&&!this.mf&&s.pe(),p("onReconstruct",[this])},_a:function(t){t.Bt.style.display="inline-block",t.Bt.style.verticalAlign="top"},addView:function(t,i){E(i)&&(i=this.di.length);var e=this.$$?this:this.getTopParentView(),e=(S.xt=this,e&&e.ui?e.ui(t,this,i):a(t,this,i));return S.xt=null,e.N.id},removeView:function(t){var i,t="object"!=w(t)?v(t)||(this.$$?this.$$(t):null):t,e=et.find.call(this.di,t);0<=e&&(this.df&&this.df(e,t),i=this.elements?this:this.getFormView(),this.di.splice(e,1),i&&yi(t,function(t){t.name&&delete i.getCleanValues()[t.config.name]},i,!0),t.destructor(),this._f(!0),i&&i.pe()),p("onReconstruct",[this])},reconstruct:function(){this.vf=0,this.zt(this.ff)},Wi:function(t,i,e){t.N.hidden||(t.N.hidden=!0,x(t.Bt),this.vf++,e||S.St||this.resizeChildren(!0))},He:function(t){t.callEvent&&t.callEvent("onViewShow",[])},resizeChildren:function(){if(!S.wt&&this.uf){var t=this.getParentView();if(t)return t.resizeChildren?t.resizeChildren():t.resize();var i,e,s=this.$getSize(0,0),n=i=this.uf[0]||0,h=e=this.uf[1]||0;(1e5<=s[1]||1e5<=s[3] +)&&this.Bt.parentNode&&(n=i=Math.max(s[0],this.N.width||this.Bt.parentNode.offsetWidth||i||0),h=e=Math.max(s[2],this.N.height||this.Bt.parentNode.offsetHeight||e||0)),t?this.ba(i,e):(s[0]>i&&(n=s[0]),s[2]>e&&(h=s[2]),!(t=this.Bt.parentNode==document.body&&!this.setPosition)&&i>s[1]&&(n=s[1]),!t&&e>s[3]&&(h=s[3]),this.$setSize(n,h)),S.bt&&(S.bt=!1,this.resizeChildren()),p("onResize",[])}},getChildViews:function(){return this.di},index:function(t){t.N&&(t=t.N.id);for(var i=0;is&&(s=e[0]),e[1]r&&(r=e[2]),e[3]"},load:function(t){this.src_setter(t)},src_setter:function(t){return this.callEvent("onBeforeLoad",[])?this.getIframe().src=t:""},getIframe:function(){return this.Qi.getElementsByTagName("iframe")[0]},getWindow:function(){return this.getIframe().contentWindow}},h.view,s),{name:"layout",$init:function(){this.vf=0},defaults:{type:"line"},af:function(){this.Wf&&(t=this.Wf(t)),this.Yf||(this.Bt.className+=" webix_layout_"+(this.N.type||""),this.Yf=1),this.N.margin!==undefined&&(this.ga=this.N.margin),this.N.padding!==undefined&&"object"!==w(this.N.padding)&&(this.ma.left=this.ma.right=this.ma.top=this.ma.bottom=this.N.padding),this.N.paddingX!==undefined&&(this.ma.left=this.ma.right=this.N.paddingX),this.N.paddingY!==undefined&&(this.ma.top=this.ma.bottom=this.N.paddingY),"object"===w(this.N.padding)&&R.extend(this.ma,this.N.padding,!0),(this.ma.left||this.ma.right||this.ma.top||this.ma.bottom)&&(this.ma.defined=!0),this.Uf()&&!this.N.borderless&&(this.Qi.style.borderWidth="1px",this.qf=!0);var t=this.ff;this.N.borderless&&(this.N.At={top:!0,left:!0,right:!0,bottom:!0}),this.va(t),hn.api.af.call(this,t),this.pa(t)},$getSize:function(t,i){t=t||0,i=i||0;var e,s=this.ga*(this.di.length-this.vf-1);return(this.qf||this.Uf())&&(e=this.N.At)&&(t+=(e.left?0:1)+(e.right?0:1),i+=(e.top?0:1)+(e.bottom?0:1)),this.N.height||(i+=this.ma.top+this.ma.bottom+(this.lf?s:0)),this.N.width||(t+=this.ma.left+this.ma.right+(this.lf?0:s)),hn.api.$getSize.call(this,t,i)},$setSize:function(t,i){this.uf=[t,i],(this.Uf()||this.qf?h:Zi).api.$setSize.call(this,t,i),i=this.Fe,t=this.De,this.N.scroll&&(i=Math.max(i,this.Sf[1]),t=Math.max(t,this.Sf[0])),this.ba(t,i)},ba:function(t,i){var e=this.ga*(this.di.length-this.vf-1);return i-=this.ma.top+this.ma.bottom,t-=this.ma.left+this.ma.right,this.lf?i-=e:t-=e,hn.api.ba.call(this,t,i)},resizeChildren:function(t){if(t){this.$e=null;for(var i=[],e=0;e
",this.Qi=this.Bt,this.yn=this.Qi.childNodes[0],t.header||(this.yn.style.display="none"),this.sd=this.Qi.childNodes[0].childNodes[1],this.nd=this.Qi.childNodes[0].childNodes[0],this.Rn=this.Qi.childNodes[1],this.Bt.className+=" webix_accordionitem",this.En=this.Tt=null,this.di=!0,this.Rn.setAttribute("role","tabpanel"),this.yn.setAttribute("role","tab"),this.attachEvent("onKeyPress",this.ze)},Vt:function(){this.body_setter()},zt:function(t){this.Tt.destructor(),this.Tt=t,this.Rn.appendChild(this.Tt.Bt),this.resize()},_id:"webix_ai_id",getChildViews:function(){return[this.Tt]},body_setter:function(t){return(t="object"!=w(t)?{template:t}:t).At={top:!0,left:!0,right:!0,bottom:!0},(S.xt=this).Tt=a.jt(t),this.Rn.appendChild(this.Tt.Bt),t},header_setter:function(t){return t=t&&_(t)},headerAlt_setter:function(t){return t=t&&_(t)},$getSize:function(t,i){var e=this.Tt.$getSize(0,0),s=this.N.At,s=(s&&(t+=(s.left?0:1)+(s.right?0:1),i+=(s.top?0:1)+(s.bottom?0:1)),0),n=Zi.api.$getSize.call(this,0,0),h=(n[0]=(n[0]||e[0])+t,1e5<=n[1]&&(n[1]=e[1]),n[1]+=t,n[2]=(n[2]||e[2])+i,n[3]<1e5);return h||(n[3]=e[3]),n[3]+=i,this.getParentView().lf?this.N.collapsed?n[2]=n[3]=this.hd()+i:this.N.header&&(s=this.N.headerHeight):(this.N.collapsed&&(n[0]=n[1]=this.hd()+t),this.N.header&&(s=this.N.headerHeight)),h||(n[2]+=s,n[3]+=s),n},on_click:{webix_accordionitem_header:function(t){return this.rd(t),!1},webix_accordionitem_header_v:function(t){return this.rd(t),!1}},rd:function(){this.define("collapsed",!this.N.collapsed)},collapsed_setter:function(t){if(!1!==this.N.header){var i=this.getParentView();if(i){if(t)if(i.ed(this))this.od();else{var e=0;if(1":"")+t.value+(t.badge||0===t.badge?"
"+t.badge+"
":"")},width:"auto",templateStart:_('
'),templateEnd:_("
")},$skin:function(){this.type.height=A.listItemHeight},disableItem:function(t){this.u1(t,!0)},enableItem:function(t){this.u1(t,!1)},u1:function(t,i){var e=this.getItem(t);e&&(e.disabled=i,this.refresh(t))},isItemEnabled:function(t){t=this.getItem(t);return t&&!t.disabled},Za:function(t,i,e){return this.isItemEnabled(t)?t:(t=this.getNextId(t,e)||null)&&t!=i?this.Za(t,i,e):i}},Sn={api:t,view:R.protoUI(t,ae,He,le,ge,Ve,Ne,Le,on.view,oe)};li(Sn.view,{name:"uploader",template:"{common.removeIcon()}{common.percent()}
#sizetext#
{common.fileName()}",percent:function(t){return"transfer"==t.status?"
"+t.percent+"%
":"
"},removeIcon:function(){return"
"},fileName:function(t){return"
"+t.name+"
"},on_click:{webix_remove_upload:function(t,i){v(this.config.uploader).files.remove(i)}}});R.protoUI({name:"uploader",defaults:{autosend:!0,multiple:!0,inputName:"upload"},$cssName:"button webix_uploader",$allowsClear:!0,on_click:{webix_hidden_upload:function(){return!1}},send:function(){},fileDialog:function(){},stopUpload:function(){},$skin:function(){mn.api.$skin.call(this),"material"!=Ni&&"mini"!=Ni||(this.defaults.css="webix_primary")},$init:function(){this.files=new gn,this.Et=[this.files],R.extend(this,ms,!0)},$setSize:function(t,i){h.api.$setSize.call(this,t,i)&&this.render()},apiOnly_setter:function(t){return b(this.render,this),this.$apiOnly=t},rl:function(t){for(var i=0;i
').concat(i.wv(t.value),""),i.$renderInput(t,h,s)):h+i.$renderInput(t)},highlight:function(t){return _.escape(t)},type:"text"},$init:function(t){var i=this,e=t.type||this.defaults.type;this.Bt.className+=" webix_el_"+e,"textarea"==e?(delete t.clear,t.height=t.height||0,t.minHeight=t.minHeight||60,this.Li=!0):(this.scrollEv=l(document,"selectionchange",function(){i.$view.contains(document.getSelection().focusNode)&&i.l1()}),this.attachEvent("onDestruct",function(){ci(i.scrollEv)})),this.attachEvent("onChange",function(){return i.l1()}),this.attachEvent("onAfterRender",function(){i.f1();["scroll","focus","blur","paste","cut","keyup","input"].forEach(function(t){return o(i.getInputNode(),t,function(){return i.l1()})}),i.d1(!0)})},$setSize:function(){H.api.$setSize.apply(this,arguments),this.f1()},$renderIcon:function(t){return"text"==t.type?H.api.$renderIcon.apply(this,arguments):""},Ev:function(t){return"textarea"==this.N.type?t?this.f0-this.N.inputPadding:"":H.api.Ev.apply(this,arguments)},getInputNode:function(){return this.et.querySelector("text"==this.N.type?"input":"textarea")},_1:function(){return this.et.querySelector(".webix_text_highlight")},d1:function(t){var i=this._1().firstElementChild,e=this.getValue();!t&&e==(this.v1||"")||(this.v1=e,i.innerHTML=this.N.highlight.apply(this,[e])+" ")},p1:function(){var t=this._1(),i=("text"==this.N.type&&(t=t.firstElementChild),this.getInputNode());t.scrollTop=i.scrollTop,t.scrollLeft=i.scrollLeft},f1:function(){var t,i;this.gv&&this.isVisible()&&(t=this.getInputNode(),(i=this._1().style).left=t.offsetLeft+"px",i.top=t.offsetTop+"px",i.height=t.getBoundingClientRect().height+"px")},l1:function(){b(function(){this.$destructed||(this.d1(),this.p1())},this)}},yn,H.view);var Mn,kn,Cn,$n,t={name:"timeboard",defaults:{width:260,hours:!0,seconds:!1,twelve:/%([a,A])/.test(j.timeFormat)},$skin:function(){an.api.$skin.call(this),this.defaults.margin=A.layoutMargin.form,this.defaults.padding=A.layoutPadding.space},$init:function(t){var i,s=this,e=(this.$view.className+=" webix_timeboard",[]),n=(E(t.twelve)?this.defaults:t).twelve,h=(E(t.hours)?this.defaults:t).hours,r=t.seconds||this.defaults.seconds;E(t.height)&&(i=+h+1+1+ +r+ +!!t.button,t.height=A.inputHeight*i+(t.margin||this.defaults.margin)*(i-1)+2*(t.padding||this.defaults.padding)),e.push(this.m1(h,r,n)),e.push.apply(e,V(this.b1(h,r,n))),t.button&&e.push(this.g1()),t.rows=[{view:"form",elements:e,padding:0,borderless:!0,on:{onChange:function(t,i,e){return s.w1(e)}}}],this.$ready.push(function(){this.x1=this.queryView("form");var t=this.N.value;t&&this.setValue(t,"auto")})},setValue:function(t,i){t=this.$prepareValue(t);var e=this.N.value;P.equal(t,e)||(this.N.value=t,this.$setValue(t),this.callEvent("onChange",[t,e,i]))},$prepareValue:function(t){return(t="string"==typeof t?j.parseTimeFormatDate(t):t)||P.datePart(new Date)},$setValue:function(t){var i={};i.minutes=i.sminutes=t.getMinutes(),this.N.hours&&(i.shours=i.hours=t.getHours()),this.N.seconds&&(i.sseconds=i.seconds=t.getSeconds()),this.N.twelve&&!E(i.hours)&&(i.day_part=(11#label#
",inputWidth:30,on:{onItemClick:function(){this.setValue(this.getValue()==s?n:s,"user")},onKeyPress:function(t,i){this.ze(t,i)}}})),{type:"clean",cols:h}},y1:function(i,e){var s=this,n="hours"===i?e?11:23:59;return{view:"text",width:Ht("00").width+2*A.dataPadding+2*A.inputPadding,name:i,format:{parse:function(t){return 1<(t=12==t&&"hours"===i&&e?"00":t).length?t.replace(/^0/,""):t||0},edit:function(t){return t<=0&&"hours"===i&&e?t=12:t<0?t=0:n You need Webix PRO"}},rn.view),R.protoUI({name:"checksuggest",defaults:{template:"GPL version doesn't support checksuggest
You need Webix PRO"}},rn.view),R.protoUI({name:"datasuggest",defaults:{template:"GPL version doesn't support datasuggest
You need Webix PRO"}},rn.view),R.protoUI({name:"gridsuggest",defaults:{template:"GPL version doesn't support gridsuggest
You need Webix PRO"}},rn.view),{name:"mentionsuggest",defaults:{symbol:"@",filter:function(t,i){var e=this.N.symbol;return-1!==(i=i.substring(0,this.Y1)).indexOf(e)&&(!!(i=i.substring(i.lastIndexOf(e)+e.length)).length&&-1!==(t.id?this.getItemText(t.id):t.text||t.value).toString().toLowerCase().indexOf(i.toLowerCase()))}},$init:function(){this.attachEvent("onValueSuggest",this.N1)},$enterKey:function(t){var i;return this.isVisible()&&(d(t),(i=this.N.master?v(this.N.master):i)&&i.callEvent&&i.callEvent("onEnter")),Dn.api.$enterKey.apply(this,arguments)},N1:function(){this.jo&&(this.Y1=Rt(this.jo).start)},F1:function(t){return{pos:this.Y1,symbol:this.N.symbol,config:t}},A1:function(){},T1:function(t){var i=this.N.symbol,e=this.jo.value,s=e.substring(this.Y1);e=(e=e.substring(0,this.Y1)).substring(0,e.lastIndexOf(i)+i.length)+t,this.jo.value=e+s,Bt(this.jo,e.length)},M1:!1}),yn=(R.protoUI(t,Dn.view),R.protoUI({name:"daterange",defaults:{template:"GPL version doesn't support daterange
You need Webix PRO"}},rn.view),{name:"daterangesuggest",defaults:{type:"daterange",body:{view:"daterange",icons:!0,button:!0,borderless:!0}},getValue:function(){return this.getRange().getValue()},setValue:function(t,i){this.getRange().setValue(m(t),i)},getRange:function(){return this.getBody()},getButton:function(){return this.getBody().getChildViews()[1].getChildViews()[1]},U1:function(t){var i=v(this.N.master);i&&i.setValue(t,"user")},C1:function(){var t=this.getRange();t.attachEvent("onAfterDateSelect",f(function(t){this.U1(t)}, -this)),t.attachEvent("onDateClear",f(function(t){this.U1(t)},this)),t.attachEvent("onTodaySet",f(function(t){this.U1(t)},this))}}),t=(R.protoUI(yn,Dn.view),R.protoUI({name:"daterangepicker",defaults:{template:"GPL version doesn't support daterangepicker
You need Webix PRO"}},rn.view),R.protoUI({name:"excelbar",defaults:{template:"GPL version doesn't support excelbar
You need Webix PRO"}},rn.view),R.protoUI({name:"excelviewer",defaults:{template:"GPL version doesn't support excelviewer
You need Webix PRO"}},rn.view),R.protoUI({name:"pdfbar",defaults:{template:"GPL version doesn't support pdfbar
You need Webix PRO"}},rn.view),R.protoUI({name:"pdfviewer",defaults:{template:"GPL version doesn't support pdfviewer
You need Webix PRO"}},rn.view),{name:"video",$init:function(t){t.id||(t.id=++y),this.$ready.push(this.q1)},q1:function(){var t=this.N;if(this.Qi=g("video",{"class":"webix_view_video",style:"width:100%;height:100%;",autobuffer:"autobuffer"},""),t.poster&&(this.Qi.poster=t.poster),t.src){"object"!=w(t.src)&&(t.src=[t.src]);for(var i=0;i'}t.controls&&(this.Qi.controls=!0),t.autoplay&&(this.Qi.autoplay=!0),this.Bt.appendChild(this.Qi)},getVideo:function(){return this.Qi},defaults:{src:"",controls:!0}}),yn=(R.protoUI(t,h.view),R.protoUI({name:"gage",defaults:{template:"GPL version doesn't support gage
You need Webix PRO"}},rn.view),R.protoUI({name:"barcode",defaults:{template:"GPL version doesn't support barcode
You need Webix PRO"}},rn.view),R.protoUI({name:"bulletgraph",defaults:{template:"GPL version doesn't support bulletgraph
You need Webix PRO"}},rn.view),{name:"geochart",defaults:{chart:{displayMode:"auto",region:"world",resolution:"countries"}},$init:function(t){this.$view.innerHTML="
",this.Qi=this.$view.firstChild,this.G1=B.defer(),t.chart=R.extend(t.chart||{},this.defaults.chart),this.data.provideApi(this,!0),this.$ready.push(this.render),this.X1(),this.data.attachEvent("onClearAll",f(this.K1,this)),this.data.attachEvent("onStoreUpdated",f(this.X1,this))},$skin:function(){this.defaults.chart.backgroundColor=A.backColor},getMap:function(t){return t?this.G1:this.Ba},Z1:function(t){return f(function(){"function"==typeof t&&t(),Mn=Mn||window.google,this.J1()},this)},render:function(){"undefined"==typeof window.google||"undefined"==typeof window.google.charts?(kn||((kn=document.createElement("script")).type="text/javascript",kn.src="//www.gstatic.com/charts/loader.js",document.getElementsByTagName("head")[0].appendChild(kn)),kn.onload=this.Z1(kn.onload)):this.Z1()()},J1:function(){Mn.visualization&&Mn.visualization.GeoChart?(this.Ba=new Mn.visualization.GeoChart(this.Qi),this.Q1(),this.G1.resolve(this.Ba)):(Mn.charts.load("current",{packages:["geochart"],mapsApiKey:this.N.key}),Mn.charts.setOnLoadCallback(f(function(){this.J1()},this)))},$onLoad:function(t){return!this.Ba&&(this.G1.then(f(function(){this.parse(t,this.N.datatype)},this)),!0)},X1:function(){if(this.Ba){var n=this.Pl&&this.Pl.length?this.Pl:this.tm(),h=[];if(this.data.each(function(t){for(var i=[],e=0;e",this.Qi=this.$view.firstChild,this.G1=B.defer(),this.data.provideApi(this,!0),this.$ready.push(this.render)},getMap:function(t){return t?this.G1:this.Ba},Z1:function(t){return f(function(){"function"==typeof t&&t(),Cn=Cn||window.google,this.J1.call(this)},this)},render:function(){var t,i;"undefined"==typeof window.google||"undefined"==typeof window.google.maps?($n||(($n=document.createElement("script")).type="text/javascript",i=(t=this.N).src||"//maps.google.com/maps/api/js",i+=-1===i.indexOf("?")?"?":"&",t.key&&(i+="&key="+t.key),t.libraries&&(i+="&libraries="+t.libraries),$n.src=i,document.getElementsByTagName("head")[0].appendChild($n)),$n.onload=this.Z1($n.onload)):this.Z1()()},J1:function(){var t=this.config;this.isVisible(t.id)&&(this.Ba=new Cn.maps.Map(this.Qi,{zoom:t.zoom,center:new Cn.maps.LatLng(t.center[0],t.center[1]),mapTypeId:Cn.maps.MapTypeId[t.mapType]}),this.G1.resolve(this.Ba),this.Qi.firstChild.setAttribute("webix_disable_drag","true"))},center_setter:function(t){return this.Ba&&this.Ba.setCenter(new Cn.maps.LatLng(t[0],t[1])),t},mapType_setter:function(t){return this.Ba&&this.Ba.setMapTypeId(Cn.maps.MapTypeId[t]),t},zoom_setter:function(t){return this.Ba&&this.Ba.setZoom(t),t},layerType_setter:function(t){return"heatmap"==t&&(this.config.libraries="visualization"),this.em[t]&&(R.extend(this,this.em[t],!0),this.data.attachEvent("onStoreUpdated",f(function(){this.G1.then(f(function(){this.drawData.call(this,arguments)},this))},this))),t},defaults:{zoom:5,center:[39.5,-98.5],mapType:"ROADMAP",layerType:"marker"},$setSize:function(){h.api.$setSize.apply(this,arguments),this.Ba&&Cn.maps.event.trigger(this.Ba,"resize")},$onLoad:function(t){return!this.Ba&&(this.G1.then(f(function(){this.parse(t)},this)),!0)},em:{marker:{drawData:function(t,i,e){switch(e){case"add":case"update":i.$marker=this.sm(i);break;case"delete":i.$marker.setMap(null);break;default:this.data.each(function(t){t.$marker=this.sm(t)},this)}},clearAll:function(t){this.data.each(function(t){t.$marker.setMap(null)}),this.data.clearAll(t)},showItem:function(t){t=this.getItem(t);this.Ba.setCenter(new Cn.maps.LatLng(t.lat,t.lng))},sm:function(t){var i,e={};for(i in t)e[i]=t[i];e.position=new Cn.maps.LatLng(t.lat,t.lng),e.map=t.hidden?null:this.Ba;var s=t.$marker;return s?t.$marker.setMap(e.map):(s=new Cn.maps.Marker(e),this.Ct(s)),this.callEvent("onItemRender",[t]),s},Ct:function(t){var i=this;t.addListener("click",function(){i.callEvent("onItemClick",[this.id,this])}),t.getDraggable()&&(t.addListener("dragend",function(){i.nm(this,!0)}),t.addListener("drag",function(){i.nm(this)}))},nm:function(t,i){var e=this.getItem(t.id),t=t.getPosition(),i=i?"onAfterDrop":"onDrag";e.lat=t.lat(),e.lng=t.lng(),this.callEvent(i,[e.id,e])}},heatmap:{heatmapConfig_setter:function(t){return t=t||{}},drawData:function(){this.hm&&(this.hm.setMap(null),this.hm=null);var t,i=[];this.data.each(function(t){i.push(this.rm(t))},this),i.length&&(t=R.extend(this.config.heatmapConfig,{data:i,map:this.Ba}, -!0),this.hm=new Cn.maps.visualization.HeatmapLayer(t),this.callEvent("onHeatMapRender",[this.hm]))},getHeatmap:function(){return this.hm},rm:function(t){var i,e={};for(i in t)e[i]=t[i];return e.location=new Cn.maps.LatLng(t.lat,t.lng),e}}}},me,s,h.view);function In(t,i){return"axis_x"===t&&-1!==i.className.indexOf("webix_axis_title_x")}function Fn(t,i){if(t.canvases){for(var e=0;e You need Webix PRO"}},rn.view),R.protoUI({name:"checksuggest",defaults:{template:"GPL version doesn't support checksuggest
You need Webix PRO"}},rn.view),R.protoUI({name:"datasuggest",defaults:{template:"GPL version doesn't support datasuggest
You need Webix PRO"}},rn.view),R.protoUI({name:"gridsuggest",defaults:{template:"GPL version doesn't support gridsuggest
You need Webix PRO"}},rn.view),{name:"mentionsuggest",defaults:{symbol:"@",filter:function(t,i){var e=this.N.symbol;return-1!==(i=i.substring(0,this.Y1)).indexOf(e)&&(!!(i=i.substring(i.lastIndexOf(e)+e.length)).length&&-1!==(t.id?this.getItemText(t.id):t.text||t.value).toString().toLowerCase().indexOf(i.toLowerCase()))}},$init:function(){this.attachEvent("onValueSuggest",this.N1)},$enterKey:function(t){var i;return this.isVisible()&&(d(t),(i=this.N.master?v(this.N.master):i)&&i.callEvent&&i.callEvent("onEnter")),Dn.api.$enterKey.apply(this,arguments)},N1:function(){this.jo&&(this.Y1=Rt(this.jo).start)},F1:function(t){return{pos:this.Y1,symbol:this.N.symbol,config:t}},A1:function(){},T1:function(t){var i=this.N.symbol,e=this.jo.value,s=e.substring(this.Y1);e=(e=e.substring(0,this.Y1)).substring(0,e.lastIndexOf(i)+i.length)+t,this.jo.value=e+s,Bt(this.jo,e.length)},M1:!1}),yn=(R.protoUI(t,Dn.view),R.protoUI({name:"daterange",defaults:{template:"GPL version doesn't support daterange
You need Webix PRO"}},rn.view),{name:"daterangesuggest",defaults:{type:"daterange",body:{view:"daterange",icons:!0,button:!0,borderless:!0}},getValue:function(){return this.getRange().getValue()},setValue:function(t,i){this.getRange().setValue(m(t),i)},getRange:function(){return this.getBody()},getButton:function(){return this.getBody().getChildViews()[1].getChildViews()[1]},U1:function(t){var i=v(this.N.master);i&&i.setValue(t,"user")},C1:function(){var t=this.getRange();t.attachEvent("onAfterDateSelect",f(function(t){this.U1(t)},this)), +t.attachEvent("onDateClear",f(function(t){this.U1(t)},this)),t.attachEvent("onTodaySet",f(function(t){this.U1(t)},this))}}),t=(R.protoUI(yn,Dn.view),R.protoUI({name:"daterangepicker",defaults:{template:"GPL version doesn't support daterangepicker
You need Webix PRO"}},rn.view),R.protoUI({name:"excelbar",defaults:{template:"GPL version doesn't support excelbar
You need Webix PRO"}},rn.view),R.protoUI({name:"excelviewer",defaults:{template:"GPL version doesn't support excelviewer
You need Webix PRO"}},rn.view),R.protoUI({name:"pdfbar",defaults:{template:"GPL version doesn't support pdfbar
You need Webix PRO"}},rn.view),R.protoUI({name:"pdfviewer",defaults:{template:"GPL version doesn't support pdfviewer
You need Webix PRO"}},rn.view),{name:"video",$init:function(t){t.id||(t.id=++y),this.$ready.push(this.q1)},q1:function(){var t=this.N;if(this.Qi=g("video",{"class":"webix_view_video",style:"width:100%;height:100%;",autobuffer:"autobuffer"},""),t.poster&&(this.Qi.poster=t.poster),t.src){"object"!=w(t.src)&&(t.src=[t.src]);for(var i=0;i'}t.controls&&(this.Qi.controls=!0),t.autoplay&&(this.Qi.autoplay=!0),this.Bt.appendChild(this.Qi)},getVideo:function(){return this.Qi},defaults:{src:"",controls:!0}}),yn=(R.protoUI(t,h.view),R.protoUI({name:"gage",defaults:{template:"GPL version doesn't support gage
You need Webix PRO"}},rn.view),R.protoUI({name:"barcode",defaults:{template:"GPL version doesn't support barcode
You need Webix PRO"}},rn.view),R.protoUI({name:"bulletgraph",defaults:{template:"GPL version doesn't support bulletgraph
You need Webix PRO"}},rn.view),{name:"geochart",defaults:{chart:{displayMode:"auto",region:"world",resolution:"countries"}},$init:function(t){this.$view.innerHTML="
",this.Qi=this.$view.firstChild,this.G1=B.defer(),t.chart=R.extend(t.chart||{},this.defaults.chart),this.data.provideApi(this,!0),this.$ready.push(this.render),this.X1(),this.data.attachEvent("onClearAll",f(this.K1,this)),this.data.attachEvent("onStoreUpdated",f(this.X1,this))},$skin:function(){this.defaults.chart.backgroundColor=A.backColor},getMap:function(t){return t?this.G1:this.Ba},Z1:function(t){return f(function(){"function"==typeof t&&t(),Mn=Mn||window.google,this.J1()},this)},render:function(){"undefined"==typeof window.google||"undefined"==typeof window.google.charts?(kn||((kn=document.createElement("script")).type="text/javascript",kn.src="//www.gstatic.com/charts/loader.js",document.getElementsByTagName("head")[0].appendChild(kn)),kn.onload=this.Z1(kn.onload)):this.Z1()()},J1:function(){Mn.visualization&&Mn.visualization.GeoChart?(this.Ba=new Mn.visualization.GeoChart(this.Qi),this.Q1(),this.G1.resolve(this.Ba)):(Mn.charts.load("current",{packages:["geochart"],mapsApiKey:this.N.key}),Mn.charts.setOnLoadCallback(f(function(){this.J1()},this)))},$onLoad:function(t){return!this.Ba&&(this.G1.then(f(function(){this.parse(t,this.N.datatype)},this)),!0)},X1:function(){if(this.Ba){var n=this.Pl&&this.Pl.length?this.Pl:this.tm(),h=[];if(this.data.each(function(t){for(var i=[],e=0;e",this.Qi=this.$view.firstChild,this.G1=B.defer(),this.data.provideApi(this,!0),this.$ready.push(this.render)},getMap:function(t){return t?this.G1:this.Ba},Z1:function(t){return f(function(){"function"==typeof t&&t(),Cn=Cn||window.google,this.J1.call(this)},this)},render:function(){var t,i;"undefined"==typeof window.google||"undefined"==typeof window.google.maps?($n||(($n=document.createElement("script")).type="text/javascript",i=(t=this.N).src||"//maps.google.com/maps/api/js",i+=-1===i.indexOf("?")?"?":"&",t.key&&(i+="&key="+t.key),t.libraries&&(i+="&libraries="+t.libraries),$n.src=i,document.getElementsByTagName("head")[0].appendChild($n)),$n.onload=this.Z1($n.onload)):this.Z1()()},J1:function(){var t=this.config;this.isVisible(t.id)&&(this.Ba=new Cn.maps.Map(this.Qi,{zoom:t.zoom,center:new Cn.maps.LatLng(t.center[0],t.center[1]),mapTypeId:Cn.maps.MapTypeId[t.mapType]}),this.G1.resolve(this.Ba),this.Qi.firstChild.setAttribute("webix_disable_drag","true"))},center_setter:function(t){return this.Ba&&this.Ba.setCenter(new Cn.maps.LatLng(t[0],t[1])),t},mapType_setter:function(t){return this.Ba&&this.Ba.setMapTypeId(Cn.maps.MapTypeId[t]),t},zoom_setter:function(t){return this.Ba&&this.Ba.setZoom(t),t},layerType_setter:function(t){return"heatmap"==t&&(this.config.libraries="visualization"),this.em[t]&&(R.extend(this,this.em[t],!0),this.data.attachEvent("onStoreUpdated",f(function(){this.G1.then(f(function(){this.drawData.call(this,arguments)},this))},this))),t},defaults:{zoom:5,center:[39.5,-98.5],mapType:"ROADMAP",layerType:"marker"},$setSize:function(){h.api.$setSize.apply(this,arguments),this.Ba&&Cn.maps.event.trigger(this.Ba,"resize")},$onLoad:function(t){return!this.Ba&&(this.G1.then(f(function(){this.parse(t)},this)),!0)},em:{marker:{drawData:function(t,i,e){switch(e){case"add":case"update":i.$marker=this.sm(i);break;case"delete":i.$marker.setMap(null);break;default:this.data.each(function(t){t.$marker=this.sm(t)},this)}},clearAll:function(t){this.data.each(function(t){t.$marker.setMap(null)}),this.data.clearAll(t)},showItem:function(t){t=this.getItem(t);this.Ba.setCenter(new Cn.maps.LatLng(t.lat,t.lng))},sm:function(t){var i,e={};for(i in t)e[i]=t[i];e.position=new Cn.maps.LatLng(t.lat,t.lng),e.map=t.hidden?null:this.Ba;var s=t.$marker;return s?t.$marker.setMap(e.map):(s=new Cn.maps.Marker(e),this.Ct(s)),this.callEvent("onItemRender",[t]),s},Ct:function(t){var i=this;t.addListener("click",function(){i.callEvent("onItemClick",[this.id,this])}),t.getDraggable()&&(t.addListener("dragend",function(){i.nm(this,!0)}),t.addListener("drag",function(){i.nm(this)}))},nm:function(t,i){var e=this.getItem(t.id),t=t.getPosition(),i=i?"onAfterDrop":"onDrag";e.lat=t.lat(),e.lng=t.lng(),this.callEvent(i,[e.id,e])}},heatmap:{heatmapConfig_setter:function(t){return t=t||{}},drawData:function(){this.hm&&(this.hm.setMap(null),this.hm=null);var t,i=[];this.data.each(function(t){i.push(this.rm(t))},this),i.length&&(t=R.extend(this.config.heatmapConfig,{data:i,map:this.Ba},!0), +this.hm=new Cn.maps.visualization.HeatmapLayer(t),this.callEvent("onHeatMapRender",[this.hm]))},getHeatmap:function(){return this.hm},rm:function(t){var i,e={};for(i in t)e[i]=t[i];return e.location=new Cn.maps.LatLng(t.lat,t.lng),e}}}},me,s,h.view);function In(t,i){return"axis_x"===t&&-1!==i.className.indexOf("webix_axis_title_x")}function Fn(t,i){if(t.canvases){for(var e=0;eMath.abs(t))a=t<0?-h:0;else{var s=Math.abs(t),e=Math.floor(this.Pm(s)),o=s/Math.pow(10,e),a=0!=e||.1<=h?Math.ceil(10*o)/10*Math.pow(10,e)-h:s;for(1=a[0]&&h<=a[3]&&h>=a[1]&&(!e||s[o ].index>e.index)&&(e=s[o])}return e},hideSeries:function(t){this.canvases[t].hideCanvas();var i=this.N.legend;i&&i.values&&i.values[t]&&(i.values[t].$hidden=!0,this._m()),this.Ba.hide(this.Qi,t,!0)},showSeries:function(t){this.canvases[t].showCanvas();var i=this.N.legend;i&&i.values&&i.values[t]&&(delete i.values[t].$hidden,this._m()),this.Ba.hide(this.Qi,t,!1)},_m:function(t,i){var e,s,n,h,r,o,a,u,c=0,l=0;if(t=t||[],i=i||this.De,a=this.canvases.legend.getCanvas(),s=this.N.legend,v="x"!=this.N.legend.layout?"width:"+s.width+"px":"",this.lm&&(this.lm.innerHTML="",this.lm.parentNode.removeChild(this.lm)),this.canvases.legend.clearCanvas(!0),n=g("DIV",{"class":"webix_chart_legend",style:"left:"+c+"px; top:"+l+"px;"+v},""),s.padding&&(n.style.padding=s.padding+"px"),this.lm=n,this.Qi.appendChild(n),r=[],s.values)for(e=0;ethis._2||n<0||n+e.width>this.$width-this.Iy),!i||h?t.getPopup().show({x:-1e4,y:-1e4}):t.getPopup().show(i)),this.N.prerender||t.linkInput||t.$inline||(t.node.top-=r,t.node.style.top=t.node.top+"px")}))}},{math_setter:function(t){return t&&this.eM(),t},sM:"$",eM:function(){D.strict||(this.data.attachEvent("onStoreUpdated",f(this.nM,this)),this.data.attachEvent("onStoreLoad",f(this.hM,this)),this.attachEvent("onStructureLoad",this.hM))},nM:function(t,i,e){if(t&&"paint"!=e)if("delete"==e)for(var s=0;s":ps.checkbox.apply(this,arguments)},this.data.provideApi(this,!0),this.Bt.setAttribute("role","treegrid")},bo:!1,BM:function(e){return function(t,i){return i=i.row,e.call(this,t,i)}},po:function(t){for(var i=this.N.prerender?t.source:[t.start],e=0;e You need Webix PRO"}},rn.view),R.proto({name:"DataRecord",isVisible:function(){return!0},$init:function(t){this.data=t||{};t=t&&t.id?t.id:++y;this.N={id:t},a.views[t]=this},getValues:function(){return this.data},setValues:function(t,i,e){this.data=i?R.extend(this.data,t,!0):t,this.callEvent("onChange",[t,e])},refresh:function(){this.callEvent("onBindRequest")}},s,lt,Kt,Yi)),Pn=R.proto({name:"DataValue",isVisible:function(){return!0},$init:function(t){t&&!E(t.value)||(this.data=t||"");t=t&&t.id?t.id:++y;this.N={id:t},a.views[t]=this},setValue:function(t,i){this.data=t,this.callEvent("onChange",[t,i])},getValue:function(){return this.data},refresh:function(){this.callEvent("onBindRequest")}},s,lt),t=R.proto({name:"TreeCollection",$init:function(){R.extend(this.data,_s,!0),this.data.provideApi(this,!0),R.extend(this,ls,!0)}},cs,gn);R.Date=P,R.Number=js,R.promise=B,R.DataCollection=gn,R.DataRecord=zn,R.DataValue=Pn,R.TreeCollection=t,R.AtomDataLoader=Kt,R.AtomRender=ri,R.AutoScroll=oi,R.AutoTooltip=Yt,R.BaseBind=lt,R.BindSource=Ki,R.Canvas=Ji,R.CodeParser=Zt,R.CollectionBind=qi, -R.ContextHelper=se,R.CopyPaste=oe,R.CustomPrint=ae,R.CustomScroll=ue,R.DataMarks=ce,R.DataMove=le,R.DataLoader=me,R.DataState=be,R.DataStore=pe,R.Destruction=Ui,R.DragControl=F,R.DragItem=ge,R.DragOrder=we,R.EditAbility=Ce,R.EventSystem=s,R.FlexLayout=$e,R.Group=Fe,R.GroupMethods=De,R.GroupStore=Ie,R.HTMLOptions=Te,R.HtmlMap=Ae,R.IdSpace=Pe,R.KeysNavigation=He,R.MapCollection=ze,R.Modality=_t,R.MouseEvents=Ve,R.Movable=ct,R.NavigationButtons=Be,R.OverlayBox=Re,R.PagingAbility=Ee,R.ProgressBar=je,R.RecordBind=Xi,R.RenderStack=Oe,R.ResizeArea=ee,R.SingleRender=Wt,R.Scrollable=Le,R.SelectionModel=Ne,R.Settings=Yi,R.Sparklines=rs,R.TablePaste=os,R.TooltipControl=pi,R.Touch=I,R.TreeAPI=as,R.TreeClick=us,R.TreeDataLoader=cs,R.TreeDataMove=ls,R.TreeRenderStack=fs,R.TreeStateCheckbox=ds,R.TreeStore=_s,R.TreeTablePaste=vs,R.TreeType=ps,R.UIManager=M,R.Undo=xe,R.UploadDriver=ms,R.ValidateCollection=bs,R.ValidateData=fe,R.ValueBind=Gi,R.Values=gs,R.VirtualRenderStack=ws,R.VRenderStack=xs,R.html=dt,R.skin=te,R.debug=function(t){if(t)if("object"!==w(t))G={events:!0};else for(var i in t)G[i]=t[i];else G={}},R.i18n=j,R.ready=Mi,R.env=D,R.color=T,R.csv=re,R.clipbuffer=he,R.storage=Ns,R.template=_,R.type=li,R.editors=ke,R.animate=k,R.print=function(t,i){t=v(t);if(t=t&&t.$printView?t.$printView():t){t.callEvent&&t.callEvent("onBeforePrint",[i]);var e=i=function(i){(i=i||{}).paper=i.paper||"a4",i.size=D.printSizes.find(function(t){return t.id==i.paper}),i.size||(i.size=D.printSizes[0],i.paper=i.size.id);i.mode=Ys[i.mode]?i.mode:"portrait",i.fit=Ws[i.fit]?i.fit:"page",i.scroll=i.scroll||!1,i.margin=i.margin||0===i.margin?i.margin:{};var t=isNaN(+i.margin)?D.printMargin:i.margin;return i.margin={top:i.margin.top||0===i.margin.top?i.margin.top:t,bottom:i.margin.bottom||0===i.margin.bottom?i.margin.bottom:t,right:i.margin.right||0===i.margin.right?i.margin.right:t,left:i.margin.left||0===i.margin.left?i.margin.left:t},i}(i),s=(u(document.body,"webix_print"),e.docHeader&&Gs("Header",e),e.docFooter&&Gs("Footer",e),e.size);if(Mt("@media print { @page{ size:"+(s.preset?s.preset+" "+e.mode:"portrait"==e.mode?"".concat(s.width,"in ").concat(s.height,"in"):"".concat(s.height,"in ").concat(s.width,"in"))+";margin-top:"+e.margin.top+"px;margin-bottom:"+e.margin.bottom+"px;margin-right:"+e.margin.right+"px;margin-left:"+e.margin.left+"px;}}","print"),t.$customPrint){if(s=t.$customPrint(i)){if(s.then)return s.then(function(){return Us(i)});qs(t,i)}}else qs(t,i);Us(i)}},R.rules=Di,R.filters={number:{greater:function(t,i){return ii.start)&&(!i.end||t=i.end}}},R.patterns=Xs,R.fullscreen=Wi,R.version="10.3.0",R.name="core",R.level_in=function(){0}, +R.ContextHelper=se,R.CopyPaste=oe,R.CustomPrint=ae,R.CustomScroll=ue,R.DataMarks=ce,R.DataMove=le,R.DataLoader=me,R.DataState=be,R.DataStore=pe,R.Destruction=Ui,R.DragControl=F,R.DragItem=ge,R.DragOrder=we,R.EditAbility=Ce,R.EventSystem=s,R.FlexLayout=$e,R.Group=Fe,R.GroupMethods=De,R.GroupStore=Ie,R.HTMLOptions=Te,R.HtmlMap=Ae,R.IdSpace=Pe,R.KeysNavigation=He,R.MapCollection=ze,R.Modality=_t,R.MouseEvents=Ve,R.Movable=ct,R.NavigationButtons=Be,R.OverlayBox=Re,R.PagingAbility=Ee,R.ProgressBar=je,R.RecordBind=Xi,R.RenderStack=Oe,R.ResizeArea=ee,R.SingleRender=Wt,R.Scrollable=Le,R.SelectionModel=Ne,R.Settings=Yi,R.Sparklines=rs,R.TablePaste=os,R.TooltipControl=pi,R.Touch=I,R.TreeAPI=as,R.TreeClick=us,R.TreeDataLoader=cs,R.TreeDataMove=ls,R.TreeRenderStack=fs,R.TreeStateCheckbox=ds,R.TreeStore=_s,R.TreeTablePaste=vs,R.TreeType=ps,R.UIManager=M,R.Undo=xe,R.UploadDriver=ms,R.ValidateCollection=bs,R.ValidateData=fe,R.ValueBind=Gi,R.Values=gs,R.VirtualRenderStack=ws,R.VRenderStack=xs,R.html=dt,R.skin=te,R.debug=function(t){if(t)if("object"!==w(t))G={events:!0};else for(var i in t)G[i]=t[i];else G={}},R.i18n=j,R.ready=Mi,R.env=D,R.color=T,R.csv=re,R.clipbuffer=he,R.storage=Ns,R.template=_,R.type=li,R.editors=ke,R.animate=k,R.print=function(t,i){t=v(t);if(t=t&&t.$printView?t.$printView():t){t.callEvent&&t.callEvent("onBeforePrint",[i]);var e=i=function(i){(i=i||{}).paper=i.paper||"a4",i.size=D.printSizes.find(function(t){return t.id==i.paper}),i.size||(i.size=D.printSizes[0],i.paper=i.size.id);i.mode=Ys[i.mode]?i.mode:"portrait",i.fit=Ws[i.fit]?i.fit:"page",i.scroll=i.scroll||!1,i.margin=i.margin||0===i.margin?i.margin:{};var t=isNaN(+i.margin)?D.printMargin:i.margin;return i.margin={top:i.margin.top||0===i.margin.top?i.margin.top:t,bottom:i.margin.bottom||0===i.margin.bottom?i.margin.bottom:t,right:i.margin.right||0===i.margin.right?i.margin.right:t,left:i.margin.left||0===i.margin.left?i.margin.left:t},i}(i),s=(u(document.body,"webix_print"),e.docHeader&&Gs("Header",e),e.docFooter&&Gs("Footer",e),e.size);if(Mt("@media print { @page{ size:"+(s.preset?s.preset+" "+e.mode:"portrait"==e.mode?"".concat(s.width,"in ").concat(s.height,"in"):"".concat(s.height,"in ").concat(s.width,"in"))+";margin-top:"+e.margin.top+"px;margin-bottom:"+e.margin.bottom+"px;margin-right:"+e.margin.right+"px;margin-left:"+e.margin.left+"px;}}","print"),t.$customPrint){if(s=t.$customPrint(i)){if(s.then)return s.then(function(){return Us(i)});qs(t,i)}}else qs(t,i);Us(i)}},R.rules=Di,R.filters={number:{greater:function(t,i){return ii.start)&&(!i.end||t=i.end}}},R.patterns=Xs,R.fullscreen=Wi,R.version="10.3.1",R.name="core",R.level_in=function(){0}, R.level_out=function(){0},R.clone=X,R.copy=m,R.single=function(t){var i=null;return function(){return(i=i||new t({})).RM&&i.RM.apply(i,arguments),i}},R.bind=f,R.exec=K,R.wrap=function(i,e){return i?function(){var t=i.apply(this,arguments);return e.apply(this,arguments),t}:e},R.isUndefined=E,R.delay=b,R.once=Z,R.uid=J,R.toNode=Q,R.toFunctor=tt,R.isArray=C,R.isDate=it,R.EM=$,R.jM=et,R.OM=ui,R.LM=o,R.event=l,R.eventRemove=ci,R.callEvent=p,R.attachEvent=ht,R.detachEvent=rt,R.blockEvent=function(){return nt.blockEvent()},R.unblockEvent=function(){return nt.unblockEvent()},R.mapEvent=function(t){return nt.mapEvent(t)},R.hasEvent=function(t){return nt.hasEvent(t)},R.stringify=st,R.toPNG=function(i,s){var n=B.defer();return qt(D.cdn+"/extras/html2canvas-1.0.min.js").then(function(){(s=(s="string"==typeof s?{filename:s}:s)||{}).export_mode="png";var e,t=v(i);return(t=t&&t.$exportView?t.$exportView(s):t)?(t=t?t.$view:Q(i),e=Cs(s.filename,"png"),window.html2canvas(t,{background:"#fff",logging:!1,useCORS:!0}).then(function(t){var i=function(t){!1!==s.download&&zt(t,e),n.resolve(t)};t.msToBlob?i(t.msToBlob()):t.toBlob(i,"image/png")}),n):n.reject(ys)})},R.toCSV=function(t,i){i=i||{};t=v(t);if(!(t=t&&t.$exportView?t.$exportView(i):t))return B.reject(ys);i.export_mode="csv",R.extend(i,{filterHTML:!0});var e=ks(t,i),t=$s(t,i,e),e=re.stringify(t),t=Cs(i.filename,"csv"),e=new Blob(["\ufeff"+e],{type:"text/csv"});return!1!==i.download&&zt(e,t),B.resolve(e)},R.toPDF=Is,R.toExcel=zs,R.alert=function(){var t=Ei.apply(this,arguments);return t.type=t.type||"alert",zi(t)},R.confirm=ji,R.modalbox=Oi,R.prompt=function(){var t=Ei.apply(this,arguments);return t.type=t.type||"prompt",t.input=t.input||{},Ri(t)},R.message=Li,R.editStop=function(){p("onEditEnd",[])},R.ajax=ut,R.DataDriver=Gt,R.dp=_e,R.DataProcessor=ve,R.remote=Qs,R.require=qt,R.proxy=pt,R.send=function(t,i,e,s){var n,h=g("FORM",{target:s||"_self",action:t,method:e||"POST"},"");for(n in i){var r=g("INPUT",{type:"hidden",name:n,value:i[n]},"");h.appendChild(r)}h.style.display="none",document.body.appendChild(h),h.submit(),document.body.removeChild(h)},R.ui=a,R.$$=v,Object.defineProperty(R,"NM",{value:!0})}); //# sourceMappingURL=webix.min.js.map diff --git a/codebase/webix.min.js.map b/codebase/webix.min.js.map index 7cb3d93..99c1dd1 100644 --- a/codebase/webix.min.js.map +++ b/codebase/webix.min.js.map @@ -1 +1 @@ -{"version":3,"file":"webix.min.js","sources":["../sources/thirdparty/promiz.js","../sources/load/drivers/xml.js","../sources/load/ajax.js","../sources/webix/env.js","../sources/load/drivers/excel.js","../sources/webix/template.js","../sources/core/autoscroll.js","../sources/ui/core.js","../sources/webix/rules.js","../sources/webix/message.js","../sources/webix/fullscreen.js","../sources/core/uimanager.js","../sources/core/destruction.js","../sources/views/baseview.js","../sources/views/view.js","../sources/core/canvas.js","../sources/css/skins/material/config.js","../sources/css/skins/willow/config.js","../sources/core/touch.js","../sources/core/dragcontrol.js","../sources/views/window.js","../sources/core/customprint.js","../sources/core/validatedata.js","../sources/load/dataprocessor.js","../sources/core/datastore.js","../sources/core/datastate.js","../sources/core/dragitem.js","../sources/core/undo.js","../sources/webix/editors.js","../sources/core/editability.js","../sources/core/htmloptions.js","../sources/core/idspace.js","../sources/core/mapcollection.js","../sources/core/navigationbuttons.js","../sources/core/progressbar.js","../sources/core/selectionmodel.js","../sources/webix/color.js","../sources/core/sparklines/pie.js","../sources/core/sparklines/radar.js","../sources/core/treeclick.js","../sources/core/treerenderstack.js","../sources/core/treestore.js","../sources/core/virtualrenderstack.js","../sources/core/vrenderstack.js","../sources/webix/export/common.js","../sources/webix/export/topdf.js","../sources/webix/export/toexcel.js","../sources/i18n/en.js","../sources/core/date.js","../sources/webix/storage.js","../sources/load/remote.js","../sources/ui/datafilter.js","../sources/i18n/de.js","../sources/i18n/es.js","../sources/i18n/it.js","../sources/i18n/zh.js","../sources/views/baselayout.js","../sources/views/scrollview.js","../sources/views/layout.js","../sources/views/accordionitem.js","../sources/views/resizer.js","../sources/views/multiview.js","../sources/views/tabview.js","../sources/views/proxy.js","../sources/views/form.js","../sources/views/htmlform.js","../sources/views/property.js","../sources/views/calendar.js","../sources/views/colorboard.js","../sources/views/colorselect.js","../sources/views/button.js","../sources/views/label.js","../sources/views/text.js","../sources/core/textpattern.js","../sources/views/radio.js","../sources/views/datepicker.js","../sources/views/richselect.js","../sources/views/segmented.js","../sources/views/toggle.js","../sources/views/slider.js","../sources/views/switch.js","../sources/views/tabbar.js","../sources/views/richtext.js","../sources/views/list.js","../sources/views/timeboard.js","../sources/views/suggest.js","../sources/views/daterangesuggest.js","../sources/views/geochart.js","../sources/views/googlemap.js","../sources/views/chart/pie.js","../sources/views/chart/bar.js","../sources/views/chart/line.js","../sources/webix/helpers.js","../sources/webix/customevents.js","../sources/webix/export/topng.js","../sources/webix/export/tocsv.js","../sources/webix/api.js","../sources/load/send.js"],"sourcesContent":["var global = window;\n\nvar queueId = 1;\nvar queue = {};\nvar isRunningTask = false;\n\nif (!global.setImmediate && global.addEventListener)\n\tglobal.addEventListener(\"message\", function (e) {\n\t\tif (e.source == global){\n\t\t\tif (isRunningTask)\n\t\t\t\tnextTick(queue[e.data]);\n\t\t\telse {\n\t\t\t\tisRunningTask = true;\n\t\t\t\ttry {\n\t\t\t\t\tif (typeof queue[e.data] === \"function\")\n\t\t\t\t\t\tqueue[e.data]();\n\t\t\t\t} catch (e) {\n\t\t\t\t\t// eslint-disable-line\n\t\t\t\t}\n\n\t\t\t\tdelete queue[e.data];\n\t\t\t\tisRunningTask = false;\n\t\t\t}\n\t\t}\n\t});\n\nfunction nextTick(fn) {\n\tif (global.setImmediate) global.setImmediate(fn);\n\t// if inside of web worker\n\telse if (global.importScripts || !global.addEventListener) setTimeout(fn);\n\telse {\n\t\tqueueId++;\n\t\tqueue[queueId] = fn;\n\t\tglobal.postMessage(queueId, \"*\");\n\t}\n}\n\nDeferred.resolve = function (value) {\n\tif (!(this._d == 1))\n\t\tthrow TypeError();\n\n\tif (value instanceof Deferred)\n\t\treturn value;\n\n\treturn new Deferred(function (resolve) {\n\t\tresolve(value);\n\t});\n};\n\nDeferred.reject = function (value) {\n\tif (!(this._d == 1))\n\t\tthrow TypeError();\n\n\treturn new Deferred(function (resolve, reject) {\n\t\treject(value);\n\t});\n};\n\nDeferred.all = function (arr) {\n\tif (!(this._d == 1))\n\t\tthrow TypeError();\n\n\tif (!(arr instanceof Array))\n\t\treturn Deferred.reject(TypeError());\n\n\tvar d = new Deferred();\n\n\tfunction done(e, v) {\n\t\tif (v)\n\t\t\treturn d.resolve(v);\n\n\t\tif (e)\n\t\t\treturn d.reject(e);\n\n\t\tvar unresolved = arr.reduce(function (cnt, v) {\n\t\t\tif (v && v.then)\n\t\t\t\treturn cnt + 1;\n\t\t\treturn cnt;\n\t\t}, 0);\n\n\t\tif(unresolved == 0)\n\t\t\td.resolve(arr);\n\n\n\t\tarr.map(function (v, i) {\n\t\t\tif (v && v.then)\n\t\t\t\tv.then(function (r) {\n\t\t\t\t\tarr[i] = r;\n\t\t\t\t\tdone();\n\t\t\t\t\treturn r;\n\t\t\t\t}, done);\n\t\t});\n\t}\n\n\tdone();\n\n\treturn d;\n};\n\nDeferred.race = function (arr) {\n\tif (!(this._d == 1))\n\t\tthrow TypeError();\n\n\tif (!(arr instanceof Array))\n\t\treturn Deferred.reject(TypeError());\n\n\tif (arr.length == 0)\n\t\treturn new Deferred();\n\n\tvar d = new Deferred();\n\n\tfunction done(e, v) {\n\t\tif (v)\n\t\t\treturn d.resolve(v);\n\n\t\tif (e)\n\t\t\treturn d.reject(e);\n\n\t\tvar unresolved = arr.reduce(function (cnt, v) {\n\t\t\tif (v && v.then)\n\t\t\t\treturn cnt + 1;\n\t\t\treturn cnt;\n\t\t}, 0);\n\n\t\tif(unresolved == 0)\n\t\t\td.resolve(arr);\n\n\t\tarr.map(function (v) {\n\t\t\tif (v && v.then)\n\t\t\t\tv.then(function (r) {\n\t\t\t\t\tdone(null, r);\n\t\t\t\t}, done);\n\t\t});\n\t}\n\n\tdone();\n\n\treturn d;\n};\n\nDeferred._d = 1;\n\n\n/**\n * @constructor\n */\nfunction Deferred(resolver) {\n\t\"use strict\";\n\tif (typeof resolver != \"function\" && resolver != undefined)\n\t\tthrow TypeError();\n\t\t\n\tif (typeof this != \"object\" || (this && this.then))\n\t\tthrow TypeError();\n\n\t// states\n\t// 0: pending\n\t// 1: resolving\n\t// 2: rejecting\n\t// 3: resolved\n\t// 4: rejected\n\tvar self = this,\n\t\tstate = 0,\n\t\tval = 0,\n\t\tnext = [],\n\t\tfn, er;\n\n\tself[\"promise\"] = self;\n\n\tself[\"resolve\"] = function (v) {\n\t\tfn = self.fn;\n\t\ter = self.er;\n\t\tif (!state) {\n\t\t\tval = v;\n\t\t\tstate = 1;\n\n\t\t\tnextTick(fire);\n\t\t}\n\t\treturn self;\n\t};\n\n\tself[\"reject\"] = function (v) {\n\t\tfn = self.fn;\n\t\ter = self.er;\n\t\tif (!state) {\n\t\t\tval = v;\n\t\t\tstate = 2;\n\n\t\t\tnextTick(fire);\n\n\t\t}\n\t\treturn self;\n\t};\n\n\tself[\"_d\"] = 1;\n\n\tself[\"then\"] = function (_fn, _er) {\n\t\tif (!(this._d == 1))\n\t\t\tthrow TypeError();\n\n\t\tvar d = new Deferred();\n\n\t\td.fn = _fn;\n\t\td.er = _er;\n\t\tif (state == 3) {\n\t\t\td.resolve(val);\n\t\t}\n\t\telse if (state == 4) {\n\t\t\td.reject(val);\n\t\t}\n\t\telse {\n\t\t\tnext.push(d);\n\t\t}\n\n\t\treturn d;\n\t};\n\n\tself[\"finally\"] = function(_handler){\n\t\tvar _value;\n\t\tconst handler = function(value){\n\t\t\t_value = value;\n\t\t\treturn _handler();\n\t\t};\n\t\t\n\t\tconst value = function(){\n\t\t\tconst d = new Deferred();\n\t\t\tif(state == 4)\n\t\t\t\treturn d.reject(_value);\n\t\t\telse\n\t\t\t\treturn d.resolve(_value);\n\t\t};\n\n\t\treturn self.then(handler, handler).then(value, value);\n\t};\n\n\tself[\"catch\"] = function (_er) {\n\t\treturn self[\"then\"](null, _er);\n\t};\n\n\t//compatibility with old version of promiz lib\n\tself[\"fail\"] = function (_er) {\n\t\treturn self[\"then\"](null, _er);\n\t};\n\n\tvar finish = function (type) {\n\t\tstate = type || 4;\n\t\tfor (var i=0; i= 400 || x.status === 0;\n\t\t\t\tvar text, data;\n\t\t\t\tif (x.responseType == \"blob\" || x.responseType == \"arraybuffer\"){\n\t\t\t\t\ttext = \"\";\n\t\t\t\t\tdata = x.response;\n\t\t\t\t} else {\n\t\t\t\t\ttext = x.responseText||\"\";\n\t\t\t\t\tdata = self._data(x);\n\t\t\t\t}\n\t\t\t\tif (is_error){\n\t\t\t\t\tcallEvent(\"onAjaxError\", [x]);\n\t\t\t\t\tdefer.reject(x);\n\t\t\t\t\tif(call)\n\t\t\t\t\t\tajax.$callback((self.master || window), call, text, data, x, is_error);\n\t\t\t\t} else {\n\t\t\t\t\tdefer.resolve(data);\n\t\t\t\t\tif(call)\n\t\t\t\t\t\tajax.$callback((self.master || window), call, text, data, x, is_error);\n\t\t\t\t}\t\n\t\t\t}\n\t\t};\n\n\t\tif (this._timeout)\n\t\t\tx.timeout = this._timeout;\n\n\t\t//IE can use sync mode sometimes, fix it\n\t\tif (!this._sync)\n\t\t\tsetTimeout(function(){\n\t\t\t\tx.send(params||null);\n\t\t\t}, 0);\n\t\telse\n\t\t\tx.send(params||null);\n\t\t\n\t\tif (this.master && !this._sync){\n\t\t\tdefer.then(function(data){\n\t\t\t\t//anti-leak\n\t\t\t\tself.master=null;\n\t\t\t\tcall=self=master=null;\t\n\t\t\t\treturn data;\n\t\t\t});\n\t\t}\n\n\t\treturn this._sync?x:defer; //return XHR, which can be used in case of sync. mode\n\t},\n\t_data:function(x){\n\t\treturn {\n\t\t\txml:function(){ \n\t\t\t\ttry{\n\t\t\t\t\treturn xml.tagToObject(xml.toObject(x.responseText, this));\n\t\t\t\t}\n\t\t\t\tcatch(e){\n\t\t\t\t\tlog(x.responseText);\n\t\t\t\t\tlog(e.toString()); assert(0, \"Invalid xml data for parsing\"); \n\t\t\t\t}\n\t\t\t},\n\t\t\trawxml:function(){ \n\t\t\t\tif (!window.XPathResult)\n\t\t\t\t\treturn xml.fromString(x.responseText);\n\t\t\t\treturn x.responseXML;\n\t\t\t},\n\t\t\ttext:function(){ return x.responseText; },\n\t\t\tjson:function(){\n\t\t\t\treturn json.toObject(x.responseText, false);\n\t\t\t}\n\t\t};\n\t},\n\t//GET request\n\tget:function(url,params,call){\n\t\treturn this._send(url,params,call,\"GET\");\n\t},\n\t//POST request\n\tpost:function(url,params,call){\n\t\treturn this._send(url,params,call,\"POST\");\n\t},\n\t//PUT request\n\tput:function(url,params,call){\n\t\treturn this._send(url,params,call,\"PUT\");\n\t},\n\t//DELETE request\n\tdel:function(url,params,call){\n\t\treturn this._send(url,params,call,\"DELETE\");\n\t},\n\t//PATCH request\n\tpatch:function(url,params,call){\n\t\treturn this._send(url,params,call,\"PATCH\");\n\t},\n\n\tsync:function(){\n\t\tthis._sync = true;\n\t\treturn this;\n\t},\n\ttimeout:function(num){\n\t\tthis._timeout = num;\n\t\treturn this;\n\t},\n\tresponse:function(value){\n\t\tthis._response = value;\n\t\treturn this;\n\t},\n\theaders:function(header){\n\t\tthis._header = extend(this._header||{},header);\n\t\treturn this;\n\t},\n\tbind:function(master){\n\t\tthis.master = master;\n\t\treturn this;\n\t}\n};\najax.$callback = function(owner, call, text, data, x, is_error){\n\tif (owner.$destructed) return;\n\n\tif (is_error)\n\t\tcallEvent(\"onAjaxError\", [x]);\n\t\n\tif (call){\n\t\tvar method = call.success || call;\n\t\tif (is_error)\n\t\t\tmethod = call.error;\n\t\tif (method && method.call)\n\t\t\tmethod.call(owner,text,data,x);\n\t}\n};","const env = {};\n\nenv.cdn = \"//cdn.webix.com\";\nenv.codebase = \"\";\nenv.zIndexBase = 100;\nenv.scrollSize = 17;\nenv.strict = !!window.webix_strict;\nenv.https = document.location.protocol === \"https:\";\n\nconst agent = navigator.userAgentData;\nconst deprecatedAgent = agent && agent.platform && agent.brands.length ? null : navigator.userAgent;\n\nconst browsers = {\n\tChromium: \"Chrom\", //in userAgent - Chrome, in userAgentData.brands - Chromium\n\tIE: \"Trident\",\n\tEdge: \"Edg\", // in userAgent - Edg, in userAgentData.brands - Microsoft Edge\n\tFF: \"Firefox\",\n\tSafari: \"Safari\"\n};\n\nfor(let browser in browsers){\n\tconst checkBrowser = deprecatedAgent ?\n\t\tdeprecatedAgent.indexOf(browsers[browser]) != -1 :\n\t\tagent.brands.find(v => v.brand.indexOf(browsers[browser]) != -1);\n\n\tif(checkBrowser){\n\t\tenv[\"is\"+browser] = true;\n\t\t//Edge is a chromium-based browser (so we set isChromium:true and isEdge:true)\n\t\tif(browser != \"Chromium\")\n\t\t\tbreak;\n\t}\n}\n\nconst platform = deprecatedAgent || agent.platform;\nenv.isMac = platform.toLowerCase().indexOf(\"mac\") != -1;\nif (/iPad|iPhone|iPod/.test(platform)) env.isIOS = true;\nif (platform.indexOf(\"Android\") != -1) env.isAndroid = true;\n\nif(deprecatedAgent){\n\tif(env.isIOS || env.isAndroid || deprecatedAgent.indexOf(\"Mobile\") != -1 || deprecatedAgent.indexOf(\"Windows Phone\") != -1)\n\t\tenv.mobile = true;\n} else\n\tenv.mobile = agent.mobile;\n\nif (env.mobile || navigator.maxTouchPoints > 1)\n\tenv.touch = true;\n\nenv.fastClick = !env.touch;\n\n//maximum height/width for HTML elements in pixels (rough), bigger values will be ignored by browser\nif (env.isIE || env.isEdge || env.isFF)\n\tenv.maxHTMLElementSize = 10000000;\nif (env.isSafari)\n\tenv.maxHTMLElementSize = 100000000;\n\nenv.transform = \"transform\";\nenv.transition = \"transition\";\nenv.transitionDuration = \"transitionDuration\";\nenv.translate = \"translate3d\";\nenv.transitionEnd = \"transitionend\";\n\n//touch events that can be prevented\nenv.passiveEventListeners = false;\ntry {\n\tconst opts = Object.defineProperty({}, \"passive\", {\n\t\tget: function() { // eslint-disable-line\n\t\t\tenv.passiveEventListeners = true;\n\t\t}\n\t});\n\twindow.addEventListener(\"testPassive\", null, opts);\n\twindow.removeEventListener(\"testPassive\", null, opts);\n} catch (e) {} // eslint-disable-line\n\nenv.svg = (function(){\n\treturn document.implementation.hasFeature(\"http://www.w3.org/TR/SVG11/feature#BasicStructure\", \"1.1\");\n})();\n\nenv.svganimation = (function(){\n\treturn document.implementation.hasFeature(\"https://www.w3.org/TR/SVG11/feature#SVG-animation\", \"1.1\");\n})();\n\nexport default env;","import {extend, bind, isDate, isUndefined} from \"../../webix/helpers\";\nimport env from \"../../webix/env\";\n\nimport Promise from \"../../thirdparty/promiz\";\nimport i18n from \"../../webix/i18n\";\n\nimport require from \"../require\";\nimport jsarray from \"./jsarray\";\n\n\nconst excel = extend({\n\ttoObject:function(data){\n\t\tif(!data.excel){\n\t\t\tvar opts = data.options || {};\n\t\t\tif (opts.dataurl) \n\t\t\t\textend(opts, this._urlToOptions(opts.dataurl));\n\n\t\t\tdata = data.data || data;\n\t\t\tvar promise = Promise.defer();\n\n\t\t\tif(data.name){ //file\n\t\t\t\topts.ext = data.name.split(\".\").pop();\n\t\t\t\tvar reader = new FileReader();\n\n\t\t\t\treader.onload = bind(function (e) {\n\t\t\t\t\tpromise.resolve(this.parseData(e.target.result, opts));\n\t\t\t\t}, this);\n\t\t\t\treader.readAsArrayBuffer(data);\n\t\t\t}\n\t\t\telse //arraybuffer\n\t\t\t\tpromise.resolve(this.parseData(data, opts));\n\n\t\t\treturn promise;\n\t\t}\n\t\t//plain jsarray or hash\n\t\treturn data;\n\t},\n\tparseData:function(data, options){\n\t\tdata = new Uint8Array(data);\n\t\tconst arr = [];\n\t\tfor(let i = 0; i != data.length; ++i)\n\t\t\tarr[i] = String.fromCharCode(data[i]);\n\n\t\tlet ext = (options.ext || options).toLowerCase();\n\t\tif (ext != \"xls\") ext = \"xlsx\";\n\t\treturn require(env.cdn + \"/extras/xlsx.core.styles.min.js\").then(bind(function(){\n\t\t\t/* global XLS, XLSX */\n\t\t\tconst wb = (ext == \"xls\" ? XLS : XLSX).read(arr.join(\"\"), {\n\t\t\t\ttype: \"binary\",\n\t\t\t\tcellStyles: true,\n\t\t\t\tcellDates: isUndefined(options.cellDates) ? true : options.cellDates,\n\t\t\t\tsheetStubs: options.sheetStubs\n\t\t\t});\n\n\t\t\tconst book = wb.Workbook;\n\t\t\tconst res = {\n\t\t\t\tsheets: wb.Sheets,\n\t\t\t\tnames: wb.SheetNames,\n\t\t\t\toptions:options,\n\t\t\t\tranges: book ? (book.Names || []) : [],\n\t\t\t\tstates: book && book.Sheets ? book.Sheets.map(s => [\"visible\", \"hidden\", \"veryHidden\"][s.Hidden]) : wb.SheetNames.map(() => \"visible\")\n\t\t\t};\n\t\t\treturn extend(this.getSheet(res, options), res);\n\t\t}, this));\n\t},\n\tgetSheet:function(data, options){\n\t\tvar name = options.name || data.names[0];\n\t\tdata = this.sheetToArray(data.sheets[name], options);\n\t\tif(options.rows && options.rows.length)\n\t\t\tdata.data = data.data.splice(options.rows[0], Math.min(options.rows[1], data.data.length)-options.rows[0]);\n\t\treturn data;\n\t},\n\tsheetToArray:function(sheet, options){\n\t\tconst all = [];\n\t\tconst spans = [];\n\t\tconst styles = [];\n\t\tconst sizes = [];\n\t\tconst types = [];\n\t\tconst hidden = [];\n\n\t\tconst cellTypes = { n:\"number\", d:\"date\", s:\"string\", b:\"boolean\"};\n\n\t\tif(sheet && sheet[\"!ref\"]){\n\t\t\tvar range = XLS.utils.decode_range(sheet[\"!ref\"]), \n\t\t\t\trow, col, cellCoord, cell,\n\t\t\t\txCorrection = range.s.c,\n\t\t\t\tyCorrection = range.s.r+(options.rows?options.rows[0]:0);\n\n\t\t\tfor (row = range.s.r; row <= range.e.r; row++) {\n\t\t\t\tvar nrow = [];\n\t\t\t\tfor (col = range.s.c; col <= range.e.c; col++) {\n\t\t\t\t\tcellCoord = XLS.utils.encode_cell({ r: row, c: col });\n\t\t\t\t\tcell = sheet[cellCoord];\n\t\t\t\t\tif(!cell)\n\t\t\t\t\t\tnrow.push(\"\");\n\t\t\t\t\telse{\n\t\t\t\t\t\tvar ncell = \"\";\n\t\t\t\t\t\tif(options.math&&cell.f) // get formula\n\t\t\t\t\t\t\tncell = cell.f.charAt(0)==\"=\" ? cell.f : \"=\"+cell.f;\n\t\t\t\t\t\telse if (cell.t ==\"d\" && isDate(cell.v))\n\t\t\t\t\t\t\tncell = i18n.dateFormatStr(cell.v);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tncell = cell.v;\n\t\t\t\t\t\tnrow.push(ncell);\n\n\t\t\t\t\t\tif (cell.s)\n\t\t\t\t\t\t\tstyles.push([row-yCorrection, col-xCorrection, cell.s]);\n\t\t\t\t\t\tif (cell.t)\n\t\t\t\t\t\t\ttypes.push([row-yCorrection, col-xCorrection, cellTypes[cell.t]]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tall.push(nrow);\n\t\t\t}\n\n\t\t\tif(sheet[\"!merges\"]){\n\t\t\t\tvar merges = sheet[\"!merges\"];\n\t\t\t\tfor(let i = 0; i=0 && e.r-yCorrection<=options.rows[1]))\n\t\t\t\t\t\tspans.push([s.r-yCorrection, s.c-xCorrection, e.c-s.c+1, e.r-s.r+1]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(sheet[\"!cols\"]){\n\t\t\t\tvar widths = sheet[\"!cols\"];\n\t\t\t\tfor(let i = 0; i\": \">\",\n\t\"\\\"\": \""\",\n\t\"'\": \"'\",\n\t\"`\": \"`\"\n};\nvar badChars = /[&<>\"'`]/g;\nvar escapeChar = function(chr) {\n\treturn escape[chr] || \"&\";\n};\n\n\nfunction template(str){\n\tif (typeof str == \"function\") return str;\n\tif (_cache[str])\n\t\treturn _cache[str];\n\t\t\n\tstr=(str||\"\").toString();\t\t\t\n\tif (str.indexOf(\"->\")!=-1){\n\t\tvar teststr = str.split(\"->\");\n\t\tswitch(teststr[0]){\n\t\t\tcase \"html\": \t//load from some container on the page\n\t\t\t\tstr = getValue(teststr[1]);\n\t\t\t\tbreak;\n\t\t\tcase \"http\": \t//load from external file\n\t\t\t\tstr = new ajax().sync().get(teststr[1],{uid:uid()}).responseText;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t//do nothing, will use template as is\n\t\t\t\tbreak;\n\t\t}\n\t}\n\t\t\n\t//supported idioms\n\t// {obj.attr} => named attribute or value of sub-tag in case of xml\n\tstr=(str||\"\").toString();\t\t\n\n\t// Content Security Policy enabled\n\tif(env.strict){\n\t\tif (!_csp_cache[str]){\n\t\t\t_csp_cache[str] = [];\n\n\t\t\t// get an array of objects (not sorted by position)\n\t\t\tvar temp_res = [];\n\t\t\tstr.replace(/\\{obj\\.([^}?]+)\\?([^:]*):([^}]*)\\}/g,function(search,s1,s2,s3,pos){\n\t\t\t\ttemp_res.push({pos: pos, str: search, fn: function(obj){\n\t\t\t\t\treturn obj[s1]?s2:s3;\n\t\t\t\t}});\n\t\t\t});\n\t\t\tstr.replace(/\\{common\\.([^}(]*)\\}/g,function(search,s,pos){\n\t\t\t\ttemp_res.push({pos: pos, str: search, fn: function(_,common){\n\t\t\t\t\treturn common[s]||\"\";\n\t\t\t\t}});\n\t\t\t});\n\t\t\tstr.replace(/\\{common\\.([^}(]*)\\(\\)\\}/g,function(search,s,pos){\n\t\t\t\ttemp_res.push({pos: pos, str: search, fn: function(obj,common){\n\t\t\t\t\treturn (common[s]?common[s].apply(this, arguments):\"\");\n\t\t\t\t}});\n\t\t\t});\n\t\t\tstr.replace(/\\{obj\\.([^:}]*)\\}/g,function(search,s,pos){\n\t\t\t\ttemp_res.push({pos: pos, str: search, fn: function(obj){\n\t\t\t\t\treturn obj[s];\n\t\t\t\t}});\n\t\t\t});\n\t\t\tstr.replace(\"{obj}\",function(search,pos){\n\t\t\t\ttemp_res.push({pos: pos, str: search, fn: function(obj){\n\t\t\t\t\treturn obj;\n\t\t\t\t}});\n\t\t\t});\n\t\t\tstr.replace(/#([^#'\";, ]+)#/gi,function(search,s,pos){\n\t\t\t\tif(s.charAt(0)==\"!\"){\n\t\t\t\t\ts = s.substr(1);\n\t\t\t\t\ttemp_res.push({pos: pos, str: search, fn: function(obj){\n\t\t\t\t\t\tif(s.indexOf(\".\")!= -1)\n\t\t\t\t\t\t\tobj = CodeParser.collapseNames(obj); // apply complex properties\n\t\t\t\t\t\treturn template.escape(obj[s]);\n\t\t\t\t\t}});\n\t\t\t\t}\n\t\t\t\telse{\n\t\t\t\t\ttemp_res.push({pos: pos, str: search, fn: function(obj){\n\t\t\t\t\t\tif(s.indexOf(\".\")!= -1)\n\t\t\t\t\t\t\tobj = CodeParser.collapseNames(obj); // apply complex properties\n\t\t\t\t\t\treturn obj[s];\n\t\t\t\t\t}});\n\t\t\t\t}\n\n\t\t\t});\n\n\t\t\t// sort template parts by position\n\t\t\ttemp_res.sort(function(a,b){\n\t\t\t\treturn (a.pos > b.pos)?1:-1;\n\t\t\t});\n\n\t\t\t// create an array of functions that return parts of html string\n\t\t\tif(temp_res.length){\n\t\t\t\tvar lastPos = 0;\n\t\t\t\tvar addStr = function(str,n0,n1){\n\t\t\t\t\t_csp_cache[str].push(function(){\n\t\t\t\t\t\treturn str.slice(n0,n1);\n\t\t\t\t\t});\n\t\t\t\t};\n\t\t\t\tfor(var i = 0; i< temp_res.length; i++){\n\t\t\t\t\tvar pos = temp_res[i].pos;\n\t\t\t\t\taddStr(str,lastPos,pos);\n\t\t\t\t\t_csp_cache[str].push(temp_res[i].fn);\n\t\t\t\t\tlastPos = pos + temp_res[i].str.length;\n\t\t\t\t}\n\t\t\t\taddStr(str,lastPos,str.length);\n\t\t\t}\n\t\t\telse\n\t\t\t\t_csp_cache[str].push(function(){return str;});\n\t\t}\n\t\treturn function(){\n\t\t\tvar s = \"\";\n\t\t\tfor(var i=0; i < _csp_cache[str].length;i++){\n\t\t\t\ts += _csp_cache[str][i].apply(this,arguments);\n\t\t\t}\n\t\t\treturn s;\n\t\t};\n\t}\n\n\tlet helpers = false;\n\tstr=str.replace(slashes,\"\\\\\\\\\");\n\tstr=str.replace(newlines,\"\\\\n\");\n\tstr=str.replace(quotes,\"\\\\\\\"\");\n\n\tstr=str.replace(/\\{obj\\.([^}?]+)\\?([^:]*):([^}]*)\\}/g,\"\\\"+(obj.$1?\\\"$2\\\":\\\"$3\\\")+\\\"\");\n\tstr=str.replace(/\\{common\\.([^}(]*)\\}/g,\"\\\"+(common.$1||'')+\\\"\");\n\tstr=str.replace(/\\{common\\.([^}(]*)\\(\\)\\}/g,\"\\\"+(common.$1?common.$1.apply(this, arguments):\\\"\\\")+\\\"\");\n\tstr=str.replace(/\\{obj\\.([^}]*)\\}/g,\"\\\"+(obj.$1)+\\\"\");\n\tstr=str.replace(\"{obj}\",\"\\\"+obj+\\\"\");\n\tstr=str.replace(/#([^#'\";, ]+)#/gi,function(str, key){\n\t\tif (key.charAt(0)==\"!\"){\n\t\t\thelpers = true;\n\t\t\treturn \"\\\"+template.escape(obj.\"+key.substr(1)+\")+\\\"\";\n\t\t} else\n\t\t\treturn \"\\\"+(obj.\"+key+\")+\\\"\";\n\t});\n\n\ttry {\n\t\tif (helpers){\n\t\t\tconst temp = Function(\"obj\",\"common\",\"marks\", \"value\", \"template\", \"return \\\"\"+str+\"\\\";\");\n\t\t\t_cache[str] = function(a,b,c,d){ \n\t\t\t\treturn temp(a,b,c,d,template);\n\t\t\t};\n\t\t} else {\n\t\t\t_cache[str] = Function(\"obj\",\"common\",\"return \\\"\"+str+\"\\\";\");\n\t\t}\n\t} catch(e){\n\t\tassert(0, \"Invalid template:\"+str);\n\t}\n\n\treturn _cache[str];\n}\n\n\n\ntemplate.escape = function(str){\n\tif (str === undefined || str === null) return \"\";\n\treturn (str.toString() || \"\" ).replace(badChars, escapeChar);\n};\ntemplate.empty=function(){\treturn \"\";\t};\n\nexport default template;","import {offset} from \"../webix/html\";\nimport {delay} from \"../webix/helpers\";\n\n\nconst AutoScroll = {\n\t_auto_scroll:function(pos){\n\t\tlet yScroll, xScroll;\n\t\tlet mode = this._settings.dragscroll;\n\n\t\tif (typeof mode !== \"string\")\n\t\t\tmode = this._settings.layout||\"xy\";\n\t\txScroll = mode.indexOf(\"x\") !== -1;\n\t\tyScroll = mode.indexOf(\"y\") !== -1;\n\n\t\tconst data = this._body || this.$view;\n\t\tconst box = offset(data);\n\n\t\tconst sense = Math.max((this._settings.rowHeight||(this.type&&!isNaN(parseFloat(this.type.height))?this.type.height:0))+5, 40); //dnd auto-scroll sensivity\n\t\tlet reset = false;\n\n\t\tif (yScroll && this._auto_y_scroll(pos, box, sense) ) reset = true;\n\t\tif (xScroll && this._auto_x_scroll(pos, box, sense) ) reset = true;\n\n\t\tif (reset)\n\t\t\tthis._auto_scroll_delay = delay(this._auto_scroll, this, [pos], 100);\n\t},\n\t_auto_scroll_column:function(pos){\n\t\tconst mode = this._settings.dragscroll;\n\t\tif (typeof mode === \"string\" && mode.indexOf(\"x\") === -1)\n\t\t\treturn;\n\n\t\tconst data = this._header || this.$view;\n\t\tconst box = offset(data);\n\n\t\tconst sense = Math.max(this._settings.headerRowHeight||0, 40);\n\t\tif ( this._auto_x_scroll(pos, box, sense) )\n\t\t\tthis._auto_scroll_delay = delay(this._auto_scroll_column, this, [pos], 100);\n\t},\n\t_auto_y_scroll:function(pos, box, sense){\n\t\tlet top = box.y;\n\t\tlet bottom = top + box.height;\n\t\tconst scroll = this.getScrollState();\n\n\t\tconst config = this._settings;\n\t\tif(config.topSplit){\n\t\t\tconst topSplitPos = this._cellPosition(this.getIdByIndex(config.topSplit-1), this.columnId(0));\n\t\t\ttop += topSplitPos.top + topSplitPos.height;\n\t\t}\n\n\t\tif (pos.y < (top + sense)){\n\t\t\treturn this._auto_scrollTo(scroll.x, scroll.y-sense*2, pos, \"y\");\n\t\t} else if (pos.y > bottom - sense){\n\t\t\treturn this._auto_scrollTo(scroll.x, scroll.y+sense*2, pos, \"y\");\n\t\t}\n\t\treturn false;\n\t},\n\t_auto_x_scroll:function(pos, box, sense){\n\t\tlet left = box.x;\n\t\tlet right = left + box.width;\n\t\tconst scroll = this.getScrollState();\n\n\t\tif (pos.x < (left + sense)){\n\t\t\treturn this._auto_scrollTo(scroll.x-sense*2, scroll.y, pos, \"x\");\n\t\t} else if (pos.x > right - sense){\n\t\t\treturn this._auto_scrollTo(scroll.x+sense*2, scroll.y, pos, \"x\");\n\t\t}\n\t\treturn false;\n\t},\n\t_auto_scrollTo:function(x, y, pos, mode){\n\t\tif (this.callEvent(\"onBeforeAutoScroll\", [pos])){\n\t\t\tthis.scrollTo(x, y);\n\t\t\tthis.callEvent(\"onAfterAutoScroll\", []);\n\t\t\tconst scroll = this.getScrollState();\n\t\t\tconst diff = this._render_scroll_shift ? 0 : (this._render_scroll_diff||0);\n\t\t\treturn Math.abs((mode === \"x\" ? x : y) - scroll[mode] + diff) < 1;\n\t\t}\n\t\treturn false;\n\t}\n};\n\nexport default AutoScroll;","import {assert} from \"../webix/debug\";\n\nimport {uid, isArray, toNode, isUndefined, toFunctor} from \"../webix/helpers\";\nimport {attachEvent} from \"../webix/customevents\";\nimport {locate} from \"../webix/html\";\nimport {use} from \"../services\";\n\nimport type from \"../webix/type\";\nimport state from \"../core/state\";\n\n//global click events for UI\nimport \"./click\";\n\nconst views = {};\n\nfunction ui(config, parent, id){\n\tvar res;\n\tstate._ui_creation++;\n\t// save old value of global scope\n\tconst temp_scope = state._global_scope;\n\t// save old value of global collection\n\tconst temp_collection = state._global_collection;\n\t// set global scope to the scope of new UI or to previous value\n\t// as result inner webix.ui calls will have access the scope of master view\n\t// mainly necessary for suggests\n\tstate._global_scope = config.$scope || temp_scope;\n\ttry {\n\t\tres = _ui_creator(config, parent, id);\n\t} finally {\n\t\tstate._ui_creation--;\n\t\t// restore global scope\n\t\tstate._global_scope = temp_scope;\n\t\t// restore global collection\n\t\t// if an error occurred while creating the isolated layout\n\t\tstate._global_collection = temp_collection;\n\t}\n\treturn res;\n}\nui.views = views;\n\n\nfunction _ui_creator(config, parent, id){\n\tvar multiset = isArray(config);\n\tvar node = toNode((config.container||parent)||document.body);\n\n\t// solve problem with non-unique ids\n\tif(node._settings)\n\t\tid = _correctId(node, multiset, id);\n\n\tvar top_node;\n\tvar moving = false;\n\tvar body_child = (node == document.body);\n\tif (config._settings || (node && multiset)){\n\t\ttop_node = config;\n\t\tmoving = true;\n\t} else {\n\t\tif (node && body_child)\n\t\t\tconfig.$topView = true;\n\t\tif (!config._inner)\n\t\t\tconfig._inner = {};\n\n\t\tif (parent && parent.getParentView){\n\t\t\tstate._parent_cell = (!id && id!==0) ? parent.getParentView() : parent;\n\t\t}\n\n\t\ttop_node = _view(config);\n\t}\n\n\tif (body_child && !top_node.setPosition && !top_node.$apiOnly)\n\t\tuse(\"fixHeight\")();\n\n\tif (top_node._settings && top_node._settings._hidden && !node.$view){\n\t\ttop_node._settings._container = node;\n\t} else if (!top_node.$apiOnly){\n\t\tif (node.appendChild)\n\t\t\t_appendDom(node, top_node, config);\n\t\telse if (node.destructor){\n\t\t\tvar target = node;\n\n\t\t\t//addView or view moving with target id\n\t\t\tif (!id && id!==0 && !isArray(top_node)){\n\t\t\t\tid = node;\n\t\t\t\tnode = node.getParentView();\n\t\t\t}\n\n\t\t\t//if target supports view adding\n\t\t\tif (node && node._replace){\n\t\t\t\tif (moving && top_node.getParentView){\n\t\t\t\t\t//if source supports view removing\n\t\t\t\t\tlet parent = top_node.getParentView();\n\t\t\t\t\tif (parent && parent._remove){\n\t\t\t\t\t\tparent._remove(top_node);\n\t\t\t\t\t}\n\t\t\t\t\t//adjust parent link and scope\n\t\t\t\t\ttop_node._parent_cell = node;\n\t\t\t\t\ttop_node.$scope = node.$scope;\n\t\t\t\t}\n\n\t\t\t\tnode._replace(top_node, id);\n\t\t\t} else {\n\t\t\t\tlet parent = target.$view.parentNode;\n\t\t\t\ttarget.destructor();\n\t\t\t\t_appendDom(parent, top_node, config);\n\t\t\t}\n\t\t} else\n\t\t\tassert(0, \"Not existing parent:\"+config.container);\n\t}\n\n\treturn top_node;\n}\n\nfunction _appendDom(node, top_node, config){\n\tnode.appendChild(top_node._viewobj);\n\tif (top_node.getParentView()) return;\n\n\t//resize window with position center or top\n\t//do not resize other windows and elements\n\t// which are attached to custom html containers\n\tif (((!top_node.setPosition || top_node._settings.fullscreen) && node == document.body) || top_node._settings.position )\n\t\tstate.top_views.push(top_node._destructor_handler);\n\tif (!config.skipResize)\n\t\ttop_node.adjust();\n}\n\nfunction _correctId(target, multiset, id){\n\t//replace view\n\tvar views = [target];\n\t//replace content of layout\n\tif (multiset)\n\t\tviews = target.getChildViews();\n\t//replace content of window\n\telse if (target._body_cell)\n\t\tviews = [target._body_cell];\n\t//add cell in layout by number\n\telse if (typeof id == \"number\"){\n\t\treturn id;\n\t//replace cell in layout by id\n\t} else if (id){\n\t\tviews = [$$(id)];\n\t\t_deleteIds(views);\n\t\treturn views[0].config.id;\n\t}\n\n\t_deleteIds(views);\n\treturn id;\n}\n\nfunction _deleteIds(uis){\n\tfor (var i = uis.length - 1; i >= 0; i--){\n\t\tlet current = uis[i];\n\t\t//remove original id\n\t\tdelete views[current.config.id];\n\t\t//create temp id\n\t\tcurrent.config.id = \"x\"+uid();\n\t\tviews[current.config.id] = current;\n\t\t//process childs\n\t\tif (current.getChildViews)\n\t\t\t_deleteIds(current.getChildViews());\n\t\t//process related UI\n\t\tif (current._destroy_with_me)\n\t\t\t_deleteIds(current._destroy_with_me);\n\t}\n}\n\n\nfunction _view(config){\n\n\tif (DEBUG){\n\t\t// check for trailing comma\n\t\tvar coll = config.cells || config.rows || config.elements || config.cols;\n\t\tif (coll)\n\t\t\tfor (let i=0; i0; i--) {\n\t\tassert(origins[i],\"Invalid mixing source\");\n\t\tif (typeof origins[i]== \"function\")\n\t\t\torigins[i]=origins[i].prototype;\n\t\tif (origins[i].$init) \n\t\t\tconstruct.push(origins[i].$init);\n\t\tif (origins[i].defaults){ \n\t\t\tvar defaults = origins[i].defaults;\n\t\t\tif (!compilation.defaults)\n\t\t\t\tcompilation.defaults = {};\n\t\t\tfor (let def in defaults)\n\t\t\t\tif (isUndefined(compilation.defaults[def]))\n\t\t\t\t\tcompilation.defaults[def] = defaults[def];\n\t\t}\n\t\tif (origins[i].type && compilation.type){\n\t\t\tfor (let def in origins[i].type)\n\t\t\t\tif (!compilation.type[def])\n\t\t\t\t\tcompilation.type[def] = origins[i].type[def];\n\t\t}\n\t\t\t\n\t\tfor (var key in origins[i]){\n\t\t\tif (!compilation[key] && compilation[key] !== false)\n\t\t\t\tcompilation[key] = origins[i][key];\n\t\t}\n\t}\n\t\n\tif (has_constructor)\n\t\tconstruct.push(compilation.$init);\n\t\n\t\n\tcompilation.$init = function(){\n\t\tfor (var i=0; i 0 && message.keyboard){\n\t\tconst code = e.which || e.keyCode;\n\t\tif(code != 13 && code != 32 && code != 27)\n\t\t\treturn;\n\n\t\tlet activeBox;\n\n\t\tfor(let i = count - 1; i >= 0; i--){\n\t\t\tconst box = modalbox.pull[ order[i] ];\n\n\t\t\tif(box._box != source && box._box.contains(source) && code == 32) // ignore space inside input\n\t\t\t\treturn;\n\n\t\t\tif(box.container && box.container.contains(source)){\n\t\t\t\tactiveBox = box;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif(!activeBox)\n\t\t\tactiveBox = modalbox.pull[ order[order.length-1] ];\n\n\t\tif (code == 13 || code == 32)\n\t\t\tcallback(activeBox, true);\n\t\telse if (code == 27)\n\t\t\tcallback(activeBox, false);\n\n\t\tpreventEvent(e);\n\t\treturn !(e.cancelBubble = true);\n\t}\n}\n\nevent(document, \"keydown\", modal_key, { capture: true });\n\t\nfunction modality(mode, container){\n\tvar node = container || document.body;\n\tvar cover;\n\tif(isUndefined(node.modality)){\n\t\tcover = create(\"DIV\", {\n\t\t\t\"class\":\"webix_modal_cover\",\n\t\t\tstyle:\"position:\"+(container ? \"absolute\" : \"fixed\")+\";\"\n\t\t});\n\t\tcover.onkeydown = modal_key;\n\n\t\tif(container){\n\t\t\tvar position = window.getComputedStyle(container).position;\n\t\t\tif(position != \"fixed\" && position != \"absolute\" && position != \"sticky\" && position != \"relative\")\n\t\t\t\tnode.style.position = \"relative\";\n\t\t}\n\t\tnode.appendChild(cover);\n\t\tnode.modality = 1;\n\t}\n\telse\n\t\tmode ? node.modality ++ : node.modality --;\n\n\t//trigger visibility only if necessary\n\tif((mode && node.modality === 1) || node.modality === 0){\n\t\tcover = cover || Array.prototype.slice.call(node.querySelectorAll(\".webix_modal_cover\")).filter(el => el.parentNode == node)[0];\n\n\t\tif(cover){\n\t\t\tif(!node.modality){\n\t\t\t\tcover.style.display = \"none\";\n\t\t\t\tremoveCss(node, \"webix_modalbox_inside\");\n\t\t\t}\n\t\t\telse if(node.modality == 1){\n\t\t\t\tcover.style.display = \"inline-block\";\n\t\t\t\taddCss(node, \"webix_modalbox_inside\");\n\t\t\t}\n\t\t}\n\t}\n\treturn cover;\n}\n\nfunction button(text, result, className){\n\treturn \"
\"+text+\"
\";\n}\n\nfunction input(config){\n\treturn \"
\";\n}\n\nfunction info(text){\n\tif (!t.area){\n\t\tt.area = document.createElement(\"DIV\");\n\t\tt.area.className = \"webix_message_area\";\n\t\tt.area.style[t.position]=\"5px\";\n\t\t\n\t\tdocument.body.appendChild(t.area);\n\t}\n\tt.area.setAttribute(\"role\", \"alert\");\n\tt.area.setAttribute(\"aria-atomic\", true);\n\tt.hide(text.id);\n\tvar message = document.createElement(\"DIV\");\n\tmessage.innerHTML = \"
\"+text.text+\"
\";\n\tmessage.className = \"webix_message webix_\" + text.type;\n\tmessage.onclick = function(){\n\t\tif (text) t.hide(text.id);\n\t\ttext = null;\n\t};\n\n\tif (t.position == \"bottom\" && t.area.firstChild)\n\t\tt.area.insertBefore(message,t.area.firstChild);\n\telse\n\t\tt.area.appendChild(message);\n\t\n\tif (text.expire > 0)\n\t\tt.timers[text.id]=window.setTimeout(function(){\n\t\t\tt.hide(text.id);\n\t\t}, text.expire);\n\n\t//styling for animation\n\tmessage.style.height = message.offsetHeight-2+\"px\";\n\n\tt.pull[text.id] = message;\n\tmessage = null;\n\n\treturn text.id;\n}\nfunction _boxStructure(config, ok, cancel, hasInput){\n\tvar box = document.createElement(\"DIV\");\n\tvar css = config.css ? \" \"+config.css : \"\";\n\tbox.className = \"webix_modal_box webix_\"+config.type+css;\n\tbox.setAttribute(\"webixbox\", 1);\n\tbox.setAttribute(\"role\", \"alertdialog\");\n\tbox.setAttribute(\"aria-label\", config.title || \"\");\n\tbox.setAttribute(\"tabindex\", \"0\");\n\n\tvar inner = \"\";\n\tif (config.width)\n\t\tbox.style.width = config.width+(rules.isNumber(config.width)?\"px\":\"\");\n\tif (config.height)\n\t\tbox.style.height = config.height+(rules.isNumber(config.height)?\"px\":\"\");\n\tif (config.title)\n\t\tinner += \"
\"+config.title+\"
\";\n\tinner += \"
\"+(config.content?\"\":(config.text || \"\"))+\"
\";\n\tinner += \"
\";\n\tif (hasInput)\n\t\tinner += input(config.input);\n\tif (cancel)\n\t\tinner += button(config.cancel || i18n.message.cancel, false);\n\tif (ok)\n\t\tinner += button(config.ok || i18n.message.ok, true,\"confirm\");\n\tif (config.buttons && !ok && !cancel){\n\t\tfor (var i=0; i\";\n\tbox.innerHTML = inner;\n\n\tif (config.content){\n\t\tvar node = config.content;\n\t\tif (typeof node == \"string\") \n\t\t\tnode = document.getElementById(node);\n\t\tif (node.style.display == \"none\")\n\t\t\tnode.style.display = \"\";\n\t\tbox.childNodes[config.title?1:0].appendChild(node);\n\t}\n\n\tif (config.type.indexOf(\"prompt\") != -1){\n\t\tconst inputBox = box.querySelector(\".webix_popup_input\");\n\t\tconst input = inputBox.querySelector(\"input\");\n\t\tinput.oninput = function(){\n\t\t\tif (config.input.invalid){\n\t\t\t\tremoveCss(inputBox, \"webix_popup_invalid\");\n\t\t\t\tconfig.input.invalid = false;\n\t\t\t}\n\t\t};\n\t}\n\n\tbox.onclick = function(e){\n\t\tvar source = e.target;\n\t\tif (!source.className) source = source.parentNode;\n\t\tif (source.className.indexOf(\"webix_popup_button\")!=-1){\n\t\t\tlet result = source.getAttribute(\"result\");\n\t\t\tresult = (result == \"true\")||(result == \"false\"?false:result);\n\t\t\tcallback(config, result);\n\t\t}\n\t\te.cancelBubble = true;\n\t};\n\tconfig._box = box;\n\treturn box;\n}\n\nmodalbox.pull = {};\nmodalbox.order = [];\n\nfunction _createBox(config, ok, cancel, hasInput){\n\tconst box = config.tagName ? config : _boxStructure(config, ok, cancel, hasInput);\n\tconst container = config.container;\n\n\tconst containerWidth = container ? container.offsetWidth : (window.innerWidth||document.documentElement.offsetWidth);\n\tconst containerHeight = container ? container.offsetHeight : (window.innerHeight||document.documentElement.offsetHeight);\n\tconst containerLeft = container ? container.scrollLeft : 0;\n\tconst containerTop = container ? container.scrollTop : 0;\n\n\tif(config.container)\n\t\tbox.style.position = \"absolute\";\n\n\ttoNode((config.container || document.body).appendChild(box));\n\tconst cover = modality(true, config.container);\n\n\tconst x = config.left||Math.abs(containerLeft+Math.floor((containerWidth - box.offsetWidth)/2));\n\tconst y = config.top||Math.abs(containerTop+Math.floor((containerHeight - box.offsetHeight)/2));\n\tif (config.position == \"top\")\n\t\tbox.style.top = \"-3px\";\n\telse{\n\t\tbox.style.top = y+\"px\";\n\t\tif(cover){\n\t\t\tcover.style.top = containerTop+\"px\";\n\t\t\tcover.style.left = containerLeft+\"px\";\n\t\t}\n\t}\n\tbox.style.left = x+\"px\";\n\t//necessary for IE only\n\tbox.onkeydown = modal_key;\n\n\tif(hasInput)\n\t\tbox.querySelector(\".webix_popup_input input\").focus();\n\telse\n\t\tbox.focus();\n\n\tif (!config.id)\n\t\tconfig.id = _uid(\"modalbox\");\n\telse if(modalbox.pull[config.id]){\n\t\tmodalbox.hide(config.id);\n\t}\n\n\tmodalbox.order.push(config.id);\n\tmodalbox.pull[config.id] = config;\n\n\tconfig._promise = Promise.defer();\n\treturn config._promise;\n}\n\nfunction alertPopup(config){\n\treturn _createBox(config, true);\n}\nfunction confirmPopup(config){\n\treturn _createBox(config, true, true);\n}\nfunction boxPopup(config){\n\treturn _createBox(config);\n}\nfunction promptPopup(config){\n\treturn _createBox(config, true, true, true);\n}\nfunction box_params(text, type, callback){\n\tif (typeof text != \"object\"){\n\t\tif (typeof type == \"function\"){\n\t\t\tcallback = type;\n\t\t\ttype = \"\";\n\t\t}\n\t\ttext = {text:text, type:type, callback:callback };\n\t}\n\treturn text;\n}\nfunction params(text, type, expire, id){\n\tif (typeof text != \"object\")\n\t\ttext = {text:text, type:type, expire:expire, id:id};\n\ttext.id = text.id||_uid(\"message\");\n\ttext.expire = text.expire||t.expire;\n\treturn text;\n}\nexport function alert(){\n\tvar text = box_params.apply(this, arguments);\n\ttext.type = text.type || \"alert\";\n\treturn alertPopup(text);\n}\nexport function confirm(){\n\tvar text = box_params.apply(this, arguments);\n\ttext.type = text.type || \"confirm\";\n\treturn confirmPopup(text);\n}\n\nexport function modalbox(){\n\tvar text = box_params.apply(this, arguments);\n\ttext.type = text.type || \"alert\";\n\treturn boxPopup(text);\n}\n\nexport function prompt(){\n\tvar text = box_params.apply(this, arguments);\n\ttext.type = text.type || \"prompt\";\n\ttext.input = text.input || {};\n\treturn promptPopup(text);\n}\n\nmodalbox.hide = function(id){\n\tif(id && modalbox.pull[id]){\n\t\tvar node = modalbox.pull[id]._box;\n\t\tif(node){\n\t\t\tnode.parentNode.removeChild(node);\n\t\t\tmodalbox.order.splice(modalbox.order.indexOf(id), 1);\n\t\t\tmodality(false, modalbox.pull[id].container);\n\t\t\tdelete modalbox.pull[id];\n\t\t}\n\t}\n};\n\nmodalbox.hideAll = function(){\n\tfor (var id in modalbox.pull){\n\t\tthis.hide(id);\n\t}\n};\n\nexport function message(text, type, expire, id){ //eslint-disable-line\n\ttext = params.apply(this, arguments);\n\ttext.type = text.type||\"info\";\n\n\tvar subtype = text.type.split(\"-\")[0];\n\tswitch (subtype){\n\t\tcase \"alert\":\n\t\t\treturn alertPopup(text);\n\t\tcase \"confirm\":\n\t\t\treturn confirmPopup(text);\n\t\tcase \"modalbox\":\n\t\t\treturn boxPopup(text);\n\t\tcase \"prompt\":\n\t\t\treturn promptPopup(text);\n\t\tdefault:\n\t\t\treturn info(text);\n\t}\n}\n\nvar t = message;\nt.expire = 4000;\nt.keyboard = true;\nt.position = \"top\";\nt.pull = {};\nt.timers = {};\n\nt.hideAll = function(){\n\tfor (var key in t.pull)\n\t\tt.hide(key);\n};\nt.hide = function(id){\n\tvar obj = t.pull[id];\n\tif (obj && obj.parentNode){\n\t\twindow.setTimeout(function(){\n\t\t\tobj.parentNode.removeChild(obj);\n\t\t\tobj = null;\n\t\t},2000);\n\t\t//styling for animation\n\t\tobj.style.height = 0;\n\t\tobj.className+=\" hidden\";\n\t\tt.area.removeAttribute(\"role\");\n\t\t\n\t\tif(t.timers[id])\n\t\t\twindow.clearTimeout(t.timers[id]);\n\t\tdelete t.pull[id];\n\t}\n};\n\n//override circualr dependencies\ndefine(\"message\", message);\nexport default modalbox;","import {ui, $$} from \"../ui/core\";\nimport {isUndefined} from \"../webix/helpers\";\nimport {create} from \"../webix/html\";\nimport {assert} from \"../webix/debug\";\n\nconst fullscreen = {\n\tset:function(view, config){\n\t\tconfig = config || {};\n\n\t\tif(this._view)\n\t\t\tthis.exit();\n\n\t\tif($$(view))\n\t\t\tview = $$(view);\n\t\telse{\n\t\t\tif(typeof view == \"string\")\n\t\t\t\tview = document.getElementById(view);\n\t\t\tif(view instanceof Element)\n\t\t\t\tview = {$view: view, $html: true};\n\t\t\tassert(view, \"Incorrect view for fullscreen mode\");\n\t\t}\n\n\t\tthis._view = view;\n\t\tthis._pos = this._setPosition();\n\n\t\tconst viewConfig = view.config;\n\t\tif(view.setPosition){\n\t\t\tviewConfig.fullscreen = true;\n\t\t\tview.resize();\n\n\t\t\treturn view;\n\t\t}\n\t\telse{\n\t\t\tthis._fullscreen = ui({\n\t\t\t\tview:\"window\",\n\t\t\t\thead: this._getHeadConfig(config),\n\t\t\t\tcss:config.css||\"\",\n\t\t\t\tfullscreen:true,\n\t\t\t\tborderless:true,\n\t\t\t\t//better resize logic\n\t\t\t\tbody:{rows:[]}\n\t\t\t});\n\n\t\t\tif(viewConfig)\n\t\t\t\tthis._sizes = {\n\t\t\t\t\twidth: viewConfig.width, minWidth: viewConfig.minWidth, maxWidth: viewConfig.maxWidth,\n\t\t\t\t\theight: viewConfig.height, minHeight: viewConfig.minHeight, maxHeight: viewConfig.maxHeight\n\t\t\t\t};\n\n\t\t\tif(view.getParentView && view.getParentView()){\n\t\t\t\tthis._parent = view.getParentView();\n\n\t\t\t\tif(this._parent.index){\n\t\t\t\t\tthis._pos.index = this._parent.index(view);\n\t\t\t\t\tthis._pos.active = this._parent.getActiveId ? this._parent.getActiveId() == viewConfig.id : false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse{\n\t\t\t\tthis._parent = view.$view.parentNode;\n\t\t\t\tthis._pos.node = create(\"div\");\n\n\t\t\t\t//save old position\n\t\t\t\tthis._parent.replaceChild(this._pos.node, view.$view);\n\t\t\t}\n\n\t\t\tthis._fullscreen.getBody().addView(view.$html ? {view:\"template\", content:view.$view, css:\"webix_fullscreen_html\"} : view);\n\n\t\t\tthis._fullscreen.show();\n\t\t\tthis._setSizes(view);\n\n\t\t\treturn this._fullscreen;\n\t\t}\n\t},\n\texit:function(){\n\t\tif(this._view){\n\t\t\tconst viewConfig = this._view.config;\n\t\t\tthis._setPosition(true);\n\t\t\tif(this._view.setPosition){\n\t\t\t\tviewConfig.fullscreen = false;\n\t\t\t\tthis._view.resize();\n\t\t\t}\n\t\t\telse{\n\t\t\t\tif(this._parent instanceof Element){\n\t\t\t\t\tthis._view._parent_cell = null;\n\t\t\t\t\tif(this._view._set_inner)\n\t\t\t\t\t\tthis._view._set_inner(this._view.config);\n\t\t\t\t\tthis._parent.replaceChild(this._view.$view, this._pos.node);\n\t\t\t\t}\n\t\t\t\telse{\n\t\t\t\t\tif(!isUndefined(this._pos.index)){\n\t\t\t\t\t\tthis._parent.addView(this._view, this._pos.index);\n\t\t\t\t\t\tif(this._pos.active)\n\t\t\t\t\t\t\tthis._view.show(false, false);\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\tthis._view._parent_cell = this._parent;\n\t\t\t\t\t\tthis._parent._replace(this._view);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis._setSizes(this._view, this._sizes);\n\n\t\t\t\t//prevent view destruction (with layout)\n\t\t\t\tif(!this._view.$html)\n\t\t\t\t\tthis._fullscreen.getBody()._cells = [];\n\n\t\t\t\t//we can't set head false with replace, so we need to close win\n\t\t\t\tthis._fullscreen.close();\n\t\t\t}\n\t\t\tthis._clearValues();\n\t\t}\n\t},\n\t_clearValues:function(){\n\t\tdelete this._parent;\n\t\tdelete this._view;\n\t\tdelete this._sizes;\n\t\tdelete this._pos;\n\t\tdelete this._fullscreen;\n\t},\n\t_setPosition(restore){\n\t\tconst view = this._view;\n\t\tconst oldStyles = {};\n\n\t\tif(view.setPosition){\n\t\t\tif(restore)\n\t\t\t\tview.setPosition(this._pos.left, this._pos.top);\n\t\t\telse{\n\t\t\t\toldStyles.left = view.config.left;\n\t\t\t\toldStyles.top = view.config.top;\n\t\t\t\tview.setPosition(0,0);\n\t\t\t}\n\t\t}\n\t\telse{\n\t\t\tconst rules = [\"position\", \"top\", \"bottom\", \"left\", \"right\"];\n\t\t\tconst style = view.$view.style;\n\n\t\t\trules.forEach(rule => {\n\t\t\t\tif(restore)\n\t\t\t\t\tstyle[rule] = this._pos[rule];\n\t\t\t\telse{\n\t\t\t\t\toldStyles[rule] = style[rule];\n\t\t\t\t\tstyle[rule] = rule == \"position\" ? \"relative\" : 0;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn oldStyles;\n\t},\n\t_setSizes:function(view, sizes){\n\t\tif(!view.$html){\n\t\t\tsizes = sizes || {height:0, minHeight:0, maxHeight:0, width:0, minWidth:0, maxWidth:0};\n\t\t\tview.define(sizes);\n\t\t\tview.resize();\n\t\t}\n\t},\n\t_getHeadConfig:function(config){\n\t\tif(config.head === false || typeof config.head == \"object\")\n\t\t\treturn config.head;\n\t\telse{\n\t\t\treturn {\n\t\t\t\tcols:[\n\t\t\t\t\t{template:config.head||\"\", type:\"header\", borderless:true},\n\t\t\t\t\t{view:\"icon\", icon:\"wxi-close\", click:()=>{\n\t\t\t\t\t\tthis.exit();\n\t\t\t\t\t}}\n\t\t\t\t]\n\t\t\t};\n\t\t}\n\t}\n};\n\nexport default fullscreen;","import ready from \"../webix/ready\";\n\nimport {assert} from \"../webix/debug\";\nimport {event} from \"../webix/htmlevents\";\nimport {delay,uid,_power_array,isUndefined,isArray} from \"../webix/helpers\";\nimport {callEvent} from \"../webix/customevents\";\nimport {locate,preventEvent} from \"../webix/html\";\nimport {modalbox} from \"../webix/message\";\nimport fullscreen from \"../webix/fullscreen\";\n\nimport {$$} from \"../ui/core\";\nimport state from \"../core/state\";\n\nimport {define} from \"../services\";\n\n\nconst UIManager = {\n\t_view: null,\n\t_hotkeys: {},\n\t_focus_time:0,\n\t_controls: {\n\t\t\"esc\": \"escape\",\n\t\t\"up\": \"arrowup\",\n\t\t\"down\": \"arrowdown\",\n\t\t\"left\": \"arrowleft\",\n\t\t\"right\": \"arrowright\",\n\t\t\"pgdown\": \"pagedown\",\n\t\t\"pgup\": \"pageup\",\n\t\t\"space\": \" \",\n\t\t\"multiply\": \"*\",\n\t\t\"add\": \"+\",\n\t\t\"subtract\": \"-\",\n\t\t\"decimal\": \".\",\n\t\t\"divide\": \"/\",\n\t\t\"pausebreak\":\"pause\",\n\t\t\"5numlocked\":\"clear\"\n\t},\n\t_inputs:{\n\t\t\"input\": 1,\n\t\t\"button\":1,\n\t\t\"textarea\":1,\n\t\t\"select\":1\n\t},\n\t_enable: function() {\n\t\t// attaching events here\n\t\tevent(document, \"keydown\", this._keypress, { bind:this });\n\t\tevent(document, \"compositionstart\", ()=> this._startComposition());\n\t\tevent(document, \"compositionend\", ()=> this._endComposition());\n\t\tevent(document.body, \"click\", this._focus_click, { capture:true, bind:this });\n\t\tevent(document.body, \"focus\", this._focus_tab, { capture:true, bind:this });\n\n\t\tstate.destructors.push({obj:this});\n\t},\n\t_startComposition: function(){\n\t\tclearTimeout(this._composition);\n\t\tthis._composition = true;\n\t},\n\t_endComposition: function(){\n\t\t//in some browsers compositionEnd fires before the keyDown event\n\t\tthis._composition = delay(() => delete this._composition);\n\t},\n\tdestructor: function(){\n\t\tUIManager._view = null;\n\t},\n\tgetFocus: function() {\n\t\treturn this._view;\n\t},\n\t_focus_action:function(view){\n\t\tthis._focus_was_there = this._focus_was_there || view._settings.id;\n\t},\n\tsetFocus: function(view, only_api, tab){\n\t\t//view can be empty\n\t\tview = $$(view);\n\t\t//unfocus if view is hidden\n\t\tif (view && !view.$view) view = null;\n\n\t\t//store last click time, it is necessary to prevent refocusing\n\t\t//for example when user moves focus from onclick handler somewher\n\t\t//and we want to prevent autofocusing, when event will reach document.body\n\t\tthis._focus_time = state._focus_time = new Date();\n\n\t\tif (this._view === view) return true;\n\t\tif (this._view && this._view.callEvent)\n\t\t\tthis._view.callEvent(\"onBlur\", [this._view]);\n\n\t\tif (view && view.callEvent){\n\t\t\tview.callEvent(\"onFocus\", [view, this._view]);\n\t\t\tif(tab) view.callEvent(\"onTabFocus\", [view, this._view]);\n\t\t}\n\t\tcallEvent(\"onFocusChange\", [view, this._view]);\n\n\t\tif (this._view && this._view.blur && !only_api) this._view.blur();\n\t\tthis._view = view;\n\t\tif (view && view.focus && !only_api) view.focus();\n\t\treturn true;\n\t},\n\tapplyChanges: function(element){\n\t\tvar view = this.getFocus();\n\t\tif (view && view != element && view._applyChanges)\n\t\t\tview._applyChanges(element);\n\t},\n\thasFocus: function(view) {\n\t\treturn (view === this._view) ? true : false;\n\t},\n\t_focus: function(e){\n\t\tfor(let i = 0; i < modalbox.order.length; i++){\n\t\t\tif(modalbox.pull[ modalbox.order[i] ]._box.contains(e.target))\n\t\t\t\treturn;\n\t\t}\n\n\t\tvar view = locate(e, /*@attr*/\"view_id\") || this._focus_was_there;\n\n\t\t//if html was repainted we can miss the view, so checking last processed one\n\t\tview = $$(view);\n\t\tthis._focus_was_there = null;\n\n\t\t//set timer, to fix issue with Android input focusin\n\t\tstate._focus_time = new Date();\n\n\t\tif (view == this._view) return true;\n\n\t\tif (view){\n\t\t\tif (this.canFocus(view)){\n\t\t\t\t// keep form focus\n\t\t\t\tif (this._view && this._view.getFormView() == view && this._view.focus)\n\t\t\t\t\tthis._view.focus();\n\t\t\t\telse{\n\t\t\t\t\t//radio view with scroll: focus changes onClick event target into radiogroup, so we need to readjust the focus target before it happens\n\t\t\t\t\tif (e.target.type == \"radio\" || e.target.getAttribute(\"role\") == \"radio\")\n\t\t\t\t\t\te.target.setAttribute(\"tabindex\", \"0\");\n\n\t\t\t\t\tthis.setFocus(view);\n\t\t\t\t}\n\t\t\t}\n\t\t\t//remove focus from an unreachable view\n\t\t\telse if (view.$view.contains(e.target))\n\t\t\t\te.target.blur();\n\t\t}\n\t\telse this.setFocus(null);\n\n\t\treturn true;\n\t},\n\t_focus_click:function(e){\n\t\t// if it was onfocus/onclick less then 100ms behore then we ignore it\n\t\tif ((new Date())-this._focus_time < 100) {\n\t\t\tthis._focus_was_there = null;\n\t\t\treturn false;\n\t\t}\n\t\treturn this._focus(e);\n\t},\n\t_focus_tab: function(e){\n\t\tif(!this._inputs[e.target.nodeName.toLowerCase()])\n\t\t\treturn false;\n\t\treturn this._focus(e);\n\t},\n\t_top_modal: function(view){\n\t\tconst modality = state._modality;\n\t\tif (!modality.length) return true;\n\n\t\tconst top = this._getTop(view);\n\t\treturn (top.$view.style.zIndex||0) >= Math.max(...modality);\n\t},\n\t_getTop: function(view){\n\t\tlet top = view.queryView(view => !view.getParentView(), \"parent\") || view;\n\n\t\tconst insideContainer = $$(top.$view.parentNode); //container inside view (like filter in query view list)\n\t\tif(insideContainer)\n\t\t\ttop = this._getTop(insideContainer);\n\n\t\treturn top;\n\t},\n\tcanFocus:function(view){\n\t\tif(document.body.modality || view.$view.modality || view.queryView(view => view.$view.modality, \"parent\")) //modalbox\n\t\t\treturn false;\n\t\treturn view.isVisible() && view.isEnabled() && !view.config.disabled && this._top_modal(view) && !view.queryView({disabled:true}, \"parent\");\n\t},\n\n\t_moveChildFocus: function(check_view){\n\t\tvar focus = this.getFocus();\n\t\t//we have not focus inside of closing item\n\t\tif (check_view && !this._is_child_of(check_view, focus))\n\t\t\treturn false;\n\n\t\tif (!this._focus_logic(\"getPrev\", check_view))\n\t\t\tthis._view = null;\n\t},\n\t_is_child_of: function(parent, child) {\n\t\tif (!parent) return false;\n\t\tif (!child) return false;\n\t\twhile (child) {\n\t\t\tif (child === parent) return true;\n\t\t\tchild = child.getParentView();\n\t\t}\n\t\treturn false;\n\t},\n\t_keypress_timed:function(){\n\t\tif (this && this.callEvent)\n\t\t\tthis.callEvent(\"onTimedKeyPress\",[]);\n\t},\n\t_keypress: function(e) {\n\t\tlet code = e.which || e.keyCode;\n\n\t\t// processing or not found\n\t\tif (code == 229 || code == 0) return;\n\n\t\t// numpad keys\n\t\tif (code > 95 && code < 106) code -= 48;\n\n\t\tconst view = this.getFocus();\n\t\tif (view && view.callEvent) {\n\t\t\tif (view.callEvent(\"onKeyPress\", [code, e]) === false)\n\t\t\t\tpreventEvent(e);\n\t\t\tif (view.hasEvent(\"onTimedKeyPress\")){\n\t\t\t\tclearTimeout(view._key_press_timeout);\n\t\t\t\tview._key_press_timeout = delay(this._keypress_timed, view, [], (view._settings.keyPressTimeout||250));\n\t\t\t}\n\t\t}\n\n\t\tif (this._check_keycode(e) === false) {\n\t\t\tpreventEvent(e);\n\t\t\treturn false;\n\t\t}\n\t},\n\n\t// dir - getNext or getPrev\n\t_focus_logic: function(dir, focus) {\n\t\tvar next = focus||this.getFocus();\n\t\tif(next){\n\t\t\tdir = dir || \"getNext\";\n\t\t\tvar start = next;\n\t\t\tvar marker = uid();\n\n\t\t\twhile (true) { // eslint-disable-line\n\t\t\t\tnext = this[dir](next);\n\t\t\t\t// view with focus ability\n\t\t\t\tif (next && this.canFocus(next))\n\t\t\t\t\treturn this.setFocus(next);\n\n\t\t\t\t// elements with focus ability not found\n\t\t\t\tif (next === start || next.$fmarker == marker){\n\t\t\t\t\tif(focus)\n\t\t\t\t\t\tdocument.activeElement.blur();\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\t//prevents infinity loop\n\t\t\t\tnext.$fmarker = marker;\n\t\t\t}\n\t\t}\n\t},\n\t_tab_logic:function(view, e){\n\t\tvar mode = !e.shiftKey;\n\t\tif (view && view._custom_tab_handler && !view._custom_tab_handler(mode, e))\n\t\t\treturn false;\n\n\t\tif (view && view._in_edit_mode){\n\t\t\tif (view.editNext)\n\t\t\t\treturn view.editNext(mode);\n\t\t\telse if (view.editStop){\n\t\t\t\tview.editStop();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} else\n\t\t\tdelay(function(){\n\t\t\t\tview = $$(document.activeElement);\n\t\t\t\tif(view && !UIManager.canFocus(view))\n\t\t\t\t\treturn UIManager._focus_logic(mode ? \"getNext\" : \"getPrev\", view);\n\t\t\t\tUIManager.setFocus(view, true, true);\n\t\t\t});\n\t},\n\tgetTop: function(id) {\n\t\tvar next, view = $$(id);\n\n\t\twhile (view && (next = view.getParentView()))\n\t\t\tview = next;\n\t\treturn view;\n\t},\n\n\tgetNext: function(view, _inner_call) {\n\t\tvar cells = view.getChildViews();\n\t\t//tab to first children\n\t\tif (cells.length && !_inner_call)\n\t\t\tfor (var i = 0; i < cells.length; i++)\n\t\t\t\tif(this.canFocus(cells[i]))\n\t\t\t\t\treturn cells[i];\n\n\t\t//unique case - single view without child and parent\n\t\tvar parent = view.getParentView();\n\t\tif (!parent)\n\t\t\treturn view;\n\n\t\tvar p_cells = parent.getChildViews();\n\t\tif (p_cells.length){\n\t\t\tvar index = _power_array.find.call(p_cells, view)+1;\n\t\t\twhile (index < p_cells.length) {\n\t\t\t\t//next visible child\n\t\t\t\tif (this.canFocus(p_cells[index])) \n\t\t\t\t\treturn p_cells[index];\n\n\t\t\t\tindex++;\n\t\t\t}\n\t\t} \n\n\t\t//sibling of parent\n\t\treturn this.getNext(parent, true);\n\t},\n\n\tgetPrev: function(view, _inner_call) {\n\t\tvar cells = view.getChildViews();\n\t\t//last child of last child\n\t\tif (cells.length && _inner_call)\n\t\t\tfor (var i = cells.length - 1; i >= 0; i--)\n\t\t\t\tif(this.canFocus(cells[i]))\n\t\t\t\t\treturn this.getPrev(cells[i], true);\n\n\t\tif (_inner_call && this.canFocus(view)) return view;\n\n\t\t//fallback from top to bottom\n\t\tvar parent = view.getParentView();\n\t\tif (!parent)\n\t\t\treturn this.canFocus(view) ? this.getPrev(view, true) : view;\n\n\t\tvar p_cells = parent.getChildViews();\n\t\tif (p_cells) {\n\t\t\tvar index = _power_array.find.call(p_cells, view)-1;\n\t\t\twhile (index >= 0) {\n\t\t\t\tif (this.canFocus(p_cells[index]))\n\t\t\t\t\treturn this.getPrev(p_cells[index], true);\n\t\t\t\tindex--;\n\t\t\t}\n\t\t}\n\n\t\treturn this.getPrev(parent, true);\n\t},\n\taddHotKey: function(keys, handler, view) {\n\t\tassert(handler, \"Hot key handler is not defined\");\n\t\tconst code = this._parse_keys(keys);\n\n\t\tif (!view) view = null;\n\t\tif (!this._hotkeys[code]) this._hotkeys[code] = [];\n\t\tthis._hotkeys[code].push({ handler, view });\n\n\t\treturn keys;\n\t},\n\tremoveHotKey: function(keys, func, view){\n\t\tconst code = this._parse_keys(keys);\n\t\tif (!func && !view)\n\t\t\tdelete this._hotkeys[code];\n\t\telse {\n\t\t\tvar t = this._hotkeys[code];\n\t\t\tif (t){\n\t\t\t\tfor (var i = t.length - 1; i >= 0; i--) {\n\t\t\t\t\tif (view && t[i].view !== view) continue;\n\t\t\t\t\tif (func && t[i].handler !== func) continue;\n\t\t\t\t\tt.splice(i,1);\n\t\t\t\t}\n\t\t\t\tif (!t.length)\n\t\t\t\t\tdelete this._hotkeys[code];\n\t\t\t}\n\n\t\t}\n\t},\n\t_keycode: function(key, ctrl, shift, alt, meta) {\n\t\t//key can be undefined (browser autofill)\n\t\treturn (key||\"\").toLowerCase()+\"_\"+[\"\", (ctrl ? \"1\" : \"0\"), (shift ? \"1\" : \"0\"), (alt ? \"1\" : \"0\"), (meta ? \"1\" : \"0\")].join(\"\");\n\t},\n\t_check_keycode: function(e){\n\t\tconst keyCode = e.which || e.keyCode;\n\t\tconst is_any = !e.ctrlKey && !e.altKey && !e.metaKey && (keyCode!=9)&&(keyCode!=27)&&(keyCode!=13);\n\t\tconst code = this._keycode(e.key, e.ctrlKey, e.shiftKey, e.altKey, e.metaKey);\n\n\t\tvar focus = this.getFocus();\n\t\tif (this._hotkeys[code])\n\t\t\treturn this._process_calls(this._hotkeys[code], focus, e);\n\t\telse if (is_any && this._hotkeys[\"any_0000\"])\n\t\t\treturn this._process_calls(this._hotkeys[\"any_0000\"], focus, e);\n\n\t\treturn true;\n\t},\n\t_process_calls:function(calls, focus, e){\n\t\tfor (var i = 0; i < calls.length; i++) {\n\t\t\tvar key = calls[i];\n\t\t\tif ((key.view !== null) &&\t\t//common hot-key\n\t\t\t\t(focus !== key.view) &&\t\t//hot-key for current view\n\t\t\t\t//hotkey for current type of view\n\t\t\t\t(typeof(key.view) !== \"string\" || !focus || focus.name !== key.view)) continue;\n\n\t\t\tvar temp_result = key.handler(focus, e);\n\t\t\tif (!!temp_result === temp_result) return temp_result;\n\t\t}\n\t\treturn true;\n\t},\n\t_parse_keys: function(keys) {\n\t\tvar controls = this._controls;\n\t\tvar parts = keys.toLowerCase().split(/[ +\\-_]/);\n\t\tvar ctrl, shift, alt, meta;\n\t\tctrl = shift = alt = meta = 0;\n\t\tvar letter = \"\";\n\t\tfor (var i = 0; i < parts.length; i++) {\n\t\t\tif (parts[i] === \"ctrl\") ctrl = 1;\n\t\t\telse if (parts[i] === \"shift\") shift = 1;\n\t\t\telse if (parts[i] === \"alt\") alt = 1;\n\t\t\telse if (parts[i] === \"command\") meta = 1;\n\t\t\telse {\n\t\t\t\tletter = controls[parts[i]] || parts[i];\n\t\t\t}\n\t\t}\n\n\t\treturn this._keycode(letter, ctrl, shift, alt, meta);\n\t},\n\tgetState:function(node, children) {\n\t\tchildren = (children||false);\n\t\tnode = $$(node);\n\t\tvar state = {\n\t\t\tid: node.config.id,\n\t\t\twidth: node.config.width,\n\t\t\theight: node.config.height,\n\t\t\tgravity: node.config.gravity\n\t\t};\n\t\tif (!isUndefined(node.config.collapsed)) state.collapsed = node.config.collapsed;\n\t\tif (node.name === \"tabs\" || node.name === \"tabbar\") state.activeCell = node.getValue();\n\t\t\n\t\tif (children) {\n\t\t\tstate = [state];\n\t\t\tif (node._cells) {\n\t\t\t\tfor (var i = 0; i < node._cells.length; i++)\n\t\t\t\t\tstate = state.concat(this.getState(node._cells[i], children));\n\t\t\t}\n\t\t}\n\t\treturn state;\n\t},\n\tsetState:function(states) {\n\t\tif (!isArray(states)) states = [states];\n\t\n\t\tfor (var i = 0; i < states.length; i++) {\n\t\t\tvar state = states[i];\n\t\t\tvar node = $$(state.id);\n\t\t\tif (!node) continue;\n\t\n\t\t\tif (!isUndefined(state.collapsed)) node.define(\"collapsed\", state.collapsed);\n\t\t\tif (!isUndefined(state.activeCell)) node.setValue(state.activeCell, \"auto\");\n\t\n\t\t\tnode.define(\"width\", state.width);\n\t\t\tnode.define(\"height\", state.height);\n\t\t\tnode.define(\"gravity\", state.gravity);\n\t\t}\n\t\tvar top = $$(states[0].id);\n\t\tif (top) top.resize();\n\t}\n};\n\nready(function() {\n\tUIManager._enable();\n\n\tUIManager.addHotKey(\"enter\", function(view, ev){\n\t\tif (UIManager._composition)\n\t\t\treturn false;\n\t\tif (view && view.callEvent)\n\t\t\tview.callEvent(\"onEnter\", [ev]);\n\t\tif (view && view.editStop && view._in_edit_mode){\n\t\t\tview.editStop();\n\t\t\treturn true;\n\t\t} else if (view && view.touchable){\n\t\t\tconst form = view.getFormView();\n\t\t\tif (form && !view._skipSubmit)\n\t\t\t\tform.callEvent(\"onSubmit\",[view,ev]);\n\t\t}\n\t});\n\tUIManager.addHotKey(\"esc\", function(view, ev){\n\t\tif (view){\n\t\t\tif (view.editCancel && view._in_edit_mode){\n\t\t\t\tview.editCancel();\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst top = view.getTopParentView();\n\t\t\tif (top && top.setPosition){\n\t\t\t\tif (fullscreen._fullscreen == top)\n\t\t\t\t\tfullscreen.exit();\n\t\t\t\tif (top._editorMaster){\n\t\t\t\t\tconst master = $$(top._editorMaster);\n\t\t\t\t\tif (master.editCancel && master._in_edit_mode)\n\t\t\t\t\t\tmaster.editCancel();\n\t\t\t\t}\n\t\t\t\ttop._hide(ev);\n\t\t\t}\n\t\t}\n\t});\n\tUIManager.addHotKey(\"shift+tab\", UIManager._tab_logic);\n\tUIManager.addHotKey(\"tab\", UIManager._tab_logic);\n});\n\ndefine(\"UIManager\", UIManager);\n\nexport default UIManager;","import state from \"./state\";\n\nimport {_to_array} from \"../webix/helpers\";\nimport {event, _events_final_destructor} from \"../webix/htmlevents\";\nimport {callEvent} from \"../webix/customevents\";\n\nimport {ui} from \"../ui/core\";\nimport UIManager from \"../core/uimanager\";\n\n\nconst Destruction = {\n\t$init:function(){\n\t\t//wrap in object to simplify removing self-reference\n\t\t//submenu can trigger this handler two times, preserve a single destructor reference\n\t\tvar t = this._destructor_handler = this._destructor_handler || { obj: this};\n\n\t\t//register self in global list of destructors\n\t\tstate.destructors.push(t);\n\t},\n\t//will be called automatically on unload, can be called manually\n\t//simplifies job of GC\n\tdestructor:function(){\n\t\tvar config = this._settings;\n\n\t\tif (this._last_editor)\n\t\t\tthis.editCancel();\n\n\t\tif(this.callEvent)\n\t\t\tthis.callEvent(\"onDestruct\",[]);\n\n\t\t//destructor can be called only once\n\t\tthis.destructor=function(){};\n\t\t//remove self reference from global destructions collection\n\t\tthis._destructor_handler.obj = null;\n\n\t\t//destroy child and related cells\n\t\tif (this.getChildViews){\n\t\t\tvar cells = this.getChildViews();\n\t\t\tif (cells)\n\t\t\t\tfor (let i=0; i < cells.length; i++)\n\t\t\t\t\tcells[i].destructor();\n\n\t\t\tif (this._destroy_with_me)\n\t\t\t\tfor (let i=0; i < this._destroy_with_me.length; i++)\n\t\t\t\t\tthis._destroy_with_me[i].destructor();\n\t\t}\n\n\t\tdelete ui.views[config.id];\n\n\t\tif (config.$id){\n\t\t\tvar top = this.getTopParentView();\n\t\t\tif (top && top._destroy_child)\n\t\t\t\ttop._destroy_child(config.$id);\n\t\t}\n\n\t\t//html collection\n\t\tthis._htmlmap = null;\n\t\tthis._htmlrows = null;\n\t\tthis._html = null;\n\n\n\t\tif (this._contentobj) {\n\t\t\tthis._contentobj.innerHTML=\"\";\n\t\t\tthis._contentobj._htmlmap = null;\n\t\t}\n\n\t\t//removes view container\n\t\tif (this._viewobj&&this._viewobj.parentNode){\n\t\t\tthis._viewobj.parentNode.removeChild(this._viewobj);\n\t\t}\n\n\t\tif (this.data && this.data.destructor)\n\t\t\tthis.data.destructor();\n\n\t\tif (this.unbind)\n\t\t\tthis.unbind();\n\n\t\tthis.data = null;\n\t\tthis._parent_cell = null;\n\t\tthis._viewobj = this.$view = this._contentobj = this._dataobj = null;\n\t\tthis._evs_events = this._evs_handlers = this._evs_map = {};\n\n\t\t//remove focus from destructed view\n\t\tif (UIManager._view == this)\n\t\t\tUIManager._view = null;\n\n\t\tvar url = config.url;\n\t\tif (url && url.$proxy && url.release)\n\t\t\turl.release();\n\n\t\tthis.$scope = null;\n\t\t// this flag is checked in delay method\n\t\tthis.$destructed = true;\n\t}\n};\n//global list of destructors\nevent(window,\"unload\",function(){\n\tcallEvent(\"unload\", []);\n\tstate._final_destruction = true;\n\t\n\t//call all registered destructors\n\tfor (var i=0; i {\n\t\t\t\tconst config = test.config;\n\n\t\t\t\tfor (let key in search){\n\t\t\t\t\tif (config[key] != search[key])\n\t\t\t\t\t\treturn false; \n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t};\n\t\telse\n\t\t\tconfirm = search;\n\n\t\tif (all === \"self\" && confirm(this)) return this;\n\t\tconst results = all === \"all\" ? [] : false;\n\t\tconst direction = all === \"parent\" ? this._queryGoUp : this._queryGoDown;\n\n\t\tconst found = this._queryView(confirm, direction, results);\n\t\treturn all === \"all\" ? results : found;\n\t},\n\t_queryGoDown:function(node){\n\t\treturn node.getChildViews();\n\t},\n\t_queryGoUp:function(node){\n\t\tvar parent = node.getParentView();\n\t\treturn parent ? [parent] : [];\n\t},\n\t_queryView:function(confirm, next, all){\n\t\tvar kids = next(this);\n\t\tfor (var i =0; ix) x = sizes[0];\n\t\t//minHeight\n\t\tif (sizes[2]>y) y = sizes[2];\n\n\t\t//maxWidth rule\n\t\tif ((!fullscreen || this._settings.width) && x>sizes[1]) x = sizes[1];\n\t\t//maxHeight rule\n\t\tif ((!fullscreen || this._settings.height) && y>sizes[3]) y = sizes[3];\n\n\t\tthis.$setSize(x,y);\n\t\tif (state._responsive_exception){\n\t\t\tstate._responsive_exception = false;\n\t\t\tthis.adjust();\n\t\t}\n\t},\n\tresize:function(){\n\t\tif (state._child_sizing_active || state._freeze_resize || state._responsive_tinkery ) return;\n\n\t\tvar parent = this.getParentView();\n\t\tif (parent){\n\t\t\tif (parent.resizeChildren)\n\t\t\t\tparent.resizeChildren();\n\t\t\telse\n\t\t\t\tparent.resize();\n\t\t} else {\n\t\t\tthis.adjust();\n\t\t\tcallEvent(\"onResize\",[]);\n\t\t}\n\t}\n};\n\nconst view = protoUI(api, Settings, Destruction, BaseBind, UIExtension);\nexport default { api, view };","import {isUndefined} from \"../webix/helpers\";\nimport {debug_size_box} from \"../webix/debug\";\nimport {protoUI} from \"../ui/core\";\n\nimport base from \"./baseview\";\n\nconst api = {\n\tname:\"view\",\n\t$init:function(config){\n\t\tthis._set_inner(config);\n\t},\n\n\t//deside, will component use borders or not\n\t_set_inner:function(config){\n\t\tvar border_not_set = isUndefined(config.borderless);\n\t\tif (border_not_set && !this.setPosition && config.$topView){\n\t\t\tconfig.borderless = true;\n\t\t\tborder_not_set = false;\n\t\t}\n\n\t\tif ((border_not_set && this.defaults.borderless) || config.borderless){\n\t\t\t//button and custom borderless\n\t\t\tconfig._inner = { top:true, left:true, bottom:true, right:true };\n\t\t} else {\n\t\t\t//default borders\n\t\t\tif (!config._inner)\n\t\t\t\tconfig._inner = {};\n\t\t\tthis._contentobj.style.borderWidth=\"1px\";\n\t\t}\n\t},\n\n\t$getSize:function(dx, dy){\n\n\t\tvar _borders = this._settings._inner;\n\t\tif (_borders){\n\t\t\tdx += (_borders.left?0:1)+(_borders.right?0:1);\n\t\t\tdy += (_borders.top?0:1)+(_borders.bottom?0:1);\n\t\t}\n\t\t\n\t\tvar size = base.api.$getSize.call(this, dx, dy);\n\t\t\n\t\tif (DEBUG) debug_size_box(this, size, true);\n\t\treturn size;\n\t},\n\t$setSize:function(x,y){\n\t\tif (DEBUG) debug_size_box(this, [x,y]);\n\t\t\t\n\t\tvar _borders = this._settings._inner;\n\t\tif (_borders){\n\t\t\tx -= (_borders.left?0:1)+(_borders.right?0:1);\n\t\t\ty -= (_borders.top?0:1)+(_borders.bottom?0:1);\n\t\t}\n\t\t\t\n\t\treturn base.api.$setSize.call(this,x,y);\n\t}\n};\n\nconst view = protoUI(api, base.view);\nexport default { api, view };\n\n//not necessary anymore\n//preserving for backward compatibility\nview.call(-1);\n","import {create, remove} from \"../webix/html\";\nimport {isUndefined, toNode} from \"../webix/helpers\";\nimport {proto} from \"../ui/core\";\n\nconst Canvas = proto({\n\t$init:function(container){\n\t\tthis._canvas_labels = [];\n\t\tthis._canvas_series = (!isUndefined(container.series)?container.series:container.name);\n\t\tthis._obj = toNode(container.container||container);\n\t\tvar width = container.width*(window.devicePixelRatio||1);\n\t\tvar height = container.height*(window.devicePixelRatio||1);\n\t\tvar style = container.style||\"\";\n\t\tstyle += \";width:\"+container.width+\"px;height:\"+container.height+\"px;\";\n\t\tthis._prepareCanvas(container.name, style ,width, height, container.title);\n\t},\n\t_prepareCanvas:function(name,style,x,y, title){\n\t\t//canvas has the same size as master object\n\t\tthis._canvas = create(\"canvas\",{ title:title, width:x, height:y, canvas_id:name, style:(style||\"\")});\n\t\tthis._obj.appendChild(this._canvas);\n\t\treturn this._canvas;\n\t}, \n\tgetCanvas:function(context){\n\t\tvar ctx = (this._canvas||this._prepareCanvas(this._contentobj)).getContext(context||\"2d\");\n\t\tif(!this._webixDevicePixelRatio){\n\t\t\tthis._webixDevicePixelRatio = true;\n\t\t\tctx.scale(window.devicePixelRatio||1, window.devicePixelRatio||1);\n\t\t}\n\t\treturn ctx;\n\t},\n\t_resizeCanvas:function(x, y){\n\t\tif (this._canvas){\n\t\t\tthis._canvas.setAttribute(\"width\", x*(window.devicePixelRatio||1));\n\t\t\tthis._canvas.setAttribute(\"height\", y*(window.devicePixelRatio||1));\n\t\t\tthis._canvas.style.width = x+\"px\";\n\t\t\tthis._canvas.style.height = y+\"px\";\n\t\t\tthis._webixDevicePixelRatio = false;\n\t\t}\n\t},\n\trenderText:function(x,y,text,css,w){\n\t\tif (!text) return; //ignore empty text\n\t\tif (w) w = Math.max(w,0);\n\t\tif (y) y = Math.max(y,0);\n\t\tvar t = create(\"DIV\",{\n\t\t\t\"class\":\"webix_canvas_text\"+(css?(\" \"+css):\"\"),\n\t\t\t\"style\":\"left:\"+x+\"px; top:\"+y+\"px;\",\n\t\t\t\"aria-hidden\":\"true\"\n\t\t},text);\n\t\tthis._obj.appendChild(t);\n\t\tthis._canvas_labels.push(t); //destructor?\n\t\tif (w)\n\t\t\tt.style.width = w+\"px\";\n\t\treturn t;\n\t},\n\trenderTextAt:function(valign,align, x,y,t,c,w){\n\t\tvar text=this.renderText.call(this,x,y,t,c,w);\n\t\tif (text){\n\t\t\tlet size;\n\t\t\tif(document.body.contains(text))\n\t\t\t\tsize = { width: text.offsetWidth, height: text.offsetHeight };\n\t\t\telse{\n\t\t\t\t// inside window\n\t\t\t\tconst d = create(\"DIV\",{class: \"webix_chart\", style: \"visibility:hidden; position:absolute; top:0px; left:0px;\"}, \"\");\n\t\t\t\tconst parentNode = text.parentNode;\n\t\t\t\tdocument.body.appendChild(d);\n\t\t\t\td.appendChild(text);\n\t\t\t\tsize = { width: text.offsetWidth, height: text.offsetHeight };\n\t\t\t\tparentNode.appendChild(text);\n\t\t\t\tremove(d);\n\t\t\t}\n\n\t\t\tif (valign){\n\t\t\t\tif(valign == \"middle\")\n\t\t\t\t\ttext.style.top = parseInt(y-size.height/2,10) + \"px\";\n\t\t\t\telse\n\t\t\t\t\ttext.style.top = y-size.height + \"px\";\n\t\t\t}\n\t\t\tif (align){\n\t\t\t\tif(align == \"left\")\n\t\t\t\t\ttext.style.left = x-size.width + \"px\";\n\t\t\t\telse\n\t\t\t\t\ttext.style.left = parseInt(x-size.width/2,10) + \"px\";\n\t\t\t}\n\t\t}\n\t\treturn text;\n\t},\n\tclearCanvas:function(skipMap){\n\t\tvar areas=[];\n\n\t\tremove(this._canvas_labels);\n\t\tthis._canvas_labels = [];\n\n\t\tif (!skipMap&&this._obj._htmlmap){\n\n\t\t\t//areas that correspond this canvas layer\n\t\t\tareas = this._getMapAreas();\n\t\t\t//removes areas of this canvas\n\t\t\twhile(areas.length){\n\t\t\t\tareas[0].parentNode.removeChild(areas[0]);\n\t\t\t\tareas.splice(0,1);\n\t\t\t}\n\t\t\tareas = null;\n\n\t\t\t//removes _htmlmap object if all its child nodes are removed\n\t\t\tif(!this._obj._htmlmap.getElementsByTagName(\"AREA\").length){\n\t\t\t\tthis._obj._htmlmap.parentNode.removeChild(this._obj._htmlmap);\n\t\t\t\tthis._obj._htmlmap = null;\n\t\t\t}\n\t\t}\n\t\t//FF breaks, when we are using clear canvas and call clearRect without parameters\n\t\t//width|height are used insead of offsetWidth|offsetHeight for hidden canvas (series)\n\t\tthis.getCanvas().clearRect(0,0,\n\t\t\tthis._canvas.offsetWidth||Math.floor(this._canvas.width/(window.devicePixelRatio||1)), \n\t\t\tthis._canvas.offsetHeight||Math.floor(this._canvas.height/(window.devicePixelRatio||1))\n\t\t);\n\t},\n\ttoggleCanvas:function(){\n\t\tthis._toggleCanvas(this._canvas.style.display==\"none\");\n\t},\n\tshowCanvas:function(){\n\t\tthis._toggleCanvas(true);\n\t},\n\thideCanvas:function(){\n\t\tthis._toggleCanvas(false);\n\t},\n\t_toggleCanvas:function(show){\n\t\tvar areas, i;\n\n\t\tfor(i=0; i < this._canvas_labels.length;i++)\n\t\t\tthis._canvas_labels[i].style.display = (show?\"\":\"none\");\n\n\t\tif (this._obj._htmlmap){\n\t\t\tareas = this._getMapAreas();\n\t\t\tfor( i = 0; i < areas.length; i++){\n\t\t\t\tif(show)\n\t\t\t\t\tareas[i].removeAttribute(\"disabled\");\n\t\t\t\telse\n\t\t\t\t\tareas[i].setAttribute(\"disabled\",\"true\");\n\t\t\t}\n\t\t}\n\t\t//FF breaks, when we are using clear canvas and call clearRect without parameters\n\t\tthis._canvas.style.display = (show?\"\":\"none\");\n\t},\n\t_getMapAreas:function(){\n\t\tvar res = [], areas, i;\n\t\tareas = this._obj._htmlmap.getElementsByTagName(\"AREA\");\n\t\tfor(i = 0; i < areas.length; i++){\n\t\t\tif(areas[i].getAttribute(\"userdata\") == this._canvas_series){\n\t\t\t\tres.push(areas[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn res;\n\t}\n});\n\nexport default Canvas;","const skin = {\n\ttopLayout:\"space\",\n\t//bar in accordion\n\tbarHeight:44,\t\t\t//!!!Set the same in skin.less!!!\n\ttabbarHeight: 42,\n\tsidebarTitleHeight: 44,\n\trowHeight:36,\n\ttoolbarHeight:44,\n\tlistItemHeight:36,\t\t//list, grouplist, dataview, etc.\n\tinputHeight: 38,\n\tbuttonHeight: 38,\n\tinputPadding: 3,\n\tmenuHeight: 36,\n\tlabelTopHeight: 22,\n\tpropertyItemHeight: 28,\n\ttimelineItemHeight:70,\n\tunitHeaderHeight:36,\n\tfontSize: 14,\n\n\tinputSpacing: 4,\n\tborderWidth: 1,\n\n\tsliderHandleWidth: 14,\n\tsliderPadding: 10,\n\tsliderBorder: 1,\n\tvSliderPadding:15,\n\tvSliderHeight:100,\n\tswitchHeight:24,\n\tswitchWidth:50,\n\n\t//margin - distance between cells\n\tlayoutMargin:{ space:10, wide:10, clean:0, head:4, line:-1, toolbar:4, form:8, accordion: 2 },\n\t//padding - distance inside cell between cell border and cell content\n\tlayoutPadding:{ space:10, wide:0, clean:0, head:0, line:0, toolbar:2, form:17, accordion: 0 },\n\t//space between tabs in tabbar\n\ttabMargin: 0,\n\ttabOffset: 0,\n\ttabBottomOffset: 0,\n\ttabTopOffset:0,\n\ttabBorder: true,\n\n\tcustomCheckbox: true,\n\tcustomRadio: true,\n\tsidebarMarkAll: true,\n\tpopupNoPoint: true,\n\tborderlessPopup: true,\n\n\tpopupPadding: 0,\n\n\tdataPadding: 12,\n\n\tcalendarWeekHeaderHeight: 18,\n\tpadding:0,\n\taccordionType: \"accordion\",\n\n\toptionHeight: 32,\n\ttimelineColor:\"#1CA1C1\",\n\n\tbackColor:\"#FFFFFF\",\n\tdataBorderColor:\"#EDEFF0\",\n\n\t//colorboard\n\tcolorPadding: 4\n};\n\nexport default skin;\n","const skin = {\n\ttopLayout:\"space\",\n\t//bar in accordion\n\tbarHeight: 46,\t\t\t//!!!Set the same in skin.less!!!\n\ttabbarHeight: 44,\n\tsidebarTitleHeight: 46,\n\trowHeight:36,\n\ttoolbarHeight:46,\n\tlistItemHeight:36,\t\t//list, grouplist, dataview, etc.\n\tinputHeight: 38,\n\tbuttonHeight: 38,\n\tinputPadding: 3,\n\tmenuHeight: 36,\n\tlabelTopHeight: 22,\n\tpropertyItemHeight: 28,\n\ttimelineItemHeight:64,\n\tunitHeaderHeight:36,\n\tfontSize: 14,\n\n\tinputSpacing: 4,\n\tborderWidth: 1,\n\n\tsliderHandleWidth: 14,\n\tsliderPadding: 10,\n\tsliderBorder: 1,\n\tvSliderPadding:15,\n\tvSliderHeight:100,\n\tswitchHeight:24,\n\tswitchWidth:50,\n\n\t//margin - distance between cells\n\tlayoutMargin:{ space:10, wide:10, clean:0, head:4, line:-1, toolbar:4, form:8, accordion: 2 },\n\t//padding - distance inside cell between cell border and cell content\n\tlayoutPadding:{ space:10, wide:0, clean:0, head:0, line:0, toolbar:3, form:17, accordion: 0 },\n\t//space between tabs in tabbar\n\ttabMargin: 0,\n\ttabOffset: 0,\n\ttabBottomOffset: 0,\n\ttabTopOffset:0,\n\ttabBorder: true,\n\n\tcustomCheckbox: true,\n\tcustomRadio: true,\n\tsidebarMarkAll: true,\n\tpopupNoPoint: true,\n\tborderlessPopup: true,\n\n\tpopupPadding: 0,\n\n\tdataPadding: 12,\n\n\tcalendarWeekHeaderHeight: 18,\n\tpadding:0,\n\taccordionType: \"accordion\",\n\n\toptionHeight: 32,\n\ttimelineColor:\"#37A9EF\",\n\n\tbackColor:\"#FFFFFF\",\n\tdataBorderColor:\"#E6E6E6\",\n\n\t//colorboard\n\tcolorPadding: 4\n};\n\nexport default skin;\n","import env from \"../webix/env\";\nimport ready from \"../webix/ready\";\n\nimport {event} from \"../webix/htmlevents\";\nimport {callEvent} from \"../webix/customevents\";\nimport {preventEvent, removeCss, addCss, addStyle} from \"../webix/html\";\n\n//late binding\nimport {$$} from \"../ui/core\";\n\nconst Touch = {\n\tconfig:{\n\t\tlongTouchDelay:700,\n\t\tscrollDelay:150,\n\t\tgravity:500,\n\t\tdeltaStep:10,\n\t\tspeed:\"0ms\",\n\t\tfinish:1000,\n\t\telastic:true\n\t},\n\tlimit:function(value){\n\t\tTouch._limited = value !== false;\t\n\t},\n\tdisable:function(){\n\t\tTouch._disabled = true;\n\t},\n\tenable:function(){\n\t\tTouch._disabled = false;\n\t},\n\t$init:function(){\n\t\tTouch.$init = function(){};\n\n\t\tevent(document.body, env.touch.down,\tTouch._touchstart, {passive:false});\n\t\tevent(document.body, env.touch.move, \tTouch._touchmove, {passive:false});\n\t\tevent(document, env.touch.up, \tTouch._touchend);\n\n\t\tevent(document.body,\"dragstart\",function(e){\n\t\t\tif(Touch._disabled || Touch._limited) return;\n\t\t\treturn preventEvent(e);\n\t\t});\n\n\t\tTouch._clear_artefacts();\n\t\tTouch._scroll = [null, null];\n\t\tTouch.$active = true;\n\t},\n\t_clear_artefacts:function(){\n\t\tTouch._start_context = Touch._current_context = Touch._prev_context = Touch._scroll_context = null;\n\t\tTouch._scroll_mode = Touch._scroll_node = Touch._scroll_stat = Touch._long_touched = null;\n\t\tTouch._delta = \t{ _x_moment:0, _y_moment:0, _time:0 };\n\n\t\tif (Touch._css_button_remove){\n\t\t\tremoveCss(Touch._css_button_remove,\"webix_touch\");\n\t\t\tTouch._css_button_remove = null;\n\t\t}\n\t\t\n\t\twindow.clearTimeout(Touch._long_touch_timer);\n\t\tTouch._was_not_moved = true;\n\t\tTouch._axis_x = true;\n\t\tTouch._axis_y = true;\n\t\tif (!Touch._active_transion)\n\t\t\tTouch._scroll_end();\n\t},\n\t_touchend:function(e){\n\t\tif (Touch._start_context) {\n\t\t\tif (!Touch._scroll_mode) {\n\t\t\t\tif (!Touch._long_touched && !(Touch._axis_x * Touch._axis_y)) {\n\t\t\t\t\tconst delta = Touch._get_delta(e);\n\t\t\t\t\tif (!Touch._axis_x && delta._x/(delta._y||1) > 4) {\n\t\t\t\t\t\tTouch._translate_event(\"onSwipeX\");\n\t\t\t\t\t} else if (!Touch._axis_y && delta._y/(delta._x||1) > 4) {\n\t\t\t\t\t\tTouch._translate_event(\"onSwipeY\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlet finish = Touch.config.finish;\n\t\t\t\tconst temp = Touch._get_matrix(Touch._scroll_node);\n\t\t\t\tconst x = temp.e;\n\t\t\t\tconst y = temp.f;\n\n\t\t\t\tconst delta = Touch._get_delta(e);\n\t\t\t\tconst view = $$(Touch._scroll_node);\n\n\t\t\t\tconst gravity = (view && view.$scroll) ? view.$scroll.gravity : Touch.config.gravity;\n\t\t\t\tif (delta._time) {\n\t\t\t\t\tconst nx = x + gravity * delta._x_moment / delta._time;\n\t\t\t\t\tconst ny = y + gravity * delta._y_moment / delta._time;\n\n\t\t\t\t\tconst cnx = Touch._scroll[0] ? Touch._correct_minmax(nx, false, false, Touch._scroll_stat.dx, Touch._scroll_stat.px) : x;\n\t\t\t\t\tconst cny = Touch._scroll[1] ? Touch._correct_minmax(ny, false, false, Touch._scroll_stat.dy, Touch._scroll_stat.py) : y;\n\n\t\t\t\t\tconst size = Math.max(Math.abs(cnx - x), Math.abs(cny - y));\n\t\t\t\t\tif (size < 150)\n\t\t\t\t\t\tfinish = finish * size / 150;\n\n\t\t\t\t\tif (cnx != x || cny != y)\n\t\t\t\t\t\tfinish = Math.round(finish * Math.max((cnx - x) / (nx - x), (cny - y) / (ny - y)));\n\n\t\t\t\t\tconst result = {e: cnx, f: cny};\n\t\t\t\t\tif (view && view.adjustScroll)\n\t\t\t\t\t\tview.adjustScroll(result);\n\n\t\t\t\t\tfinish = Math.min(Touch.config.finish, Math.max(100, finish));\n\t\t\t\t\tif (x != result.e || y != result.f) {\n\t\t\t\t\t\tTouch._set_matrix(Touch._scroll_node, result.e, result.f, finish + \"ms\");\n\t\t\t\t\t\tif (Touch._scroll_master)\n\t\t\t\t\t\t\tTouch._scroll_master._sync_scroll(result.e, result.f, finish + \"ms\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tTouch._scroll_end();\n\t\t\t\t\t}\n\t\t\t\t} else\n\t\t\t\t\tTouch._scroll_end();\n\t\t\t}\n\t\t\tTouch._translate_event(\"onTouchEnd\");\n\t\t\tTouch._clear_artefacts();\n\t\t}\n\t},\n\t_touchmove:function(e){\n\t\tif (!Touch._scroll_context || !Touch._start_context) return;\n\n\t\tvar\tdelta = Touch._get_delta(e);\n\t\tTouch._translate_event(\"onTouchMove\");\n\n\t\tif (Touch._scroll_mode){\n\t\t\tTouch._set_scroll_pos();\n\t\t} else {\n\t\t\tTouch._axis_x = Touch._axis_check(delta._x, \"x\", Touch._axis_x);\n\t\t\tTouch._axis_y = Touch._axis_check(delta._y, \"y\", Touch._axis_y);\n\t\t\tif (Touch._scroll_mode){\n\t\t\t\tvar view = Touch._get_event_view(\"onBeforeScroll\", true);\n\t\t\t\tif (view){\n\t\t\t\t\tvar data = {};\n\t\t\t\t\tview.callEvent(\"onBeforeScroll\",[data]);\n\t\t\t\t\tif (data.update){\n\t\t\t\t\t\tTouch.config.speed = data.speed;\n\t\t\t\t\t\tTouch.config.scale = data.scale;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tTouch._init_scroller(); //apply scrolling\n\t\t\t} else {\n\t\t\t\tconst state = Touch._is_scroll();\n\t\t\t\tconst view = $$(state && state[0]);\t\t// support subviews\n\t\t\t\tif (view && view.$hasYScroll && view.$hasYScroll() && e.cancelable){\n\t\t\t\t\treturn preventEvent(e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (Touch._scroll_mode && e.cancelable)\n\t\t\treturn preventEvent(e);\n\t},\n\t_set_scroll_pos:function(){\n\t\tif (!Touch._scroll_node) return;\n\t\tvar temp = Touch._get_matrix(Touch._scroll_node);\n\t\tvar prev = Touch._prev_context || Touch._start_context;\n\n\t\tvar view = $$(Touch._scroll_node);\n\t\tvar elastic = (view && view.$scroll) ? view.$scroll.elastic : Touch.config.elastic;\n\n\t\tif (Touch._scroll[0])\n\t\t\ttemp.e = Touch._correct_minmax( temp.e - prev.x + Touch._current_context.x , elastic, temp.e, Touch._scroll_stat.dx, Touch._scroll_stat.px);\n\t\tif (Touch._scroll[1])\n\t\t\ttemp.f = Touch._correct_minmax( temp.f - prev.y + Touch._current_context.y , elastic, temp.f, Touch._scroll_stat.dy, Touch._scroll_stat.py);\n\n\t\tTouch._set_matrix(Touch._scroll_node, temp.e, temp.f, \"0ms\");\n\t\tif (Touch._scroll_master)\n\t\t\tTouch._scroll_master._sync_scroll(temp.e, temp.f, \"0ms\");\n\t},\n\tscrollTo:function(node, x, y, speed){\n\t\tTouch._set_matrix(node,x,y,speed);\n\t},\n\t_set_matrix:function(node, xv, yv, speed){\n\t\tif (!speed){\n\t\t\tnode.style[env.transform] = \"\";\n\t\t\treturn;\n\t\t}\n\n\t\tTouch._active_transion = true;\n\t\tif (node){\n\t\t\tvar trans = Touch.config.translate || env.translate;\n\t\t\tnode.style[env.transform] = trans+\"(\"+Math.round(xv)+\"px, \"+Math.round(yv)+\"px\"+((trans==\"translate3d\")?\", 0\":\"\")+\")\";\n\t\t\tnode.style[env.transitionDuration] = speed;\n\t\t}\n\t},\n\t_get_matrix:function(node){\n\t\tvar matrix = window.getComputedStyle(node)[env.transform];\n\t\tvar tmatrix;\n\n\t\tif (matrix == \"none\")\n\t\t\ttmatrix = {e:0, f:0};\n\t\telse {\n\t\t\tif(window.WebKitCSSMatrix)\n\t\t\t\t/* global WebKitCSSMatrix */\n\t\t\t\ttmatrix = new WebKitCSSMatrix(matrix);\n\t\t\telse {\n\t\t\t\t// matrix(1, 0, 0, 1, 0, 0) --> 1, 0, 0, 1, 0, 0\n\t\t\t\tvar _tmatrix = matrix.replace(/(matrix\\()(.*)(\\))/gi, \"$2\");\n\t\t\t\t// 1, 0, 0, 1, 0, 0 --> 1,0,0,1,0,0\n\t\t\t\t_tmatrix = _tmatrix.replace(/\\s/gi, \"\");\n\t\t\t\t_tmatrix = _tmatrix.split(\",\");\n\n\t\t\t\ttmatrix = {};\n\t\t\t\tvar tkey = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"];\n\t\t\t\tfor(var i=0; i dx) return 0;\n\n\t\tconst delta = Math.abs(value-current);\n\t\tconst sign = delta/(value-current);\n\t\tif (value > 0)\n\t\t\treturn allow ? (current + sign*Math.sqrt(delta)) : 0;\n\n\t\tconst max = dx - px;\n\t\tif (max + value < 0)\n\t\t\treturn allow ? (current + sign*Math.sqrt(delta)) : -max;\n\n\t\treturn value;\n\t},\t\n\t_init_scroll_node:function(node){\n\t\tif (!node.scroll_enabled){\n\t\t\tnode.scroll_enabled = true;\n\t\t\tnode.parentNode.style.position = \"relative\";\n\t\t\tnode.style.cssText += \"transition:transform; user-select:none; transform-style:flat;\";\n\t\t\tnode.addEventListener(env.transitionEnd, function(e){\n\t\t\t\tif (e.target === this) Touch._scroll_end.call(this);\n\t\t\t}, false);\n\t\t}\n\t},\n\t_init_scroller:function(){\n\t\tif (Touch._scroll_mode.indexOf(\"x\") !== -1) Touch._scroll[0] = true;\n\t\tif (Touch._scroll_mode.indexOf(\"y\") !== -1) Touch._scroll[1] = true;\n\n\t\tif (Touch._scroll[0] || Touch._scroll[1])\n\t\t\tTouch._scroll[2] = Touch._scroll_node;\n\n\t\tTouch._init_scroll_node(Touch._scroll_node);\n\t},\n\t_axis_check:function(value, mode, old){\n\t\tif (value > Touch.config.deltaStep){\n\t\t\tif (Touch._was_not_moved){\n\t\t\t\tTouch._long_move(mode);\n\t\t\t\tTouch._locate(mode);\n\t\t\t\tif ((Touch._scroll_mode||\"\").indexOf(mode) == -1) Touch._scroll_mode = \"\";\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\treturn old;\n\t},\n\t_scroll_end:function(){\n\t\t//sending event to the owner of the scroll only\n\t\tvar result,state,view;\n\t\tview = $$(Touch._scroll_node||this);\n\t\tif (view){\n\t\t\tif (Touch._scroll_node)\n\t\t\t\tresult = Touch._get_matrix(Touch._scroll_node);\n\t\t\telse if(view.getScrollState){\n\t\t\t\tstate = view.getScrollState();\n\t\t\t\tresult = {e:-state.x, f:-state.y};\n\t\t\t}\n\t\t\tcallEvent(\"onAfterScroll\", [result]);\n\t\t\tif (view.callEvent)\n\t\t\t\tview.callEvent(\"onAfterScroll\",[result]);\n\t\t}\n\t\tif (!Touch._scroll_mode)\n\t\t\tTouch._scroll = [null, null];\n\t\tTouch._active_transion = false;\n\t},\n\t_long_move:function(){\n\t\twindow.clearTimeout(Touch._long_touch_timer);\n\t\tTouch._was_not_moved = false;\t\n\t},\t\n\t_stop_old_scroll:function(e){\n\t\tif (Touch._scroll[2]){\n\t\t\tTouch._stop_scroll(e, (Touch._scroll[0] ? \"x\" : \"y\"));\n\t\t} else\n\t\t\treturn true;\n\t},\n\t_touchstart :function(e){\n\t\tif (Touch._disabled) return;\n\n\t\tTouch._long_touched = null;\n\t\tTouch._scroll_context = Touch._start_context = env.touch.context(e);\n\n\t\tif (Touch._limited && !Touch._is_scroll())\n\t\t\tTouch._scroll_context = null;\n\n\t\tTouch._translate_event(\"onTouchStart\");\n\n\t\tif (Touch._stop_old_scroll(e))\n\t\t\tTouch._long_touch_timer = window.setTimeout(Touch._long_touch, Touch.config.longTouchDelay);\n\n\t\tconst element = $$(e);\n\t\tif (element && element.touchable && (!e.target.className || e.target.className.indexOf(\"webix_view\") !== 0)){\n\t\t\tTouch._css_button_remove = element.getNode(e);\n\t\t\taddCss(Touch._css_button_remove,\"webix_touch\");\n\t\t}\n\t},\n\t_long_touch:function(){\n\t\tif(Touch._start_context){\n\t\t\tTouch._long_touched = true;\n\t\t\tTouch._translate_event(\"onLongTouch\");\n\t\t\tcallEvent(\"onClick\", [Touch._start_context]);\n\t\t}\n\t},\n\t_stop_scroll:function(e, stop_mode){\n\t\tTouch._locate(stop_mode);\n\t\tif (Touch._scroll[2]){\n\t\t\tvar view = Touch._get_event_view(\"onBeforeScroll\", true);\n\t\t\tif (view)\n\t\t\t\tview.callEvent(\"onBeforeScroll\", [Touch._start_context,Touch._current_context]);\n\n\t\t\tif (!Touch._scroll_node || Touch._scroll_node.parentNode !== Touch._scroll[2].parentNode){\n\t\t\t\tTouch._clear_artefacts();\n\t\t\t\tTouch._scroll_end();\n\t\t\t\tTouch._start_context = env.touch.context(e);\n\t\t\t}\n\t\t}\n\t\tTouch._touchmove(e);\n\t},\t\n\t_get_delta:function(e){\n\t\tTouch._prev_context = Touch._current_context;\n\t\tTouch._current_context = env.touch.context(e);\n\n\t\tTouch._delta._x = Math.abs(Touch._start_context.x - Touch._current_context.x);\n\t\tTouch._delta._y = Math.abs(Touch._start_context.y - Touch._current_context.y);\n\n\t\tif (Touch._prev_context){\n\t\t\tif (Touch._current_context.time - Touch._prev_context.time < Touch.config.scrollDelay){\n\t\t\t\tTouch._delta._x_moment = Touch._delta._x_moment/1.3+Touch._current_context.x - Touch._prev_context.x;\n\t\t\t\tTouch._delta._y_moment = Touch._delta._y_moment/1.3+Touch._current_context.y - Touch._prev_context.y;\n\t\t\t} else {\n\t\t\t\tTouch._delta._y_moment = Touch._delta._x_moment = 0;\n\t\t\t}\n\t\t\tTouch._delta._time = Touch._delta._time/1.3+(Touch._current_context.time - Touch._prev_context.time);\n\t\t}\n\n\t\treturn Touch._delta;\n\t},\n\t_get_sizes:function(node){\n\t\treturn {\n\t\t\tdx:node.offsetWidth,\n\t\t\tdy:node.offsetHeight,\n\t\t\tpx:node.parentNode.offsetWidth,\n\t\t\tpy:node.parentNode.offsetHeight\n\t\t};\n\t},\n\t_is_scroll:function(locate_mode){\n\t\tvar node = Touch._start_context.target;\n\t\twhile(node && node.tagName != \"BODY\"){\n\t\t\tif (node.getAttribute){\n\t\t\t\tvar mode = node.getAttribute(\"touch_scroll\");\n\t\t\t\tif (mode && (!locate_mode || mode.indexOf(locate_mode) != -1))\n\t\t\t\t\treturn [node, mode];\n\t\t\t}\n\t\t\tnode = node.parentNode;\n\t\t}\n\t\treturn null;\n\t},\n\t_locate:function(locate_mode){\n\t\tvar state = Touch._is_scroll(locate_mode);\n\t\tif (state){\n\t\t\tTouch._scroll_mode = state[1];\n\t\t\tTouch._scroll_node = state[0];\n\t\t\tTouch._scroll_stat = Touch._get_sizes(state[0]);\n\t\t}\n\t\treturn state;\n\t},\n\t_translate_event:function(name){\n\t\tcallEvent(name, [Touch._start_context,Touch._current_context]);\n\t\tvar view = Touch._get_event_view(name);\n\t\tif (view)\n\t\t\tview.callEvent(name, [Touch._start_context,Touch._current_context]);\n\t},\n\t_get_event_view:function(name, active){\n\t\tvar view = $$(active ? Touch._scroll_node : Touch._start_context);\n\t\tif(!view) return null;\n\n\t\twhile (view){\n\t\t\tif (view.hasEvent && view.hasEvent(name))\n\t\t\t\treturn view;\n\t\t\tview = view.getParentView();\n\t\t}\n\n\t\treturn null;\n\t},\t\n\t_get_context:function(e){\n\t\tif (!e.touches[0]) {\n\t\t\tvar temp = Touch._current_context;\n\t\t\ttemp.time = new Date();\n\t\t\treturn temp;\n\t\t}\n\n\t\treturn {\n\t\t\ttarget:e.target,\n\t\t\tx:e.touches[0].pageX,\n\t\t\ty:e.touches[0].pageY,\n\t\t\ttime:new Date()\n\t\t};\n\t},\n\t_get_context_m:function(e){\n\t\treturn {\n\t\t\ttarget:e.target,\n\t\t\tx:e.pageX,\n\t\t\ty:e.pageY,\n\t\t\ttime:new Date()\n\t\t};\n\t}\n};\n\nfunction touchInit(){\n\tif (env.touch){\n\t\tTouch.$init();\n\n\t\t//not full screen mode\n\t\tif (document.body.className.indexOf(\"webix_full_screen\") === -1)\n\t\t\tTouch.limit(true);\n\n\t\tif (env.isSafari && CSS.supports(\"-webkit-overflow-scrolling: touch\"))\n\t\t\taddStyle(\".webix_view{ -webkit-overflow-scrolling:touch; } .webix_scroll_cont{ transform:translateZ(0px); }\");\n\t}\n}\n\nready(touchInit);\n\nenv.mouse = {\n\tdown: \"mousedown\",\n\tmove: \"mousemove\",\n\tup: \"mouseup\",\n\tcontext: Touch._get_context_m\n};\n\nenv.touch = env.touch && {\n\tdown: \"touchstart\",\n\tmove: \"touchmove\",\n\tup: \"touchend\",\n\tcontext: Touch._get_context\n};\n\t\n\nexport default Touch;","import {preventEvent, addCss, removeCss, pos as getPos, remove} from \"../webix/html\";\nimport env from \"../webix/env\";\nimport Touch from \"../core/touch\";\nimport {zIndex} from \"../ui/helpers\";\nimport {_to_array, toNode} from \"../webix/helpers\";\nimport {_event, event, eventRemove} from \"../webix/htmlevents\";\nimport {attachEvent, callEvent} from \"../webix/customevents\";\n\n\n/*\n\tBehavior:DND - low-level dnd handling\n\t@export\n\t\tgetContext\n\t\taddDrop\n\t\taddDrag\n\t\t\n\tDND master can define next handlers\n\t\tonCreateDrag\n\t\tonDragIng\n\t\tonDragOut\n\t\tonDrag\n\t\tonDrop\n\tall are optional\n*/\n\nconst DragControl ={\n\t//has of known dnd masters\n\t_drag_masters : _to_array([\"dummy\"]),\n\t/*\n\t\tregister drop area\n\t\t@param node \t\t\thtml node or ID\n\t\t@param ctrl \t\t\toptions dnd master\n\t\t@param master_mode \t\ttrue if you have complex drag-area rules\n\t*/\n\taddDrop:function(node,ctrl,master_mode){\n\t\tnode = toNode(node);\n\t\tnode.webix_drop=this._getCtrl(ctrl);\n\t\tif (master_mode) node.webix_master=true;\n\t},\n\t//return index of master in collection\n\t//it done in such way to prevent dnd master duplication\n\t//probably useless, used only by addDrop and addDrag methods\n\t_getCtrl:function(ctrl){\n\t\tctrl = ctrl||DragControl;\n\t\tvar index = this._drag_masters.find(ctrl);\n\t\tif (index<0){\n\t\t\tindex = this._drag_masters.length;\n\t\t\tthis._drag_masters.push(ctrl);\n\t\t\tif (ctrl.attachEvent)\n\t\t\t\tctrl.attachEvent(\"onDestruct\", () => DragControl.unlink(ctrl));\n\t\t}\n\t\treturn index;\n\t},\n\tunlink(ctrl){\n\t\tvar index = this._drag_masters.find(ctrl);\n\t\tif (index > -1){\n\t\t\t// if active view was destroyed, stop dnd\n\t\t\tif (DragControl._active && DragControl._active.webix_drag == index)\n\t\t\t\tDragControl._stopDrag();\n\t\t\t// if last target was destroyed, reset it and continue dnd\n\t\t\tif (DragControl._last && DragControl._last.webix_drop == index)\n\t\t\t\tDragControl._last = null;\n\n\t\t\tthis._drag_masters[index] = null;\n\t\t}\n\t},\n\t_createTouchDrag: function(e, pointer){\n\t\tconst dragCtrl = DragControl;\n\t\tconst master = this._getActiveDragMaster();\n\t\t// for data items only\n\t\tif (master && master.$longTouchLimit){\n\t\t\tif (!dragCtrl._html && !dragCtrl.createDrag(e, pointer)) return;\n\t\t\te.longtouch_drag = true;\n\n\t\t\tconst pos = getPos(e);\n\t\t\tconst customPos = dragCtrl.$dragPos(pos, e);\n\n\t\t\tconst ctx = dragCtrl._drag_context;\n\t\t\tdragCtrl._html.style.top= pos.y+dragCtrl.top+(customPos||!ctx.y_offset?0:ctx.y_offset)+\"px\";\n\t\t\tdragCtrl._html.style.left= pos.x+dragCtrl.left+(customPos||!ctx.x_offset?0:ctx.x_offset)+\"px\";\n\t\t}\n\t},\n\t/*\n\t\tregister drag area\n\t\t@param node \thtml node or ID\n\t\t@param ctrl \toptions dnd master\n\t*/\n\taddDrag:function(node,ctrl){\n\t\tnode = toNode(node);\n\t\tnode.webix_drag = this._getCtrl(ctrl);\n\t\t_event(node,\"dragstart\",preventEvent);\n\t\t_event(node, env.mouse.down, e => this._preStart(e, node, \"mouse\"));\n\t\tif (env.touch)\n\t\t\t_event(node, env.touch.down, e => this._preStart(e, node, \"touch\"));\n\t},\n\t//logic of drag - start, we are not creating drag immediately, instead of that we hears mouse moving\n\t_preStart:function(e, node, pointer){\n\t\tif (DragControl._active){\n\t\t\t//if we have nested drag areas, use the top one and ignore the inner one\n\t\t\tif (DragControl._saved_event == e) return;\n\t\t\tDragControl._preStartFalse(e);\n\t\t\tDragControl.destroyDrag(e);\n\t\t}\n\t\tDragControl._active = node;\n\n\t\tconst evobj = env[pointer].context(e);\n\t\tDragControl._start_pos = evobj;\n\t\tDragControl._saved_event = e;\n\n\t\tconst passive = (pointer === \"touch\") ? { passive:false } : null;\n\t\tDragControl._webix_drag_mm = event(document.body, env[pointer].move, e => DragControl._startDrag(e, pointer), passive);\n\t\tDragControl._webix_drag_mu = event(document, env[pointer].up, DragControl._preStartFalse);\n\n\t\t//need to run here, or will not work in IE\n\t\taddCss(document.body,\"webix_noselect\", 1);\n\t},\n\t//if mouse was released before moving - this is not a dnd, remove event handlers\n\t_preStartFalse:function(e){\n\t\tDragControl._clean_dom_after_drag();\n\t\tDragControl._touch_animation = !e.cancelable;\n\t},\n\t//mouse was moved without button released - dnd started, update event handlers\n\t_startDrag:function(e, pointer){\n\t\tconst touch = (pointer === \"touch\");\n\n\t\t// mouse: allow dnd only on left click\n\t\tif(!touch && DragControl._saved_event.button)\n\t\t\treturn;\n\n\t\t// check touch scroll animation\n\t\tDragControl._touch_animation = !e.cancelable;\n\t\tif (touch && DragControl._touch_animation){\n\t\t\tDragControl._clean_dom_after_drag();\n\t\t\treturn DragControl.destroyDrag(e);\n\t\t}\n\n\t\t//prevent unwanted dnd\n\t\tvar pos = env[pointer].context(e);\n\t\tvar master = DragControl._getActiveDragMaster();\n\n\t\t// only long-touched elements can be dragged\n\t\tvar longTouchLimit = (touch && master && master.$longTouchLimit && !Touch._long_touched);\n\t\tif (longTouchLimit || Math.abs(pos.x-DragControl._start_pos.x)<5 && Math.abs(pos.y-DragControl._start_pos.y)<5)\n\t\t\treturn;\n\n\t\tif (!DragControl._html && !DragControl.createDrag(DragControl._saved_event, pointer))\n\t\t\treturn DragControl._clean_dom_after_drag();\n\t\tDragControl._clean_dom_after_drag(true);\n\n\t\tDragControl.sendSignal(\"start\"); //useless for now\n\n\t\tif (touch) {\n\t\t\t// important: for touch events use e.target as EventTarget\n\t\t\tDragControl._webix_drag_mm = event(e.target, env[pointer].move, e => DragControl._moveDrag(e, pointer), { passive:false });\n\t\t\tDragControl._webix_drag_mu = event(e.target, env[pointer].up, DragControl._stopDrag);\n\t\t} else {\n\t\t\tDragControl._webix_drag_mm = event(document.body, env[pointer].move, e => DragControl._moveDrag(e, pointer));\n\t\t\tDragControl._webix_drag_mu = event(document, env[pointer].up, DragControl._stopDrag);\n\t\t}\n\t\tDragControl._moveDrag(e, pointer, true);\n\t},\n\t//mouse was released while dnd is active - process target\n\t_stopDrag:function(e){\n\t\tDragControl._clean_dom_after_drag();\n\t\tDragControl._saved_event = null;\n\n\t\tif (DragControl._last && e){\t//if some drop target was confirmed\n\t\t\tDragControl.$drop(DragControl._active, DragControl._last, e);\n\t\t\tDragControl.$dragOut(DragControl._active, DragControl._last, null, e);\n\t\t}\n\t\tDragControl.destroyDrag(e);\n\t\tDragControl.sendSignal(\"stop\");\t//useless for now\n\t},\n\t_clean_dom_after_drag:function(still_drag){\n\t\tthis._webix_drag_mm = eventRemove(this._webix_drag_mm);\n\t\tthis._webix_drag_mu = eventRemove(this._webix_drag_mu);\n\t\tif (!still_drag)\n\t\t\tremoveCss(document.body,\"webix_noselect\");\n\t},\n\t//dnd is active and mouse position was changed\n\t_moveDrag:function(e, pointer, first){\n\t\tvar dragCtrl = DragControl;\n\t\tvar pos = getPos(e);\n\n\t\t//give possibility to customize drag position\n\t\tvar customPos = dragCtrl.$dragPos(pos, e);\n\t\t//adjust drag marker position\n\t\tvar ctx = dragCtrl._drag_context;\n\t\tdragCtrl._html.style.top=pos.y+dragCtrl.top+(customPos||!ctx.y_offset?0:ctx.y_offset) +\"px\";\n\t\tdragCtrl._html.style.left=pos.x+dragCtrl.left+(customPos||!ctx.x_offset?0:ctx.x_offset)+\"px\";\n\n\t\t// check landing at least once\n\t\tif (first) dragCtrl._skip = false;\n\n\t\tif (dragCtrl._skip)\n\t\t\tdragCtrl._skip = false;\n\t\telse {\n\t\t\tlet evobj = e;\n\t\t\tif (pointer === \"touch\"){\n\t\t\t\tconst scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;\n\t\t\t\tconst scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;\n\n\t\t\t\tconst context = env[pointer].context(e);\n\t\t\t\tconst target = document.elementFromPoint(context.x - scrollLeft, context.y - scrollTop);\n\t\t\t\tevobj = new Proxy(e, {\n\t\t\t\t\tget: function(obj, prop){\n\t\t\t\t\t\tif (prop === \"target\"){\n\t\t\t\t\t\t\treturn target;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst res = obj[prop];\n\t\t\t\t\t\tif (typeof res === \"function\"){\n\t\t\t\t\t\t\treturn res.bind(e);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn res;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\tdragCtrl._checkLand((evobj.target), evobj);\n\t\t}\n\t\t\n\t\treturn preventEvent(e);\n\t},\n\t//check if item under mouse can be used as drop landing\n\t_checkLand:function(node,e){\n\t\twhile (node && node.tagName!=\"BODY\"){\n\t\t\tif (node.webix_drop){\t//if drop area registered\n\t\t\t\tif (this._last && (this._last!=node || node.webix_master))\t//if this area with complex dnd master\n\t\t\t\t\tthis.$dragOut(this._active,this._last,node,e);\t\t\t//inform master about possible mouse-out\n\t\t\t\tif (!this._last || this._last!=node || node.webix_master){\t//if this is new are or area with complex dnd master\n\t\t\t\t\tthis._last=null;\t\t\t\t\t\t\t\t\t\t//inform master about possible mouse-in\n\t\t\t\t\tthis._landing=this.$dragIn(DragControl._active,node,e);\n\t\t\t\t\tif (this._landing)\t//landing was rejected\n\t\t\t\t\t\tthis._last=node;\n\t\t\t\t\treturn;\t\t\t\t\n\t\t\t\t} \n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnode=node.parentNode;\n\t\t}\n\t\tif (this._last)\t//mouse was moved out of previous landing, and without finding new one \n\t\t\tthis._last = this._landing = this.$dragOut(this._active,this._last,null,e);\n\t},\n\t//mostly useless for now, can be used to add cross-frame dnd\n\tsendSignal:function(signal){\n\t\tDragControl.active=(signal==\"start\");\n\t\tcallEvent(\"onDragMode\", [signal]);\n\t},\n\t\n\t//return master for html area\n\tgetMaster:function(t){\n\t\treturn this._drag_masters[t.webix_drag||t.webix_drop];\n\t},\n\t//return dhd-context object\n\tgetContext:function(){\n\t\treturn this._drag_context;\n\t},\n\tgetNode:function(){\n\t\treturn this._html;\n\t},\n\t//called when dnd is initiated, must create drag representation\n\tcreateDrag:function(e, pointer){\n\t\tvar a = DragControl._active;\n\n\t\tDragControl._drag_context = {};\n\t\tvar master = this._drag_masters[a.webix_drag];\n\t\tvar drag_container;\n\n\t\t//if custom method is defined - use it\n\t\tif (master.$dragCreate){\n\t\t\tdrag_container = master.$dragCreate(a,e,pointer);\n\t\t\tif (!drag_container) return false;\n\t\t\tthis._setDragOffset(e);\n\t\t\tdrag_container.style.position = \"absolute\";\n\t\t} else {\n\t\t//overvise use default one\n\t\t\tvar text = DragControl.$drag(a,e,pointer);\n\t\t\tDragControl._setDragOffset(e);\n\n\t\t\tif (!text) return false;\n\t\t\tdrag_container = document.createElement(\"DIV\");\n\t\t\tdrag_container.innerHTML=text;\n\t\t\tdrag_container.className=\"webix_drag_zone\";\n\t\t\tdocument.body.appendChild(drag_container);\n\n\t\t\tvar context = DragControl._drag_context;\n\t\t\tif (context.html){\n\t\t\t\tcontext.x_offset = -Math.round(drag_container.offsetWidth * 0.5);\n\t\t\t\tcontext.y_offset = -Math.round(drag_container.offsetHeight * 0.75);\n\t\t\t}\n\t\t}\n\t\t/*\n\t\t\tdragged item must have topmost z-index\n\t\t\tin some cases item already have z-index\n\t\t\tso we will preserve it if possible\n\t\t*/\n\t\tdrag_container.style.zIndex = Math.max(drag_container.style.zIndex,zIndex());\n\n\t\tDragControl._skipDropH = event(drag_container, env[pointer].move, DragControl._skip_mark);\n\n\t\tif (!DragControl._drag_context.from)\n\t\t\tDragControl._drag_context = {source:a, from:a};\n\t\t\n\t\tDragControl._html = drag_container;\n\t\treturn true;\n\t},\n\t//helper, prevents unwanted mouse-out events\n\t_skip_mark:function(){\n\t\tDragControl._skip = true;\n\t},\n\t//after dnd end, remove all traces and used html elements\n\tdestroyDrag:function(e){\n\t\tvar a = DragControl._active;\n\t\tvar master = this._drag_masters[a.webix_drag];\n\n\t\tif (DragControl._skipDropH)\n\t\t\tDragControl._skipDropH = eventRemove(DragControl._skipDropH);\n\t\t\n\t\tif (master && master.$dragDestroy){\n\t\t\tif(DragControl._html)\n\t\t\t\tmaster.$dragDestroy(a,DragControl._html,e);\n\t\t} else\n\t\t\tremove(DragControl._html);\n\n\t\tif (master && master._auto_scroll_delay)\n\t\t\tmaster._auto_scroll_delay = window.clearTimeout(master._auto_scroll_delay);\n\n\t\tif (DragControl._dropHTML)\n\t\t\tremove(DragControl._dropHTML);\n\n\t\tDragControl._landing=DragControl._active=DragControl._last=DragControl._html=DragControl._dropHTML=null;\n\t\tDragControl._drag_context = null;\n\t},\n\t_getActiveDragMaster: function(){\n\t\treturn DragControl._drag_masters[DragControl._active.webix_drag];\n\t},\n\ttop:0,\t //relative position of drag marker to mouse cursor\n\tleft:0,\n\t_setDragOffset:function(e){\n\t\tconst pos = DragControl._start_pos;\n\t\tconst ctx = DragControl._drag_context;\n\n\t\tif(typeof ctx.x_offset != \"undefined\" && typeof ctx.y_offset != \"undefined\")\n\t\t\treturn null;\n\n\t\tctx.x_offset = ctx.y_offset = 0;\n\t\tconst m = DragControl._getActiveDragMaster();\n\t\tif (m._getDragItemPos && m !== this){\n\t\t\tconst itemPos = m._getDragItemPos(pos,e);\n\t\t\tif (itemPos){\n\t\t\t\tctx.x_offset = itemPos.x - pos.x;\n\t\t\t\tctx.y_offset = itemPos.y - pos.y;\n\t\t\t}\n\t\t}\n\t},\n\t$dragPos:function(pos, e){\n\t\tvar m=this._drag_masters[DragControl._active.webix_drag];\n\t\tif (m.$dragPos && m!=this){\n\t\t\tm.$dragPos(pos, e, DragControl._html);\n\t\t\treturn true;\n\t\t}\n\t},\n\t//called when mouse was moved in drop area\n\t$dragIn:function(s,t,e){\n\t\tvar m=this._drag_masters[t.webix_drop];\n\t\tif (m.$dragIn && m!=this) return m.$dragIn(s,t,e);\n\t\tt.className=t.className+\" webix_drop_zone\";\n\t\treturn t;\n\t},\n\t//called when mouse was moved out drop area\n\t$dragOut:function(s,t,n,e){\n\t\tvar m=this._drag_masters[t.webix_drop];\n\t\tif (m.$dragOut && m!=this) return m.$dragOut(s,t,n,e);\n\t\tt.className=t.className.replace(\"webix_drop_zone\",\"\");\n\t\treturn null;\n\t},\n\t//called when mouse was released over drop area\n\t$drop:function(s,t,e){\n\t\tvar m=this._drag_masters[t.webix_drop];\n\t\tDragControl._drag_context.from = DragControl.getMaster(s);\n\t\tif (m.$drop && m!=this) return m.$drop(s,t,e);\n\t\tt.appendChild(s);\n\t},\n\t//called when dnd just started\n\t$drag:function(s,e,p){\n\t\tvar m=this._drag_masters[s.webix_drag];\n\t\tif (m.$drag && m!=this) return m.$drag(s,e,p);\n\t\treturn \"
\"+s.innerHTML+\"
\";\n\t}\t\n};\n\n//global touch-drag handler\nattachEvent(\"onLongTouch\", function(ev){\n\tconst active = DragControl._active;\n\tif(!DragControl._touch_animation && active && active.contains(ev.target))\n\t\tDragControl._createTouchDrag(ev, \"touch\");\n});\n\n\nexport default DragControl;","import {pos as getPos, offset} from \"../webix/html\";\nimport {protoUI, ui, $$} from \"../ui/core\";\nimport animate from \"../webix/animate\";\nimport {$active} from \"../webix/skin\";\n\nimport state from \"../core/state\";\nimport env from \"../webix/env\";\nimport UIManager from \"../core/uimanager\";\nimport Destruction from \"../core/destruction\";\n\nimport {zIndex} from \"../ui/helpers\";\nimport {toNode, delay, clone, uid, extend} from \"../webix/helpers\";\nimport {_event} from \"../webix/htmlevents\";\nimport {assert} from \"../webix/debug\";\nimport {callEvent, attachEvent} from \"../webix/customevents\";\n\nimport EventSystem from \"../core/eventsystem\";\nimport Movable from \"../core/movable\";\nimport Modality from \"../core/modality\";\nimport ResizeArea from \"../core/resizearea\";\n\nimport baseview from \"./baseview\";\nimport base from \"./view\";\n\nconst api = {\n\tname:\"window\",\n\n\t$init:function(config){\n\t\tthis._viewobj.innerHTML = \"
\";\n\n\t\tthis._contentobj = this._viewobj.firstChild;\n\t\tthis._headobj = this._contentobj.childNodes[0];\n\t\tthis._dataobj = this._bodyobj = this._contentobj.childNodes[1];\n\t\tthis._viewobj.className +=\" webix_window\";\n\n\t\tthis._viewobj.setAttribute(\"role\", \"dialog\");\n\t\tthis._viewobj.setAttribute(\"tabindex\", \"0\");\n\n\t\tthis._head_cell = this._body_cell = null;\n\t\tthis._settings._inner = {top:false, left:false, right:false, bottom:false }; //set border flags\n\t\tif (!config.id) config.id = uid();\n\n\t\t_event(this._contentobj, \"click\", this._ignore_clicks, {bind:this});\n\t\t_event(this._contentobj, \"click\", function(){\n\t\t\t// brings a window to the front of other windows\n\t\t\tif(!this._settings.zIndex && this._settings.toFront){\n\t\t\t\tthis._viewobj.style.zIndex = zIndex();\n\t\t\t}\n\t\t}, {bind:this, capture:true});\n\n\t\t// hidden_setter handling\n\t\tif(config.modal)\n\t\t\tthis._modal = true;\n\t\t// head_setter handling\n\t\tif(config.headHeight)\n\t\t\tthis._settings.headHeight = config.headHeight;\n\t\tif(config.close)\n\t\t\tthis._settings.close = config.close;\n\n\t\tthis.attachEvent(\"onViewMoveEnd\", function(){\n\t\t\tif(this._settings.position)\n\t\t\t\tdelete this._settings.position;\n\t\t});\n\t},\n\t_ignore_clicks:function(e){\n\t\tconst popups = state._popups;\n\t\tlet index = popups.find(this);\n\t\tif (index == -1)\n\t\t\tindex = popups.length - 1;\n\n\t\te.click_view = index;\n\t},\n\tgetChildViews:function(){\n\t\tif (this._head_cell)\n\t\t\treturn [this._head_cell, this._body_cell];\n\t\telse\n\t\t\treturn [this._body_cell];\n\t},\n\tzIndex_setter:function(value){\n\t\tthis._viewobj.style.zIndex = value;\n\t\treturn value;\n\t},\n\t_remove:function(){ \n\t\tthis.body_setter();\n\t},\n\t_replace:function(new_view, old_view){\n\t\told_view = old_view || this._body_cell;\n\t\tconst isBody = old_view == this._body_cell;\n\n\t\told_view.destructor();\n\n\t\tif(isBody)\n\t\t\tthis._body_cell = new_view;\n\t\telse \n\t\t\tthis._head_cell = new_view;\n\n\t\t(isBody ? this._bodyobj : this._headobj).appendChild(new_view._viewobj);\n\n\t\tconst cell = new_view._viewobj.style;\n\n\t\tlet settings = { top:true, left:true, right:true, bottom:true };\n\t\tlet size = \"0px\";\n\n\t\tif(new_view.config.borderless === false){\n\t\t\tsettings = clone(this._settings._inner);\n\t\t\tsize = \"1px\";\n\t\t}\n\t\tnew_view._settings._inner = settings;\n\t\tcell.borderTopWidth = cell.borderBottomWidth = cell.borderLeftWidth = cell.borderRightWidth = size;\n\n\t\tthis.resize(true);\n\t},\n\tshow:function(node, mode, point){\n\t\tif (node === true){\n\t\t\t//recursive call from some child item\n\t\t\tif (!this._settings.hidden)\n\t\t\t\treturn;\n\t\t\tnode = null;\n\t\t}\n\n\t\tif(!this.callEvent(\"onBeforeShow\",arguments))\n\t\t\treturn false;\n\n\t\tthis._settings.hidden = false;\n\t\tthis._viewobj.style.zIndex = zIndex(this._settings.zIndex);\n\t\tif (this._settings.modal || this._modal){\n\t\t\tthis._modal_set(true);\n\t\t\tthis._modal = null; // hidden_setter handling\n\t\t}\n\n\t\tlet elPos, dx, dy;\n\t\tmode = mode || {};\n\t\tif (!mode.pos)\n\t\t\tmode.pos = this._settings.relative;\n\n\t\t//get position of source html node\n\t\t//we need to show popup which pointing to that node\n\t\tif (node){\n\t\t\t//if event was provided - get node info from it\n\t\t\tif (typeof node == \"object\" && !node.tagName){\n\t\t\t\t/*below logic is far from ideal*/\n\t\t\t\tif (node.target){\n\t\t\t\t\telPos = getPos(node);\n\t\t\t\t\tdx = 20;\n\t\t\t\t\tdy = 5;\n\t\t\t\t} else\n\t\t\t\t\telPos = node;\n\t\t\t} else {\n\t\t\t\tnode = toNode(node);\n\t\t\t\tassert(node,\"Not existing target for window:show\");\n\t\t\t\telPos = offset(node);\n\t\t\t}\n\n\t\t\t//size of body, we need to fit popup inside\n\t\t\tconst x = Math.max(window.innerWidth || 0, document.body.offsetWidth);\n\t\t\tconst y = Math.max(window.innerHeight || 0, document.body.offsetHeight);\n\n\t\t\t//size of node, near which popup will be rendered\n\t\t\tdx = dx || node.offsetWidth || 0;\n\t\t\tdy = dy || node.offsetHeight || 0;\n\t\t\t//size of popup element\n\t\t\tconst size = this._last_size;\n\n\t\t\tlet fin_x = elPos.x;\n\t\t\tlet fin_y = elPos.y;\n\t\t\tlet point_y = 0;\n\t\t\tlet point_x = 0;\n\t\t\tlet scrollLeft = 0, scrollTop = 0;\n\t\t\tconst fit = this._settings.autofit;\n\t\t\tif (fit){\n\t\t\t\tconst nochange = (fit === \"node\");\n\t\t\t\tlet delta_x = 6, delta_y = 6, delta_point = 6;\n\t\t\t\tif (!this._settings.point)\n\t\t\t\t\tdelta_x = delta_y = delta_point = 0;\n\n\t\t\t\t//default pointer position - top \n\t\t\t\tpoint = \"top\";\n\t\t\t\tfin_y=0; fin_x = 0;\n\n\t\t\t\tscrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;\n\t\t\t\t//if we want to place menu at righ, but there is no place move it to left instead\n\t\t\t\tif (x - elPos.x - dx < size[0] && mode.pos == \"right\" && !nochange)\n\t\t\t\t\tmode.pos = \"left\";\n\n\t\t\t\tif (mode.pos == \"right\"){\n\t\t\t\t\tfin_x = elPos.x+delta_x+dx; \n\t\t\t\t\tdelta_y = -dy;\n\t\t\t\t\tpoint = \"left\";\n\t\t\t\t\tpoint_y = Math.round(elPos.y+dy/2);\n\t\t\t\t\tpoint_x = fin_x - delta_point;\n\t\t\t\t} else if (mode.pos == \"left\"){\n\t\t\t\t\tfin_x = elPos.x-delta_x-size[0]-1;\n\t\t\t\t\tdelta_y = -dy;\n\t\t\t\t\tpoint = \"right\";\n\t\t\t\t\tpoint_y = Math.round(elPos.y+dy/2);\n\t\t\t\t\tpoint_x = fin_x + size[0]+1;\n\t\t\t\t} else {\n\t\t\t\t\t//left border of screen\n\t\t\t\t\tif (elPos.x < scrollLeft){\n\t\t\t\t\t\tfin_x = scrollLeft;\n\t\t\t\t\t//popup exceed the right border of screen\n\t\t\t\t\t} else if (x+scrollLeft-elPos.x > size[0]){\n\t\t\t\t\t\tfin_x = elPos.x; //aligned\n\t\t\t\t\t} else{\n\t\t\t\t\t\tfin_x = x+scrollLeft-delta_x-size[0]; //not aligned\n\t\t\t\t\t}\n\n\t\t\t\t\tpoint_x = Math.round(elPos.x+dx/2);\n\t\t\t\t\t//when we have a small popup, point need to be rendered at center of popup\n\t\t\t\t\tpoint_x = Math.min(point_x, fin_x + size[0] - delta_point*3);\n\t\t\t\t}\n\n\t\t\t\t//if height is not fixed - use default position\n\t\t\t\tscrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;\n\t\t\t\tif (((!size[1] || (y+scrollTop-dy-elPos.y-delta_y > size[1])) || nochange) && mode.pos != \"top\"){\n\t\t\t\t\t//bottom\t\n\t\t\t\t\tfin_y = dy+elPos.y+delta_y - (!this._settings.point ? 0: 4);\n\t\t\t\t\tif (!point_y){\n\t\t\t\t\t\tpoint = \"top\";\n\t\t\t\t\t\tpoint_y = fin_y-delta_point;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t//top\n\t\t\t\t\tfin_y = elPos.y-delta_y - size[1];\n\t\t\t\t\tif (fin_y < 0){\n\t\t\t\t\t\tfin_y = 0; \n\t\t\t\t\t\t//left|right point can be used, but there is no place for top point\n\t\t\t\t\t\tif (point == \"top\") point = false;\n\t\t\t\t\t} else if (!point_y){\n\t\t\t\t\t\tpoint = \"bottom\";\n\t\t\t\t\t\tfin_y --;\n\t\t\t\t\t\tpoint_y = fin_y+size[1]+1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst deltax = (mode.x || 0);\n\t\t\tconst deltay = (mode.y || 0);\n\n\t\t\tconst fixed = this._checkFixedPosition();\n\t\t\tthis.$view.style.position = fixed ? \"fixed\" : \"absolute\";\n\t\t\tif (fixed){\n\t\t\t\tfin_y = fin_y - scrollTop;\n\t\t\t\tpoint_y = point_y - scrollTop;\n\t\t\t}\n\n\t\t\tthis.setPosition(fin_x+deltax, fin_y+deltay);\n\t\t\tif (this._set_point){\n\t\t\t\tif (point && this._settings.point)\n\t\t\t\t\tthis._set_point(point,point_x+deltax, point_y+deltay, fixed);\n\t\t\t\telse\n\t\t\t\t\tthis._hide_point();\n\t\t\t}\n\t\t} else\n\t\t\tthis._setPosition(this._settings.left, this._settings.top);\n\n\t\tthis._viewobj.style.display = \"block\";\n\t\tthis._hide_timer = 1;\n\t\tdelay(function(){ this._hide_timer = 0; }, this, [], (env.fastClick ? 100 : 400));\n\n\t\tthis._render_hidden_views();\n\n\t\tif (this.config.autofocus){\n\t\t\tthis._prev_focus = UIManager.getFocus();\n\t\t\tUIManager.setFocus(this);\n\t\t}\n\n\t\tif (-1 == state._popups.find(this))\n\t\t\tstate._popups.push(this);\n\n\t\tthis.callEvent(\"onShow\",[]);\n\t}, \n\t_hide:function(e){\n\t\t//do not hide modal windows\n\t\tif (this._settings.hidden || this._settings.modal || !this._settings.escHide || this._hide_timer) return;\n\n\t\tif(e){\n\t\t\t//do not hide submenu when clicking on menu folder\n\t\t\tif (e.showpopup && (e.showpopup == this._settings.id || (this.getTopMenu && this.getTopMenu()._settings.id == e.showpopup))) return;\n\t\t\t//do not hide popup, when starting dnd with a long touch\n\t\t\tif (env.touch && e.longtouch_drag) return;\n\t\t\t//do not hide popup, when we hide inner suggest by pressing esc\n\t\t\tif (e.hidesuggest) return;\n\t\t}\n\n\t\t//do not hide popup, when we have modal layer above the popup\n\t\tif (state._modality.length && this._viewobj.style.zIndex <= Math.max(...state._modality)) return;\n\n\t\t//ignore inside clicks and clicks in child-popups\n\n\t\tif (e){\n\t\t\tlet index = e.click_view;\n\t\t\tif (!index && index !== 0) index = -1;\n\n\t\t\tconst myindex = state._popups.find(this);\n\n\t\t\tif (myindex <= index) return;\n\t\t}\n\n\t\tthis._hide_single();\n\t},\n\thidden_setter:function(value){\n\t\tif(value) \n\t\t\tthis.hide();\n\t\telse\n\t\t\tthis.show();\n\t\treturn !!value;\n\t},\n\thide:function(){\n\t\tconst index = this._hide_single();\n\t\tthis._hide_sub_popups(index);\n\t},\n\t_hide_single:function(){\n\t\tif (this.$destructed || this._settings.hidden) return;\n\n\t\tif (this._settings.modal)\n\t\t\tthis._modal_set(false);\n\n\t\tthis._hiding_process();\n\n\t\tif (this._settings.master){\n\t\t\tconst view = $$(this._settings.master);\n\t\t\tif (view && view.touchable && view._settings.popup === this._settings.id){\n\t\t\t\tconst node = view.getInputNode() || view.getNode();\n\t\t\t\tnode.setAttribute(\"aria-expanded\", false);\n\t\t\t}\n\t\t}\n\n\t\tif (this._settings.autofocus){\n\t\t\tconst el = document.activeElement;\n\t\t\t//as result of hotkey, we can have a activeElement set to document.body\n\t\t\tif (el && this._viewobj && (this._viewobj.contains(el) || el === document.body)){\n\t\t\t\tUIManager.setFocus(this._prev_focus);\n\t\t\t\tthis._prev_focus = null;\n\t\t\t}\n\t\t}\n\n\t\t// clear state\n\t\tconst index = state._popups.find(this);\n\t\tif (index > -1)\n\t\t\tstate._popups.removeAt(index);\n\n\t\treturn index;\n\t},\n\t_hiding_process:function(){\n\t\tif (this._settings.position == \"top\"){\n\t\t\tanimate(this._viewobj, {type: \"slide\", x:0, y:-(this._content_height+20), duration: 300,\n\t\t\t\tcallback:this._hide_callback, master:this});\n\t\t} else \n\t\t\tthis._hide_callback();\n\t},\n\t//hide all child-popups\n\t_hide_sub_popups:function(index){\n\t\tif (index > -1){\n\t\t\tconst order = state._popups;\n\t\t\tfor (let i=order.length-1; i>=index; i--)\n\t\t\t\tif (order[i]._hide_point)\t//hide only popups, skip windows\n\t\t\t\t\torder[i]._hide_single();\n\t\t}\n\t},\n\tdestructor: function() {\n\t\tthis.hide();\n\t\tDestruction.destructor.apply(this, []);\n\t},\n\t_hide_callback:function(){\n\t\tif (!this.$destructed){\n\t\t\tthis._viewobj.style.display = \"none\";\n\t\t\tthis._settings.hidden = true;\n\t\t\tthis.callEvent(\"onHide\",[]);\n\t\t}\n\t},\n\tclose:function(){\n\t\tthis.destructor(); \n\t},\n\t_inner_body_set:function(value){\n\t\tif (typeof value.borderless == \"undefined\")\n\t\t\tvalue.borderless = true;\n\t},\n\tbody_setter:function(value){\n\t\tif (typeof value != \"object\")\n\t\t\tvalue = {template:value };\n\t\tthis._inner_body_set(value);\n\n\t\tstate._parent_cell = this;\n\t\tthis._body_cell = ui._view(value);\n\n\t\tthis._bodyobj.appendChild(this._body_cell._viewobj);\n\t\treturn value;\n\t},\n\thead_setter:function(value){\n\t\tif (value === false) return value;\n\n\t\tconst height = this._settings.headHeight;\n\t\tconst text = typeof value == \"string\";\n\t\tconst config = { height, padding:0, css: \"webix_win_title\", type:\"header\", borderless:true };\n\t\tif(text){\n\t\t\tthis._viewobj.setAttribute(\"aria-label\", value);\n\t\t\tvalue = { template:value };\n\t\t}\n\t\tif(value.view == \"template\" || (!value.view && value.template)){\n\t\t\textend(value, config);\n\t\t}\n\t\tif(text && this.config.close){\n\t\t\tvalue = { padding:{ left: $active.inputHeight+2, right:2 }, cols:[\n\t\t\t\tvalue,\n\t\t\t\t{ height, view:\"icon\", icon:\"wxi-close\", click:()=>{\n\t\t\t\t\tthis.hide();\n\t\t\t\t}}\n\t\t\t]};\n\t\t}\n\t\telse\n\t\t\textend(value, {borderless:true});\n\n\t\tstate._parent_cell = this;\n\t\tthis._head_cell = ui._view(value);\n\n\t\tconst template = this._head_cell._viewobj.querySelector(\".webix_win_title>div\");\n\t\tif(template)\n\t\t\ttemplate.style.lineHeight = height + \"px\";\n\n\t\tthis._headobj.appendChild(this._head_cell._viewobj);\n\t\treturn value;\n\t},\n\tgetBody:function(){\n\t\treturn this._body_cell;\n\t},\n\tgetHead:function(){\n\t\treturn this._head_cell;\n\t},\n\tadjust:function(){ return this.resize(); },\n\tresizeChildren:function(){\n\t\tif (this._body_cell)\n\t\t\tthis.resize();\n\t},\n\tresize:function(){\n\t\tbaseview.api.adjust.call(this);\n\t\tcallEvent(\"onResize\", []);\n\t\tif (this.isVisible()){\n\t\t\tthis._setPosition(this._settings.left, this._settings.top);\n\t\t}\n\t},\n\t_checkFixedPosition: function() {\n\t\tif(this._settings.master) {\n\t\t\tconst top = $$(this._settings.master).getTopParentView().$view;\n\t\t\treturn top && top.style.position === \"fixed\";\n\t\t}\n\t\treturn false;\n\t},\n\t_setPosition:function(x,y){\n\t\tif ((this._settings.position || this._checkFixedPosition())){\n\t\t\tthis.$view.style.position = \"fixed\";\n\n\t\t\tconst width = this._content_width;\n\t\t\tconst height = this._content_height;\n\t\t\tif (width <= 0 || height <= 0) return;\n\n\t\t\tconst maxWidth = (window.innerWidth||document.documentElement.offsetWidth);\n\t\t\tconst maxHeight = (window.innerHeight||document.documentElement.offsetHeight);\n\t\t\tlet left = Math.round((maxWidth-width)/2);\n\t\t\tlet top = Math.round((maxHeight-height)/2);\n\n\t\t\tif (typeof this._settings.position == \"function\"){\n\t\t\t\tconst state = { \tleft:left, top:top, \n\t\t\t\t\twidth:width, height:height, \n\t\t\t\t\tmaxWidth:maxWidth, maxHeight:maxHeight };\n\t\t\t\tthis._settings.position.call(this, state);\n\t\t\t\tif (state.width != width || state.height != height){\n\t\t\t\t\tthis._settings.width = state.width;\n\t\t\t\t\tthis._settings.height = state.height;\n\t\t\t\t\tthis.$setSize(state.width, state.height);\n\t\t\t\t}\n\t\t\t\tthis.setPosition(state.left, state.top);\n\t\t\t} else {\n\t\t\t\tif (this._settings.position == \"top\"){\n\t\t\t\t\ttop = -1*height;\n\t\t\t\t}\n\t\t\t\t//popup inside a fixed win\n\t\t\t\tif(!this._settings.position){\n\t\t\t\t\tleft = this._settings.left || left;\n\t\t\t\t\ttop = this._settings.top || top;\n\t\t\t\t}\n\t\t\t\tthis.setPosition(left, top);\n\t\t\t}\n\n\t\t\tif (this._settings.position == \"top\")\n\t\t\t\tanimate(this._viewobj, {type: \"slide\", x:0, y:height-((this._settings.padding||0)*2), duration: 300 ,callback:this._topPositionCallback, master:this});\n\t\t} else \n\t\t\tthis.setPosition(x,y);\n\t},\n\t_topPositionCallback:function(node){\n\t\tanimate.clear(node);\n\t\tthis._settings.top=-((this._settings.padding||0)*2);\n\t\tthis.setPosition(this._settings.left, this._settings.top);\n\t},\n\tsetPosition:function(x,y){\n\t\tthis._viewobj.style.top = y+\"px\";\n\t\tthis._viewobj.style.left = x+\"px\";\n\t\tthis._settings.left = x; this._settings.top=y;\n\t},\n\t$getSize:function(dx, dy){\n\t\tconst _borders = this._settings._inner;\n\t\tif (_borders){\n\t\t\tdx += (_borders.left?0:1)+(_borders.right?0:1);\n\t\t\tdy += (_borders.top?0:1)+(_borders.bottom?0:1);\n\t\t}\n\t\t//line between head and body\n\t\tif (this._settings.head)\n\t\t\tdy += 1;\n\n\t\tconst size = this._body_cell.$getSize(0,0);\n\t\tlet headMinWidth = 0;\n\t\tif (this._head_cell){\n\t\t\tconst head_size = this._head_cell.$getSize(0,0);\n\t\t\tif (head_size[3]==head_size[2])\n\t\t\t\tthis._settings.headHeight = head_size[3];\n\t\t\tdy += this._settings.headHeight;\n\t\t\theadMinWidth = head_size[0];\n\t\t}\n\n\t\tif (this._settings.fullscreen){\n\t\t\tconst width = window.innerWidth || document.body.clientWidth;\n\t\t\tconst height = window.innerHeight || document.body.clientHeight;\n\t\t\treturn [width, width, height, height];\n\t\t}\n\n\t\t//get layout sizes\n\t\tconst self_size = base.api.$getSize.call(this, 0, 0);\n\n\t\t//use child settings if layout's one was not defined\n\t\tif (headMinWidth && size[1] > 100000)\n\t\t\tsize[0] = Math.max(headMinWidth, size[0]);\n\n\t\tself_size[1] = Math.min(self_size[1],(size[1]>=100000&&self_size[1]>=100000?Math.max(size[0], self_size[0]):size[1])+dx);\n\t\tself_size[3] = Math.min(self_size[3],(size[3]>=100000&&self_size[3]>=100000?Math.max(size[2], self_size[2]):size[3])+dy);\n\n\t\tself_size[0] = Math.min(Math.max(self_size[0],size[0] + dx), self_size[1]);\n\t\tself_size[2] = Math.min(Math.max(self_size[2],size[2] + dy), self_size[3]);\n\n\t\treturn self_size;\n\t},\n\t$setSize:function(x,y){\n\t\tbase.api.$setSize.call(this,x,y);\n\t\tx = this._content_width;\n\t\ty = this._content_height;\n\t\tif (this._settings.head === false) {\n\t\t\tthis._headobj.style.display=\"none\";\n\t\t\tthis._body_cell.$setSize(x,y);\n\t\t} else { \n\t\t\tthis._head_cell.$setSize(x,this._settings.headHeight);\n\t\t\tthis._body_cell.$setSize(x,y-this._settings.headHeight);\n\t\t}\n\t},\n\t$skin:function(){\n\t\tthis.defaults.headHeight = $active.barHeight;\n\t},\n\tdefaults:{\n\t\ttop:0,\n\t\tleft:0,\n\t\tautofit:true,\n\t\trelative:\"bottom\",\n\t\tbody:\"\",\n\t\thead:\"\",\n\t\thidden: true,\n\t\tautofocus:true,\n\t\tminWidth:300,\n\t\tminHeight:200,\n\t\tescHide:true\n\t}\n};\n\n//global longtouch handler\nattachEvent(\"onLongTouch\", function(ev){\n\tif (!ev || !ev.target) return;\n\n\tlet view = $$(ev.target);\n\tif (view){\n\t\tview = view.queryView(a => !a.getParentView(), \"parent\")||view;\n\n\t\tconst popups = state._popups;\n\t\tconst index = popups.find(view);\n\t\tif (index !== -1) ev.click_view = index;\n\t}\n});\n\nconst view = protoUI(api, base.view, Movable, Modality, EventSystem, ResizeArea);\nexport default {api, view};","import {create, insertBefore, remove} from \"../webix/html\";\nimport env from \"../webix/env\";\nimport {extend, bind} from \"../webix/helpers\";\n\n\nconst CustomPrint = {\n\t$customPrint:function(options, htmlOnly){\n\t\tif(this._prePrint(options, htmlOnly))\n\t\t\treturn true;\n\n\t\tvar tableData = this._getTableArray(options);\n\t\tvar table = this._getTableHTML(tableData, options);\n\n\t\tif(htmlOnly)\n\t\t\treturn table;\n\n\t\tvar doc = create(\"div\", { \"class\":\"webix_ui_print\"});\n\t\tdoc.appendChild(table);\n\n\t\tinsertBefore(doc, options.docFooter, document.body);\n\t\twindow.print();\n\t\t\n\t\tremove(doc);\n\t},\n\t_prePrint:function(options, htmlOnly){\n\t\tif(!htmlOnly && (this.config.layout ==\"y\" || options.scroll || this.config.prerender || this.config.autoheight)) return true;\n\t\t\n\t\tif(this.config.layout ==\"x\")\n\t\t\textend(options || {}, {xCount:this.count(), nobreaks:true}, true);\n\t},\n\t_getPageWidth:function(options){\n\t\tvar size = options.size;\n\t\tvar width = size[options.mode == \"portrait\"?\"width\":\"height\"];\n\t\t\n\t\treturn Math.min(width*env.printPPI-2*env.printMargin);\n\t},\n\t_getTableArray:function(options, base, start){\n\t\tvar maxWidth = options.fit ==\"page\" ? Infinity : this._getPageWidth(options);\n\t\tvar xCount = options.xCount || this._getVisibleRange()._dx;\n\n\t\tvar tableArray = [];\n\t\tvar colrow = [];\n\t\tvar width = 0;\n\t\t\n\t\tvar newTableStart, rownum, colnum;\n\n\t\tstart = start || 0;\n\t\tbase = base || [];\n\n\t\tfor(var i = 0; i=start){\n\t\t\t\twidth += this.type.width;\n\t\t\t\t\n\t\t\t\t//start a new table, if cells do not fit page width\n\t\t\t\tif(width > maxWidth && colnum>start){ // 'colnum>start' ensures that a single long cell will have to fit the page\n\t\t\t\t\tnewTableStart = colrow.length+start;\n\t\t\t\t\ttableArray.push(colrow);\n\t\t\t\t\ti = i+(xCount-colrow.length);\n\t\t\t\t\tcolrow = [];\n\t\t\t\t\twidth = 0;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tvar cellValue = this.type.template(obj, this.type);\n\t\t\t\tvar className = this._itemClassName;\n\t\t\t\t\n\t\t\t\tvar style = {\n\t\t\t\t\tdisplay:\"table-cell\",\n\t\t\t\t\theight:this.type.height + \"px\",\n\t\t\t\t\twidth:this.type.width + \"px\"\n\t\t\t\t};\n\t\t\t\t//push a cell to a row\n\t\t\t\tcolrow.push({\n\t\t\t\t\ttxt: cellValue,\n\t\t\t\t\tclassName: className+\" \"+(obj.$css || \"\"),\n\t\t\t\t\tstyle: style\n\t\t\t\t});\n\t\t\t\t//push a row to a table and start a new row\n\t\t\t\tif((i+1)%xCount === 0){\n\t\t\t\t\ttableArray.push(colrow);\n\t\t\t\t\tcolrow = [];\n\t\t\t\t\twidth = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\ti++;\n\t\t}\n\n\t\tbase.push(tableArray);\n\n\t\tif(newTableStart)\n\t\t\tthis._getTableArray(options, base, newTableStart);\t\n\n\t\treturn base;\n\t},\n\t_getTableHTML:function(tableData, options){\n\t\t\n\t\tvar container = create(\"div\");\n\n\t\ttableData.forEach(bind(function(table, i){\n\n\t\t\tvar tableHTML = create(\"table\", {\n\t\t\t\t\"class\":\"webix_table_print \"+this.$view.className,\n\t\t\t\t\"style\":\"border-collapse:collapse\"\n\t\t\t});\n\n\t\t\ttable.forEach(function(row){\n\t\t\t\tvar tr = create(\"tr\");\n\n\t\t\t\trow.forEach(function(column){\n\t\t\t\t\tvar td = create(\"td\");\n\n\n\t\t\t\t\tif (column.txt) td.innerHTML = column.txt;\n\t\t\t\t\tif (column.className) td.className = column.className;\n\t\t\t\t\tif (column.style) {\n\t\t\t\t\t\tvar keys = Object.keys(column.style);\n\t\t\t\t\t\tkeys.forEach(function(key){\n\t\t\t\t\t\t\tif (column.style[key])\n\t\t\t\t\t\t\t\ttd.style[key] = column.style[key];\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif(column.span){\n\t\t\t\t\t\tif(column.span.colspan > 1)\n\t\t\t\t\t\t\ttd.colSpan = column.span.colspan;\n\t\t\t\t\t\tif(column.span.rowspan > 1)\n\t\t\t\t\t\t\ttd.rowSpan = column.span.rowspan;\n\t\t\t\t\t}\n\t\t\t\t\ttr.appendChild(td);\n\t\t\t\t});\n\t\t\t\ttableHTML.appendChild(tr);\n\t\t\t});\n\t\t\tcontainer.appendChild(tableHTML);\n\n\t\t\tif(!options.nobreaks && i+1 < tableData.length){\n\t\t\t\tvar br = create(\"DIV\", {\"class\":\"webix_print_pagebreak\"});\n\t\t\t\tcontainer.appendChild(br);\n\t\t\t}\n\t\t\t\n\t\t}, this));\n\n\t\treturn container;\n\t}\n};\n\nexport default CustomPrint;","import {assert} from \"../webix/debug\";\nimport CodeParser from \"../core/codeparser\";\nimport rules from \"../webix/rules\";\n\n\n\nconst ValidateData = {\n\t$init:function(){\n\t\tif(this._events)\n\t\t\tthis.attachEvent(\"onChange\",this.clearValidation);\n\t},\n\tclearValidation:function(){\n\t\tif(this.elements){\n\t\t\tfor(var id in this.elements){\n\t\t\t\tthis._clear_invalid(id);\n\t\t\t}\n\t\t}\n\t},\n\tvalidate:function(mode, obj) {\n\t\tassert(this.callEvent, \"using validate for eventless object\");\n\t\t\n\t\tthis.callEvent(\"onBeforeValidate\", []);\n\n\t\tvar failed = this._validate_details = {};\n\n\t\t//optimistic by default :) \n\t\tvar result =true;\n\t\tvar rules = this._settings.rules;\n\t\t\n\t\tvar isHidden = this.isVisible && !this.isVisible();\n\t\tvar validateHidden = mode && mode.hidden;\n\t\tvar validateDisabled = mode && mode.disabled;\n\n\t\t//prevent validation of hidden elements\n\t\tvar elements = {}, hidden = {};\n\t\tfor(var i in this.elements){\n\t\t\tvar name = this.elements[i].config.name;\n\t\t\t//we are ignoring hidden and disabled fields during validation\n\t\t\t//if mode doesn not instruct us otherwise\n\t\t\t//if form itself is hidden, we can't separate hidden fiels,\n\t\t\t//so we will vaidate all fields\n\t\t\tif((isHidden || this.elements[i].isVisible() || validateHidden) && (this.elements[i].isEnabled() || validateDisabled))\n\t\t\t\telements[name] = this.elements[i];\n\t\t\telse{\n\t\t\t\thidden[name]=true;\n\t\t\t}\n\t\t}\n\t\tif (rules || elements)\n\t\t\tif(!obj && this.getValues)\n\t\t\t\tobj = this.getValues();\n\n\t\tif (rules){\n\t\t\t//complex rule, which may chcek all properties of object\n\t\t\tif (rules.$obj)\n\t\t\t\tresult = this._validate(rules.$obj, obj, obj, \"\") && result;\n\t\t\t\n\t\t\t//all - applied to all fields\n\t\t\tvar all = rules.$all;\n\t\t\tvar data = obj;\n\n\t\t\tif (this._settings.complexData)\n\t\t\t\tdata = CodeParser.collapseNames(obj, \"\", {}, (v) => !rules[v]);\n\n\t\t\tif (all)\n\t\t\t\tfor (let key in obj){\n\t\t\t\t\tif(hidden[key]) continue;\n\t\t\t\t\tlet subresult = this._validate(all, data[key], obj, key);\n\t\t\t\t\tif (!subresult)\n\t\t\t\t\t\tfailed[key] = true;\n\t\t\t\t\tresult = subresult && result;\n\t\t\t\t}\n\n\n\t\t\t//per-field rules\n\t\t\tfor (let key in rules){\n\t\t\t\tif(hidden[key]) continue;\n\t\t\t\tif (key.indexOf(\"$\")!==0 && !failed[key]){\n\t\t\t\t\tassert(rules[key], \"Invalid rule for:\"+key);\n\t\t\t\t\tlet subresult = this._validate(rules[key], data[key], obj, key);\n\t\t\t\t\tif (!subresult)\n\t\t\t\t\t\tfailed[key] = true;\n\t\t\t\t\tresult = subresult && result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//check personal validation rules\n\t\tif (elements){\n\t\t\tfor (var key in elements){\n\t\t\t\tif (failed[key]) continue;\n\n\t\t\t\tvar subview = elements[key];\n\t\t\t\tif (subview.validate){\n\t\t\t\t\tlet subresult = subview.validate();\n\t\t\t\t\tresult = subresult && result;\n\t\t\t\t\tif (!subresult)\n\t\t\t\t\t\tfailed[key] = true;\n\t\t\t\t} else {\n\t\t\t\t\tvar input = subview._settings;\n\t\t\t\t\tif (input){\t//ignore non webix inputs\n\t\t\t\t\t\tvar validator = input.validate;\n\t\t\t\t\t\tif (!validator && input.required)\n\t\t\t\t\t\t\tvalidator = rules.isNotEmpty;\n\n\t\t\t\t\t\tif (validator){\n\t\t\t\t\t\t\tlet subresult = this._validate(validator, obj[key], obj, key);\n\t\t\t\t\t\t\tif (!subresult)\n\t\t\t\t\t\t\t\tfailed[key] = true;\n\t\t\t\t\t\t\tresult = subresult && result;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\tthis.callEvent(\"onAfterValidation\", [result, this._validate_details]);\n\t\treturn result;\n\t},\n\t_validate:function(rule, data, obj, key){\n\t\tif (typeof rule == \"string\")\n\t\t\trule = rules[rule];\n\t\tif (rule.call(this, data, obj, key)){\n\t\t\tif(this.callEvent(\"onValidationSuccess\",[key, obj]) && this._clear_invalid)\n\t\t\t\tthis._clear_invalid(key);\n\t\t\treturn true;\n\t\t} else {\n\t\t\tif(this.callEvent(\"onValidationError\",[key, obj]) && this._mark_invalid)\n\t\t\t\tthis._mark_invalid(key);\n\t\t}\n\t\treturn false;\n\t}\n};\n\nexport default ValidateData;","import {assert} from \"../webix/debug\";\nimport {copy, isUndefined, bind, isArray} from \"../webix/helpers\";\nimport {callEvent} from \"../webix/customevents\";\nimport {define} from \"../services\";\n\nimport {$$, proto} from \"../ui/core\";\n\nimport {ajax} from \"../load/ajax\";\nimport proxy from \"../load/proxy\";\nimport promise from \"../thirdparty/promiz\";\n\nimport Settings from \"../core/settings\";\nimport EventSystem from \"../core/eventsystem\";\nimport ValidateData from \"../core/validatedata\";\n\nconst _pull = {};\n\nexport function dp(name,getOnly){\n\tif (typeof name == \"object\" && name._settings)\n\t\tname = name._settings.id;\n\tif (_pull[name] || getOnly)\n\t\treturn _pull[name];\n\n\tif (typeof name == \"string\"||typeof name == \"number\")\n\t\tname = { master:$$(name) };\n\n\tvar dp = new DataProcessor(name);\n\tvar masterId = dp._settings.master._settings.id;\n\t_pull[masterId]=dp;\n\n\t$$(masterId).attachEvent(\"onDestruct\",function(){\n\t\t_pull[this._settings.id] = null;\n\t\tdelete _pull[this._settings.id];\n\t});\n\n\treturn dp;\n}\n\ndefine(\"dp\", dp);\n\ndp.$$ = function(id){\n\treturn _pull[id];\n};\n\n\nexport const DataProcessor = proto({\n\tdefaults: {\n\t\tautoupdate:true,\n\t\tupdateFromResponse:false,\n\t\tmode:\"post\",\n\t\toperationName:\"webix_operation\",\n\t\ttrackMove:false\n\t},\n\n\n\t/*! constructor\n\t **/\n\t$init: function() {\n\t\tthis.reset();\n\t\tthis._ignore = false;\n\t\tthis.name = \"DataProcessor\";\n\t\tthis.$ready.push(this._after_init_call);\n\t},\n\treset:function(){\n\t\tthis._updates = [];\n\t},\n\turl_setter:function(value){\n\t\t/*\n\t\t\twe can use simple url or mode->url\n\t\t*/\n\t\tvar mode = \"\";\n\t\tif (typeof value == \"string\"){\n\t\t\tvar parts = value.split(\"->\");\n\t\t\tif (parts.length > 1){\n\t\t\t\tvalue = parts[1];\n\t\t\t\tmode = parts[0];\n\t\t\t}\n\t\t} else if (value && value.mode){\n\t\t\tmode = value.mode;\n\t\t\tvalue = value.url;\n\t\t}\n\n\t\tif (mode)\n\t\t\treturn proxy(mode, value);\n\n\t\treturn value;\n\t},\n\tmaster_setter:function(value){\n\t\tvar store = value;\n\t\tif (value.name != \"DataStore\")\n\t\t\tstore = value.data;\n\n\t\tthis._settings.store = store;\n\t\treturn value;\n\t},\n\t_promise:function(handler){\n\t\tconst prev = this._waitSave;\n\t\tthis._waitSave = [];\n\t\t\n\t\thandler();\n\t\tconst result = Promise.all(this._waitSave);\n\n\t\tthis._waitSave = prev;\n\t\tif (prev)\n\t\t\tprev.push(result);\n\n\t\treturn result;\n\t},\n\t/*! attaching onStoreUpdated event\n\t **/\n\t_after_init_call: function(){\n\t\tconst store = this._settings.store;\n\t\tif (store){\n\t\t\tstore.attachEvent(\"onStoreUpdated\", bind(this._onStoreUpdated, this));\n\t\t\tstore.attachEvent(\"onDataMove\", bind(this._onDataMove, this));\n\t\t}\n\t},\n\tignore:function(code,master){\n\t\tvar temp = this._ignore;\n\t\tthis._ignore = true;\n\t\tcode.call((master||this));\n\t\tthis._ignore = temp;\n\t},\n\toff:function(){\n\t\tthis._ignore = true;\n\t},\n\ton:function(){\n\t\tthis._ignore = false;\n\t},\n\n\t_copy_data:function(source){\n\t\tvar obj = {};\n\t\tfor (var key in source)\t\n\t\t\tif (key.indexOf(\"$\")!==0)\n\t\t\t\tobj[key]=source[key];\n\t\treturn obj;\n\t},\n\tsave:function(id, operation, obj){\n\t\toperation = operation || \"update\";\n\t\treturn this._save_inner(id, obj, operation, true);\n\t},\n\t_save_inner:function(id, obj, operation, now){\n\t\tif (typeof id == \"object\") id = id.toString();\n\t\tif (!id || this._ignore === true || !operation || operation == \"paint\") return;\n\n\t\tvar store = this._settings.store;\n\t\tif (store){\n\t\t\tobj = obj || this._settings.store.getItem(id);\n\t\t\tif (store._scheme_serialize)\n\t\t\t\tobj = store._scheme_serialize(obj);\n\t\t}\n\n\t\tvar update = { id: id, data:this._copy_data(obj), operation:operation };\n\t\t//save parent id\n\t\tif (!isUndefined(obj.$parent)) update.data.parent = obj.$parent;\n\n\t\tif (update.operation != \"delete\"){\n\t\t\t//prevent saving of not-validated records\n\t\t\tvar master = this._settings.master;\n\t\t\tif (master && master.data && master.data.getMark && master.data.getMark(id, \"webix_invalid\"))\n\t\t\t\tupdate._invalid = true;\n\n\t\t\tif (!this.validate(null, update.data))\n\t\t\t\tupdate._invalid = true;\n\t\t}\n\n\t\tif (this._check_unique(update))\n\t\t\tthis._updates.push(update);\n\n\t\tif (this._settings.autoupdate || now)\n\t\t\treturn this._sendData(id);\n\t\t\t\n\t\treturn;\n\t},\n\t_onDataMove:function(sid, tindex, parent, targetid){\n\t\tif (this._settings.trackMove){\n\t\t\tvar obj = copy(this._settings.store.getItem(sid));\n\n\t\t\tobj.webix_move_index = tindex;\n\t\t\tobj.webix_move_id = targetid;\n\t\t\tobj.webix_move_parent = parent;\n\t\t\tthis._save_inner(sid, obj, \"order\");\n\t\t}\n\t},\n\t_onStoreUpdated: function(id, obj, operation){\n\t\tswitch (operation) {\n\t\t\tcase \"save\":\n\t\t\t\toperation = \"update\";\n\t\t\t\tbreak;\n\t\t\tcase \"update\":\n\t\t\t\toperation = \"update\";\n\t\t\t\tbreak;\n\t\t\tcase \"add\":\n\t\t\t\toperation = \"insert\";\n\t\t\t\tbreak;\n\t\t\tcase \"delete\":\n\t\t\t\toperation = \"delete\";\t\t\t\t\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn true;\n\t\t}\n\t\treturn this._save_inner(id, obj, operation);\n\t},\n\t_check_unique:function(check){\n\t\tfor (var i = 0; i < this._updates.length; i++){\n\t\t\tvar one = this._updates[i];\n\t\t\tif (one.id == check.id && !one._in_progress){\n\t\t\t\tif (check.operation == \"delete\"){\n\t\t\t\t\tif (one.operation == \"insert\")\n\t\t\t\t\t\tthis._updates.splice(i,1);\n\t\t\t\t\telse \n\t\t\t\t\t\tone.operation = \"delete\";\n\t\t\t\t}\n\t\t\t\tone.data = check.data;\n\t\t\t\tone._invalid = check._invalid;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t},\n\tsend:function(){\n\t\treturn this._sendData();\n\t},\n\t_sendData: function(triggerId){\n\t\tif (!this._settings.url)\n\t\t\treturn;\n\n\t\tvar wait;\n\t\tvar marked = this._updates;\n\t\tvar to_send = [];\n\t\tvar url = this._settings.url;\n\n\t\tfor (let i = 0; i < marked.length; i++) {\n\t\t\tvar tosave = marked[i];\n\n\t\t\tif (tosave._in_progress) continue;\n\t\t\tif (tosave._invalid) continue;\n\n\t\t\tvar id = tosave.id;\n\t\t\t// call to .save(id) without autoupdate mode will send the specific object only\n\t\t\tif (!this._settings.autoupdate && triggerId && triggerId != id)\n\t\t\t\tcontinue;\n\n\t\t\tvar operation = tosave.operation;\n\t\t\tvar precise_url = proxy.$parse((typeof url == \"object\" && !url.$proxy) ? url[operation] : url);\n\t\t\tvar custom = precise_url && (precise_url.$proxy || typeof precise_url === \"function\");\n\n\t\t\tif (!precise_url) continue;\n\n\t\t\tconst store = this._settings.store;\n\t\t\tif (store && store._scheme_save)\n\t\t\t\tstore._scheme_save(tosave.data);\n\n\t\t\tif (!this.callEvent(\"onBefore\"+operation, [id, tosave]))\n\t\t\t\tcontinue;\n\t\t\ttosave._in_progress = true;\n\n\t\t\tif (!this.callEvent(\"onBeforeDataSend\", [tosave])) return;\n\n\t\t\ttosave.data = this._updatesData(tosave.data);\n\n\t\t\tlet result;\n\t\t\tif (precise_url.$proxy){\n\t\t\t\tif (precise_url.save){\n\t\t\t\t\t//proxy\n\t\t\t\t\tresult = precise_url.save(this.config.master, tosave, this);\n\t\t\t\t}\n\t\t\t\tto_send.push(tosave);\n\t\t\t} else {\n\t\t\t\tif (operation == \"insert\")\n\t\t\t\t\tdelete tosave.data.id;\n\t\t\t\t\n\t\t\t\tif (custom){\n\t\t\t\t\t//save function\n\t\t\t\t\tresult = precise_url.call(this.config.master, tosave.id, tosave.operation, tosave.data);\n\t\t\t\t} else {\n\t\t\t\t\t//normal url\n\t\t\t\t\ttosave.data[this._settings.operationName] = operation;\n\n\t\t\t\t\tresult = this._send(precise_url, tosave.data, this._settings.mode);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (result){\n\t\t\t\tresult = this._proxy_on_save(result, { id: tosave.id, status: tosave.operation });\n\t\t\t\tif (triggerId && id === triggerId){\n\t\t\t\t\twait = result;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.callEvent(\"onAfterDataSend\", [tosave]);\n\t\t}\n\n\t\tif (url.$proxy && url.saveAll && to_send.length){\n\t\t\tlet result = url.saveAll(this.config.master, to_send, this);\n\t\t\tif (result){\n\t\t\t\tresult = this._proxy_on_save(result, null);\n\t\t\t\tif (!wait)\n\t\t\t\t\twait = result;\n\t\t\t}\n\t\t}\n\n\t\treturn wait;\n\t},\n\t_proxy_on_save:function(result, state){\n\t\tif(result){\n\t\t\tif(!result.then)\n\t\t\t\tresult = promise.resolve(result);\n\n\t\t\tresult = result.then((data) => {\n\t\t\t\tif (data && typeof data.json == \"function\")\n\t\t\t\t\tdata = data.json();\n\n\t\t\t\tvar processed;\n\t\t\t\tif (state === null){\n\t\t\t\t\tprocessed = this._processResult(data); //array of responses\n\t\t\t\t} else {\n\t\t\t\t\tprocessed = this._processResult(state, \"\", data, -1); //text, data, loader\n\t\t\t\t}\n\n\t\t\t\tif (!processed)\n\t\t\t\t\tthrow processed; // trigger rejection\n\n\t\t\t\treturn processed;\n\t\t\t}, (x) => {\n\t\t\t\tthis._processError(state, \"\", null, x);\n\t\t\t\tthrow x;\n\t\t\t});\n\n\t\t\tif (this._waitSave)\n\t\t\t\tthis._waitSave.push(result);\n\n\t\t\treturn result;\n\t\t}\n\t},\n\n\t/*! process updates list to POST and GET params according dataprocessor protocol\n\t *\t@param updates\n\t *\t\tlist of objects { id: \"item id\", data: \"data hash\", operation: \"type of operation\"}\n\t *\t@return\n\t *\t\tobject { post: { hash of post params as name: value }, get: { hash of get params as name: value } }\n\t **/\n\n\n\n\t_updatesData:function(source){\n\t\tvar target = {};\n\t\tfor (var j in source){\n\t\t\tif (j.indexOf(\"$\")!==0)\n\t\t\t\ttarget[j] = source[j];\n\t\t}\n\t\treturn target;\n\t},\n\n\n\n\t/*! send dataprocessor query to server\n\t *\tand attach event to process result\n\t *\t@param url\n\t *\t\tserver url\n\t *\t@param get\n\t *\t\thash of get params\n\t *\t@param post\n\t *\t\thash of post params\n\t *\t@mode\n\t *\t\t'post' or 'get'\n\t **/\n\t_send: function(url, post, mode) {\n\t\tassert(url, \"url was not set for DataProcessor\");\n\t\treturn ajax()[mode](url, post);\n\t},\n\tattachProgress:function(start, end, error){\n\t\tthis.attachEvent(\"onBeforeDataSend\", start);\n\t\tthis.attachEvent(\"onAfterSync\", end);\n\t\tthis.attachEvent(\"onAfterSaveError\", error);\n\t\tthis.attachEvent(\"onLoadError\", error);\n\t},\n\t_processError:function(id, text, data, loader){\n\t\tif (id)\n\t\t\tthis._innerProcessResult(true, id.id, false, id.status, false, {text:text, data:data, loader:loader});\n\t\telse {\n\t\t\tthis.callEvent(\"onLoadError\", arguments);\n\t\t\tcallEvent(\"onLoadError\", [text, data, loader, this]);\n\t\t}\n\t},\n\t_innerProcessResult:function(error, id, newid, status, obj, details){\n\t\tvar master = this._settings.master;\n\t\tvar update = this.getItemState(id);\n\t\tupdate._in_progress = false;\n\n\n\n\t\tif (error){\n\t\t\tif (this.callEvent(\"onBeforeSaveError\", [id, status, obj, details])){\n\t\t\t\tupdate._invalid = true;\n\t\t\t\tif(this._settings.undoOnError && master._settings.undo){\n\t\t\t\t\tthis.ignore(function(){\n\t\t\t\t\t\tmaster.undo(id);\n\t\t\t\t\t});\n\t\t\t\t\tthis.setItemState(id, false);\n\t\t\t\t}\n\t\t\t\tthis.callEvent(\"onAfterSaveError\", [id, status, obj, details]);\n\t\t\t}\n\t\t\treturn;\n\t\t} else\n\t\t\tthis.setItemState(id, false);\n\n\t\tconst store = this._settings.store;\n\t\tif (store && store.exists(id)){\n\t\t\t//update from response\n\t\t\tif (newid && id != newid)\n\t\t\t\tstore.changeId(id, newid);\n\n\t\t\tif (obj && status != \"delete\" && this._settings.updateFromResponse)\n\t\t\t\tthis.ignore(function(){\t\t\t\t\n\t\t\t\t\tstore.updateItem(newid || id, obj);\n\t\t\t\t});\n\t\t}\n\t\t\t\n\n\t\t//clean undo history, for the saved record\n\t\tif(this._settings.undoOnError && master._settings.undo)\n\t\t\tmaster.removeUndo(newid||id);\n\n\t\tthis.callEvent(\"onAfterSave\",[obj, id, details]);\n\t\tthis.callEvent(\"onAfter\"+status, [obj, id, details]);\n\n\t\treturn obj || {};\n\t},\n\tprocessResult: function(state, hash, details){\n\t\t//compatibility with custom json response\n\t\tvar error = (hash && (hash.status == \"error\" || hash.status == \"invalid\"));\n\t\tvar newid = (hash ? ( hash.newid || hash.id ) : false);\n\n\t\treturn this._innerProcessResult(error, state.id, newid, state.status, hash, details);\n\t},\n\t// process saving from result\n\t_processResult: function(state, text, data, loader){\n\t\tvar finalResult;\n\t\tthis.callEvent(\"onBeforeSync\", [state, text, data, loader]);\n\n\t\tif(isArray(state)){ //saveAll results\n\t\t\tfinalResult = [];\n\t\t\tstate.forEach((one) => {\n\t\t\t\tfinalResult.push(this.processResult(one, one, {}));\n\t\t\t});\n\t\t}\n\t\telse{\n\t\t\tif (loader === -1){\n\t\t\t\t//callback from promise\n\t\t\t\tfinalResult = this.processResult(state, data, {});\n\t\t\t} else {\n\t\t\t\tvar proxy = this._settings.url;\n\t\t\t\tif (proxy.$proxy && proxy.result){\n\t\t\t\t\tfinalResult = proxy.result(state, this._settings.master, this, text, data, loader) || {};\n\t\t\t\t} else {\n\t\t\t\t\tvar hash;\n\t\t\t\t\tif (text){\n\t\t\t\t\t\thash = data.json();\n\t\t\t\t\t\t//invalid response\n\t\t\t\t\t\tif (text && (hash === null || typeof hash == \"undefined\"))\n\t\t\t\t\t\t\thash = { status:\"error\" };\n\t\t\t\t\t}\n\t\t\t\t\tfinalResult = this.processResult(state, hash, {text:text, data:data, loader:loader});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.callEvent(\"onAfterSync\", [state, text, data, loader]);\n\t\treturn finalResult;\n\t},\n\n\n\t/*! if it's defined escape function - call it\n\t *\t@param value\n\t *\t\tvalue to escape\n\t *\t@return\n\t *\t\tescaped value\n\t **/\n\tescape: function(value) {\n\t\tif (this._settings.escape)\n\t\t\treturn this._settings.escape(value);\n\t\telse\n\t\t\treturn encodeURIComponent(value);\n\t},\n\tgetState:function(){\n\t\tif (!this._updates.length) return false;\n\t\tfor (var i = this._updates.length - 1; i >= 0; i--)\n\t\t\tif (this._updates[i]._in_progress)\n\t\t\t\treturn \"saving\";\n\n\t\treturn true;\n\t},\n\tgetItemState:function(id){\n\t\tvar index = this._get_stack_index(id);\n\t\treturn this._updates[index] || null;\n\t},\n\tsetItemState:function(id, state){\n\t\tif (state){\n\t\t\tthis._save_inner(id, null, \"update\");\n\t\t} else{\n\t\t\tvar index = this._get_stack_index(id);\n\t\t\tif (index > -1)\n\t\t\t\tthis._updates.splice(index, 1);\n\t\t}\n\t},\n\t_get_stack_index: function(id) {\n\t\tvar index = -1;\n\t\tfor (var i=0; i < this._updates.length; i++)\n\t\t\tif (this._updates[i].id == id) {\n\t\t\t\tindex = i;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\treturn index;\n\t}\n\n}, Settings, EventSystem, ValidateData);","import {extend, _to_array, uid, isUndefined, copy, isArray, bind} from \"../webix/helpers\";\nimport {$$} from \"../ui/core\";\nimport {assert} from \"../webix/debug\";\nimport {callEvent} from \"../webix/customevents\";\nimport i18n from \"../webix/i18n\";\n\nimport EventSystem from \"./eventsystem\";\nimport DataDriver from \"../load/drivers/index\";\n\n/*\n\tDataStore is not a behavior, it standalone object, which represents collection of data.\n\tCall provideAPI to map data API\n\n\t@export\n\t\texists\n\t\tgetIdByIndex\n\t\tgetIndexById\n\t\tget\n\t\tset\n\t\trefresh\n\t\tcount\n\t\tsort\n\t\tfilter\n\t\tnext\n\t\tprevious\n\t\tclearAll\n\t\tfirst\n\t\tlast\n*/\n\nfunction DataStore(){\n\tthis.name = \"DataStore\";\n\t\n\textend(this, EventSystem);\n\n\tthis.setDriver(\"json\");\t//default data source is an\n\tthis.pull = {};\t\t\t\t\t\t//hash of IDs\n\tthis.order = _to_array();\t\t//order of IDs\n\tthis._marks = {};\n}\n\nDataStore.prototype={\n\t//defines type of used data driver\n\t//data driver is an abstraction other different data formats - xml, json, csv, etc.\n\tsetDriver:function(type){\n\t\tassert(DataDriver[type],\"incorrect DataDriver\");\n\t\tthis.driver = DataDriver[type];\n\t},\n\t//process incoming raw data\n\t_parse:function(data){\n\t\tthis.callEvent(\"onParse\", [this.driver, data]);\n\n\t\tif (this._filter_order)\n\t\t\tthis.filter();\n\t\n\t\t//get size and position of data\n\t\tconst info = this.driver.getInfo(data);\n\n\t\tif (info.config)\n\t\t\tthis.callEvent(\"onServerConfig\",[info.config]);\n\n\t\tconst options = this.driver.getOptions(data);\n\t\tif (options)\n\t\t\tthis.callEvent(\"onServerOptions\", [options]);\n\n\t\t//get array of records\n\t\tconst recs = this.driver.getRecords(data);\n\n\t\tthis._inner_parse(info, recs);\n\n\t\t//in case of tree store we may want to group data\n\t\tif (this._scheme_group && this._group_processing && !this._not_grouped_order)\n\t\t\tthis._group_processing(this._scheme_group);\n\n\t\t//optional data sorting\n\t\tif (this._scheme_sort){\n\t\t\tthis.blockEvent();\n\t\t\tthis.sort(this._scheme_sort);\n\t\t\tthis.unblockEvent();\n\t\t}\n\n\t\tthis.callEvent(\"onStoreLoad\",[this.driver, data]);\n\t\t//repaint self after data loading\n\t\tthis.refresh();\n\t},\n\t_inner_parse:function(info, recs){\n\t\tlet from = info.from;\n\t\tlet subload = true;\n\t\tlet marks = false;\n\n\t\t//some data is loaded and new data doesn't have \"pos\" - assuming update\n\t\tif (!from && from !== 0 && this.order[0]){\n\t\t\tif (this._removeMissed){\n\t\t\t\t//update mode, create kill list\n\t\t\t\tmarks = {};\n\t\t\t\tfor (let i=0; i to){ //can be in case of backward shift-selection\n\t\t\tlet a=to; to=from; from=a;\n\t\t}\n\n\t\treturn this.getIndexRange(from,to);\n\t},\n\t//converts range of indexes to array of all IDs between them\n\tgetIndexRange:function(from,to){\n\t\tto = Math.min((to === 0 ? 0 : (to||Infinity)), this.count()-1);\n\n\t\tconst ret = _to_array(); //result of method is rich-array\n\t\tfor (let i = (from||0); i <= to; i++)\n\t\t\tret.push(this.getItem(this.order[i]));\n\t\treturn ret;\n\t},\n\t//returns total count of elements\n\tcount:function(){\n\t\treturn this.order.length;\n\t},\n\t//returns truy if item with such ID exists\n\texists:function(id){\n\t\treturn !!(this.pull[id]);\n\t},\n\t//nextmethod is not visible on component level, check DataMove.move\n\t//moves item from source index to the target index\n\tmove:function(sindex,tindex){\n\t\tassert(sindex>=0 && tindex>=0, \"DataStore::move\",\"Incorrect indexes\");\n\t\tif (sindex == tindex) return;\n\n\t\tconst id = this.getIdByIndex(sindex);\n\t\tconst obj = this.getItem(id);\n\n\t\tif (this._filter_order)\n\t\t\tthis._move_inner(this._filter_order, 0, 0, this.getIdByIndex(sindex), this.getIdByIndex(tindex));\n\n\t\tthis._move_inner(this.order, sindex, tindex);\n\t\t\n\t\t\n\t\t//repaint signal\n\t\tthis.callEvent(\"onStoreUpdated\",[id,obj,\"move\"]);\n\t},\n\t_move_inner:function(col, sindex, tindex, sid, tid){\n\t\tif (sid||tid){\n\t\t\tsindex = tindex = -1;\n\t\t\tfor (let i = 0; i < col.length; i++){\n\t\t\t\tif (col[i] == sid && sindex<0)\n\t\t\t\t\tsindex = i;\n\t\t\t\tif (col[i] == tid && tindex<0)\n\t\t\t\t\ttindex = i;\n\t\t\t}\n\t\t}\n\t\tconst id = col[sindex];\n\t\tcol.removeAt(sindex);\t//remove at old position\n\t\tcol.insertAt(id,Math.min(col.length, tindex));\t//insert at new position\n\t},\n\tscheme:function(config){\n\t\tthis._scheme = {};\n\t\tthis._scheme_save = config.$save;\n\t\tthis._scheme_init = config.$init||config.$change;\n\t\tthis._scheme_update = config.$update||config.$change;\n\t\tthis._scheme_serialize = config.$serialize;\n\t\tthis._scheme_group = config.$group;\n\t\tthis._scheme_sort = config.$sort;\n\t\tthis._scheme_export = config.$export;\n\n\t\t//ignore $-starting properties, as they have special meaning\n\t\tfor (let key in config)\n\t\t\tif (key.substr(0,1) != \"$\")\n\t\t\t\tthis._scheme[key] = config[key];\n\t},\n\timportData:function(target, silent){\n\t\tconst data = target ? (target.data || target) : [];\n\t\tthis._filter_order = null;\n\n\t\tif (typeof data.serialize == \"function\"){\n\t\t\tthis.order = _to_array([].concat(data.order));\n\n\t\t\t//make full copy, to preserve object properties\n\t\t\t//[WE-CAN-DO-BETTER]\n\t\t\tif (this._make_full_copy){\n\t\t\t\tthis._make_full_copy = false;\n\t\t\t\tconst oldpull = this.pull;\n\t\t\t\tthis.pull = {};\n\t\t\t\tfor (let key in data.pull){\n\t\t\t\t\tconst old = oldpull[key];\n\t\t\t\t\tthis.pull[key] = copy(data.pull[key]);\n\t\t\t\t\tif (old && old.open) this.pull[key].open = true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.pull = {};\n\t\t\t\tfor (let key in data.pull)\n\t\t\t\t\tthis.pull[key] = data.pull[key];\n\t\t\t}\n\n\t\t\tif (data.branch && this.branch){\n\t\t\t\tthis.branch = copy(data.branch);\n\t\t\t\tthis._filter_branch = null;\n\t\t\t}\n\n\t\t} else {\n\t\t\tthis.order = _to_array();\n\t\t\tthis.pull = {};\n\t\t\tlet id, obj;\n\n\t\t\tif (isArray(target))\n\t\t\t\tfor (let key=0; key data_size){\n\t\t\tassert(0, \"Warning\",\"DataStore:add\",\"Index of out of bounds\");\n\t\t\tindex = Math.min(order.length,index);\n\t\t}\n\t\tif (this.callEvent(\"onBeforeAdd\", [id, obj, index]) === false) return false;\n\n\t\tassert(!this.exists(id), \"Not unique ID\");\n\n\t\tthis.pull[id]=obj;\n\t\torder.insertAt(id,index);\n\t\tif (this._filter_order){\t//adding during filtering\n\t\t\t//we can't know the location of new item in full dataset, making suggestion\n\t\t\t//put at end of original dataset by default\n\t\t\tlet original_index = this._filter_order.length;\n\t\t\t//if some data exists, put at the same position in original and filtered lists\n\t\t\tif (this.order.length)\n\t\t\t\toriginal_index = Math.min((index || 0), original_index);\n\n\t\t\tthis._filter_order.insertAt(id,original_index);\n\t\t}\n\n\t\t//repaint signal\n\t\tthis.callEvent(\"onStoreUpdated\",[id,obj,\"add\"]);\n\t\tthis.callEvent(\"onAfterAdd\",[id,index]);\n\n\t\treturn obj.id;\n\t},\n\t\n\t//removes element from datastore\n\tremove:function(id){\n\t\t//id can be an array of IDs - result of getSelect, for example\n\t\tif (isArray(id)){\n\t\t\tfor (let i = 0; i < id.length; i++)\n\t\t\t\tthis.remove(id[i]);\n\t\t\treturn;\n\t\t}\n\t\tif (this.callEvent(\"onBeforeDelete\",[id]) === false) return false;\n\t\t\n\t\tassert(this.exists(id), \"Not existing ID in remove command\"+id);\n\n\t\tconst obj = this.getItem(id); //save for later event\n\t\t//clear from collections\n\t\tthis.order.remove(id);\n\t\tif (this._filter_order) \n\t\t\tthis._filter_order.remove(id);\n\t\t\t\n\t\tdelete this.pull[id];\n\t\tif (this._marks[id])\n\t\t\tdelete this._marks[id];\n\n\t\t//repaint signal\n\t\tthis.callEvent(\"onStoreUpdated\",[id,obj,\"delete\"]);\n\t\tthis.callEvent(\"onAfterDelete\",[id]);\n\t},\n\t//deletes all records in datastore\n\tclearAll:function(soft){\n\t\t//instead of deleting one by one - just reset inner collections\n\t\tthis.pull = {};\n\t\tthis._marks = {};\n\t\tthis.order = _to_array();\n\t\t//this.feed = null;\n\t\tthis._filter_order = null;\n\t\tif (!soft)\n\t\t\tthis.url = null;\n\t\tthis.callEvent(\"onClearAll\",[soft]);\n\t\tthis.refresh();\n\t},\n\t//converts index to id\n\tgetIdByIndex:function(index){\n\t\tassert(index >= 0,\"DataStore::getIdByIndex Incorrect index\");\n\t\treturn this.order[index];\n\t},\n\t//converts id to index\n\tgetIndexById:function(id){\n\t\tif (!this.pull[id])\n\t\t\treturn -1;\n\t\telse\n\t\t\treturn this.order.find(id);\t//slower than getIdByIndex\n\t},\n\t//returns ID of next element\n\tgetNextId:function(id,step){\n\t\treturn this.order[this.getIndexById(id)+(step||1)];\n\t},\n\t//returns ID of first element\n\tgetFirstId:function(){\n\t\treturn this.order[0];\n\t},\n\t//returns ID of last element\n\tgetLastId:function(){\n\t\treturn this.order[this.order.length-1];\n\t},\n\t//returns ID of previous element\n\tgetPrevId:function(id,step){\n\t\treturn this.order[this.getIndexById(id)-(step||1)];\n\t},\n\t/*\n\t\tsort data in collection\n\t\t\tby - settings of sorting\n\n\t\tor\n\t\t\tby - array of settings\n\n\t\tor\n\n\t\t\tby - sorting function\n\t\t\tdir - \"asc\" or \"desc\"\n\n\t\tor\n\n\t\t\tby - property\n\t\t\tdir - \"asc\" or \"desc\"\n\t\t\tas - type of sortings\n\n\t\tSorting function will accept 2 parameters and must return 1,0,-1, based on desired order\n\n\t\treturns true if sorting was successful, false otherwise\n\t*/\n\tsort:function(by, dir, as){\n\t\tlet parameters;\n\t\tlet sort = by;\n\n\t\tif (isArray(sort)){\n\t\t\tsort = sort.map(a => this._sort_init(a));\n\t\t\tparameters = [sort];\n\t\t} else {\n\t\t\tsort = this._sort_init(by, dir, as);\n\t\t\tparameters = [sort.by, sort.dir, sort.as, sort];\n\t\t}\n\n\t\tif (!this.callEvent(\"onBeforeSort\", parameters)) return false;\n\t\tconst sorter = this.sorting.create(sort);\n\n\t\tthis.order = this._sort_core(sorter, this.order);\n\t\tif (this._filter_order)\n\t\t\tthis._filter_order = this._sort_core(sorter, this._filter_order);\n\t\tif (this._filter_branch)\t//treestore\n\t\t\tthis._sort_core(sorter, this.order, this._filter_branch);\n\n\t\t//repaint self\n\t\tthis.refresh();\n\n\t\tthis.callEvent(\"onAfterSort\", parameters);\n\t\treturn true;\n\t},\n\t_sort_init:function(by, dir, as){\n\t\tlet sort = by;\n\n\t\tif (typeof by == \"function\")\n\t\t\tsort = {as:by, dir:dir};\n\t\telse if (typeof by == \"string\")\n\t\t\tsort = {by:by, dir:dir, as:as};\n\n\t\tif (typeof sort.by == \"string\")\n\t\t\tsort.by = sort.by.replace(/#/g,\"\");\n\n\t\treturn sort;\n\t},\n\t_sort_core:function(sorter, order){\n\t\tif (this.order.length){\n\t\t\tconst pre = order.splice(0, this.$freeze);\n\t\t\t//get array of IDs\n\t\t\tconst neworder = _to_array();\n\t\t\tfor (let i = order.length-1; i>=0; i--)\n\t\t\t\tneworder[i] = this.pull[order[i]];\n\n\t\t\tneworder.sort(sorter);\n\t\t\treturn _to_array(pre.concat(neworder.map(function(obj){ \n\t\t\t\tassert(obj, \"Client sorting can't be used with dynamic loading\");\n\t\t\t\treturn this.id(obj);\n\t\t\t},this)));\n\t\t}\n\t\treturn order;\n\t},\n\t/*\n\t\tFilter datasource\n\t\t\n\t\ttext - property, by which filter\n\t\tvalue - filter mask\n\t\t\n\t\tor\n\t\t\n\t\ttext - filter method\n\t\t\n\t\tFilter method will receive data object and must return true or false\n\t*/\n\t_filter_reset:function(preserve){\n\t\t//remove previous filtering , if any\n\t\tif (this._filter_order && !preserve){\n\t\t\tthis.order = this._filter_order;\n\t\t\tdelete this._filter_order;\n\t\t}\n\t},\n\t_filter_core:function(filter, value, preserve){\n\t\tconst neworder = _to_array();\n\t\tconst freeze = this.$freeze || 0;\n\n\t\tfor (let i=0; i < this.order.length; i++){\n\t\t\tconst id = this.order[i];\n\t\t\tif (i < freeze || filter(this.getItem(id),value))\n\t\t\t\tneworder.push(id);\n\t\t}\n\t\t//set new order of items, store original\n\t\tif (!preserve || !this._filter_order)\n\t\t\tthis._filter_order = this.order;\n\t\tthis.order = neworder;\n\t},\n\tfind:function(config, first){\n\t\tconst result = [];\n\n\t\tfor(let i in this.pull){\n\t\t\tconst data = this.pull[i];\n\n\t\t\tlet match = true;\n\t\t\tif (typeof config == \"object\"){\n\t\t\t\tfor (let key in config)\n\t\t\t\t\tif (data[key] != config[key]){\n\t\t\t\t\t\tmatch = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t} else if (!config(data))\n\t\t\t\tmatch = false;\n\n\t\t\tif (match)\n\t\t\t\tresult.push(data);\n\t\t\t\n\t\t\tif (first && result.length)\n\t\t\t\treturn result[0];\n\t\t}\n\n\t\treturn first ? null : result;\n\t},\n\tfilter:function(text,value,preserve){\n\t\t//unfilter call but we already in not-filtered state\n\t\tif (!text && !this._filter_order && !this._filter_branch) return;\n\t\tif (!this.callEvent(\"onBeforeFilter\", [text, value])) return;\n\t\t\n\t\tthis._filter_reset(preserve);\n\t\tif (!this.order.length) return;\n\n\t\t//if text not define -just unfilter previous state and exit\n\t\tif (text){\n\t\t\tlet filter = text;\n\t\t\tvalue = value||\"\";\n\t\t\tif (typeof text == \"string\"){\n\t\t\t\ttext = text.replace(/#/g,\"\");\n\t\t\t\tif (typeof value == \"function\")\n\t\t\t\t\tfilter = function(obj){\n\t\t\t\t\t\treturn value(obj[text]);\n\t\t\t\t\t};\n\t\t\t\telse{\n\t\t\t\t\tvalue = value.toString().toLowerCase();\n\t\t\t\t\tfilter = function(obj,value){\t//default filter - string start from, case in-sensitive\n\t\t\t\t\t\tassert(obj, \"Client side filtering can't be used with dynamic loading\");\n\t\t\t\t\t\treturn (obj[text]||\"\").toString().toLowerCase().indexOf(value)!=-1;\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._filter_core(filter, value, preserve, this._filterMode);\n\t\t}\n\t\t//repaint self\n\t\tthis.refresh();\n\t\t\n\t\tthis.callEvent(\"onAfterFilter\", []);\n\t},\n\t/*\n\t\tIterate through collection\n\t*/\n\t_obj_array:function(){\n\t\tconst data = [];\n\t\tfor (let i = this.order.length - 1; i >= 0; i--)\n\t\t\tdata[i]=this.pull[this.order[i]];\n\n\t\treturn data;\n\t},\n\teach:function(method, master, all){\n\t\tlet order = this.order;\n\t\tif (all)\n\t\t\torder = this._filter_order || order;\n\n\t\tfor (let i = 0; i b && a ? \" \" : \"\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!silent) \n\t\t\t\tthis.refresh(id);\n\t\t}\n\t},\n\tgetMark:function(id, mark){\n\t\tconst obj = this._marks[id];\n\t\treturn (obj ? obj[mark] : false);\n\t},\n\tclearMark:function(name, css, silent){\n\t\tfor (const id in this._marks){\n\t\t\tconst obj = this._marks[id];\n\t\t\tif (obj[name]){\n\t\t\t\tdelete obj[name];\n\t\t\t\tif (css && obj.$css){\n\t\t\t\t\tconst re = new RegExp(\"(\\\\s|^)\"+name+\"(\\\\s|$)\");\n\t\t\t\t\tobj.$css = obj.$css.replace(re, (v,b,a) => b && a ? \" \" : \"\");\n\t\t\t\t}\n\t\t\t\tif (!silent)\n\t\t\t\t\tthis.refresh(id);\n\t\t\t}\n\t\t}\n\t},\n\t/*\n\t\tserializes data to a json object\n\t*/\n\tserialize: function(all){\n\t\tlet ids = this.order;\n\t\tif (all && this._filter_order)\n\t\t\tids = this._filter_order;\n\n\t\tconst result = [];\n\t\tfor(let i=0; i< ids.length;i++) {\n\t\t\tlet el = this.pull[ids[i]];\n\t\t\tif (this._scheme_serialize){\n\t\t\t\tel = this._scheme_serialize(el);\n\t\t\t\tif (el===false) continue;\n\t\t\t}\n\t\t\tresult.push(el);\n\t\t}\n\t\treturn result;\n\t},\n\tsorting:{\n\t\tcreate:function(config){\n\t\t\tif (isArray(config))\n\t\t\t\treturn this._multi(config);\n\t\t\treturn this._dir(config.dir, this._by(config.by, config.as));\n\t\t},\n\t\tas:{\n\t\t\t//handled by dataFeed\n\t\t\t\"server\":function(){\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\t\"date\":function(a,b){\n\t\t\t\ta = a-0; b = b-0;\n\t\t\t\tif (isNaN(b)) return 1;\n\t\t\t\tif (isNaN(a)) return -1;\n\n\t\t\t\treturn a>b?1:(ab?1:(ab?1:(ab?1:(ab?1:(a this._dir(c.dir, this._by(c.by, c.as)));\n\n\t\t\treturn function(a,b){\n\t\t\t\tlet result, i = 0;\n\t\t\t\tdo {\n\t\t\t\t\tresult = methods[i](a,b);\n\t\t\t\t} while(!result && methods[++i]);\n\t\t\t\treturn result;\n\t\t\t};\n\t\t},\n\t\t_by:function(prop, method){\n\t\t\tlet customMethod;\n\n\t\t\tif (typeof method != \"function\")\n\t\t\t\tmethod = this.as[method||\"string\"];\n\t\t\telse\n\t\t\t\tcustomMethod = true;\n\n\t\t\tassert(method, \"Invalid sorting method\");\n\t\t\treturn function(a,b){\n\t\t\t\tif(!customMethod){\n\t\t\t\t\ta = a[prop];\n\t\t\t\t\tb = b[prop];\n\t\t\t\t}\n\t\t\t\treturn method(a, b, prop);\n\t\t\t};\n\t\t},\n\t\t_dir:function(prop, method){\n\t\t\tif (prop == \"asc\" || !prop)\n\t\t\t\treturn method;\n\t\t\treturn function(a,b){\n\t\t\t\treturn method(a,b)*-1;\n\t\t\t};\n\t\t}\n\t}\n};\n\nexport default DataStore;","import {isArray, _to_array} from \"../webix/helpers\";\n\nconst DataState = {\n\tgetState:function(){\n\t\tvar cols_n = this.config.columns.length;\n\t\tvar columns = this.config.columns;\n\t\tvar settings = { \n\t\t\tids:[],\n\t\t\tsize:[],\n\t\t\tselect:this.getSelectedId(true),\n\t\t\tscroll:this.getScrollState()\n\t\t};\n\t\tfor(var i = 0; i < cols_n; i++){\n\t\t\tvar col = columns[i];\n\t\t\tsettings.ids.push(col.id);\n\t\t\tsettings.size.push((col.fillspace || col.adjust) ? -1 : col.width);\n\t\t}\n\n\t\tsettings.order = [].concat(this._hidden_column_order.length ? this._hidden_column_order : settings.ids);\n\n\t\tif (this._last_order.length){\n\t\t\tvar sort = this._last_order.map(id => {\n\t\t\t\treturn { id:id, dir:this._last_sorted[id].dir };\n\t\t\t});\n\t\t\tsettings.sort = (sort.length == 1) ? sort[0] : sort;\n\t\t}\n\n\t\t//this method will try to access the rendered values\n\t\t//just ignore it if grid is not rendered yet\n\t\tif (this._filter_elements && this._dtable_fully_ready) {\n\t\t\tvar filter = {};\n\t\t\tvar any_filter = 0;\n\t\t\tfor (let key in this._filter_elements) {\n\t\t\t\tif (this._hidden_column_hash[key]) continue;\n\n\t\t\t\tvar f = this._filter_elements[key];\n\t\t\t\tf[1].value = filter[key] = f[2].getValue(f[0]);\n\t\t\t\tany_filter = 1;\n\t\t\t}\n\t\t\tif (any_filter)\n\t\t\t\tsettings.filter=filter;\n\t\t}\n\n\t\tsettings.hidden = [];\n\t\tfor (let key in this._hidden_column_hash)\n\t\t\tsettings.hidden.push(key);\n\t\t\n\t\treturn settings;\n\t},\n\tsetState:function(obj){\n\t\tconst columns = this.config.columns;\n\t\tif(!obj) return;\n\n\t\tthis.markSorting();\n\t\tthis._last_order = [];\n\t\tthis._last_sorted = {};\n\n\t\tthis.blockEvent();\n\n\t\tif (obj.order && obj.order.length){\n\t\t\tthis._hidden_column_order = _to_array([].concat(obj.order));\n\t\t\tconst rs = obj.order.length - this._settings.rightSplit;\n\t\t\tthis._hidden_split = [this._settings.leftSplit, rs, this._settings.rightSplit];\n\t\t}\n\n\t\tif (obj.hidden){\n\t\t\tconst hihash = {};\n\t\t\tfor (let i=0; i 0 && col.width != obj.size[i]){\n\t\t\t\t\tdelete col.fillspace;\n\t\t\t\t\tdelete col.adjust;\n\t\t\t\t\tthis._setColumnWidth( i, obj.size[i], true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\tthis.unblockEvent();\n\n\t\tconst silent = !(this._settings.leftSplit || this._settings.rightSplit);\n\t\tthis._updateColsSizeSettings(silent);\n\t\tthis.callEvent(\"onStructureUpdate\", []);\n\n\t\tconst server = this._skip_server_op = { };\n\t\tif (obj.sort){\n\t\t\tlet sort = obj.sort, multi = true;\n\t\t\tif (!isArray(sort)){\n\t\t\t\tsort = [sort]; multi = false;\n\t\t\t}\n\t\t\tfor (let i=0; i {\n\t\t\t\tif (server.sort)\n\t\t\t\t\tthis._on_after_sort(server.$params);\n\t\t\t\tif (server.filter)\n\t\t\t\t\tthis._on_after_filter();\n\t\t\t});\n\n\t\tif (obj.select && this.select){\n\t\t\tlet select = obj.select;\n\t\t\tthis.unselect();\n\t\t\tfor (let i = 0; i < select.length; i++)\n\t\t\t\tif (!select[i].row || this.exists(select[i].row))\n\t\t\t\t\tthis._select(select[i], true);\n\t\t}\n\n\t\tif (obj.scroll)\n\t\t\tthis.scrollTo(obj.scroll.x, obj.scroll.y);\n\t}\n};\n\nexport default DataState;","import {pos, offset} from \"../webix/html\";\nimport {use} from \"../services\";\nimport Touch from \"../core/touch\";\nimport {extend, delay, _power_array, isArray} from \"../webix/helpers\";\nimport {assert} from \"../webix/debug\";\nimport DragControl from \"../core/dragcontrol\";\nimport AutoScroll from \"../core/autoscroll\";\n\n\n/*\n\tBehavior:DragItem - adds ability to move items by dnd\n\t\n\tdnd context can have next properties\n\t\tfrom - source object\n\t\tto - target object\n\t\tsource - id of dragged item(s)\n\t\ttarget - id of drop target, null for drop on empty space\n\t\tstart - id from which DND was started\n*/\n\nconst DragItem ={\n\t//helper - defines component's container as active zone for dragging and for dropping\n\t_initHandlers:function(obj, source, target){\n\t\tif (!source) DragControl.addDrop(obj._contentobj,obj,true);\n\t\tif (!target) DragControl.addDrag(obj._contentobj,obj);\n\t\tthis.attachEvent(\"onDragOut\",function(a,b){ this.$dragMark(a,b); });\n\t\tthis.attachEvent(\"onBeforeAutoScroll\",function(){\n\t\t\tvar context = DragControl.getContext();\n\t\t\treturn !!(DragControl._active && context && (context.to === this || this._auto_scroll_force));\n\t\t});\n\t},\n\tdrag_setter:function(value){\n\t\tif (value){\n\t\t\textend(this, AutoScroll, true);\n\t\t\tif (value == \"order\" || value == \"move\")\n\t\t\t\textend(this, use(\"DragOrder\"), true);\n\t\t\tif (value == \"inner\" || value == \"order\")\n\t\t\t\tthis._inner_drag_only = true;\n\n\t\t\tthis._initHandlers(this, value == \"source\", value == \"target\");\n\t\t\tdelete this.drag_setter;\t//prevent double initialization\n\t\t}\n\t\treturn value;\n\t},\n\t/*\n\t\ts - source html element\n\t\tt - target html element\n\t\td - drop-on html element ( can be not equal to the target )\n\t\te - native html event \n\t*/\n\t//called when drag moved over possible target\n\t$dragIn:function(s,t,e){\n\t\tvar id = this.locate(e) || null;\n\t\tvar context = DragControl._drag_context;\n\n\t\t//in inner drag mode - ignore dnd from other components\n\t\tif ((this._inner_drag_only || context.from._inner_drag_only) && context.from !== this) return false;\n\n\t\tvar to = DragControl.getMaster(t);\n\t\t//previous target\n\t\tvar html = (this.getItemNode(id, e)||this._dataobj);\n\t\t//prevent double processing of same target\n\t\tif (html == DragControl._landing) return html;\n\t\tcontext.target = id;\n\t\tcontext.to = to;\n\n\t\tif (this._auto_scroll_delay)\n\t\t\tthis._auto_scroll_delay = window.clearTimeout(this._auto_scroll_delay);\n\n\t\tconst fragile = (this._touch_scroll && !this._settings.prerender);\n\t\tif (this._settings.dragscroll !== false && !fragile)\n\t\t\tthis._auto_scroll_delay = delay(function(pos,id){\n\t\t\t\tthis._drag_pause(id);\n\t\t\t\tthis._auto_scroll(pos,id);\n\t\t\t}, this, [pos(e), id], 250);\n\n\t\tif (!this.$dropAllow(context, e) || !this.callEvent(\"onBeforeDragIn\",[context, e])){\n\t\t\tcontext.to = context.target = null;\n\t\t\tif (this._auto_scroll_delay)\n\t\t\t\tthis._auto_scroll_delay = window.clearTimeout(this._auto_scroll_delay);\n\t\t\treturn null;\n\t\t}\n\t\t//mark target only when landing confirmed\n\t\tthis.$dragMark(context,e);\n\t\treturn html;\n\t},\n\t$dropAllow:function(){\n\t\treturn true;\n\t},\n\t_drag_pause:function(){\n\t\t//may be reimplemented in some components\n\t\t// tree for example\n\t},\n\t_target_to_id:function(target){\n\t\treturn target && typeof target === \"object\" ? target.toString() : target;\n\t},\n\t//called when drag moved out from possible target\n\t$dragOut:function(s,t,n,e){\n\t\tvar id = (this._viewobj.contains(n) ? this.locate(e): null) || null;\n\t\tvar context = DragControl._drag_context;\n\n\t\t//still over previous target\n\t\tif ((context.target||\"\").toString() == (id||\"\").toString()) return null;\n\t\tif (this._auto_scroll_delay)\n\t\t\tthis._auto_scroll_delay = window.clearTimeout(this._auto_scroll_delay);\n\n\t\t//unmark previous target\n\t\tcontext.target = context.to = null;\n\t\tthis.callEvent(\"onDragOut\",[context,e]);\n\t\treturn null;\n\t},\n\t//called when drag moved on target and button is released\n\t$drop:function(s,t,e){\n\t\tvar context = DragControl._drag_context;\n\t\t//finalize context details\n\t\tcontext.to = this;\n\t\tthis._define_index(s,t,context);\n\n\t\t//unmark last target\n\t\tthis.$dragMark({}, e);\n\n\t\tif( context.from && context.from != context.to && context.from.callEvent ){\n\t\t\tif(!context.from.callEvent(\"onBeforeDropOut\", [context,e]))\n\t\t\t\treturn;\n\t\t}\n\n\t\tif (!this.callEvent(\"onBeforeDrop\",[context,e])) return;\n\t\t//moving\n\t\tthis._context_to_move(context,e);\n\t\t\n\t\tthis.callEvent(\"onAfterDrop\",[context,e]);\n\t},\n\t_define_index:function(s,t,context){\n\t\tvar target = this._target_to_id(context.target);\n\n\t\tif (this.getBranchIndex){\n\t\t\tif (target){\n\t\t\t\tcontext.parent = this.getParentId(target);\n\t\t\t\tcontext.index = this.getBranchIndex(target);\n\t\t\t} else context.index = -1;\n\t\t} else\n\t\t\tcontext.index = target?this.getIndexById(target):this.count();\n\t},\n\t_context_to_move:function(context){\n\t\tassert(context.from, \"Unsopported d-n-d combination\");\n\t\tif (context.from && context.from.move){\t//from different component with item dnd\n\t\t\tvar details = { parent: context.parent, mode: context.pos };\n\t\t\tcontext.from.move(context.source,context.index,context.to, details);\n\t\t}\n\t},\n\t$longTouchLimit: true,\n\t_getDragItemPos: function(pos,e){\n\t\tif (this.getItemNode){\n\t\t\tvar id = this.locate(e, true);\n\t\t\t//in some case, node may be outiside of dom ( spans in datatable for example )\n\t\t\t//so getItemNode can return null\n\t\t\tvar node = id ? this.getItemNode(id) : null;\n\t\t\treturn node ? offset(node) : node;\n\t\t}\n\t},\n\t//called when drag action started\n\t$drag:function(s,e){\n\t\tvar id = this.locate(e, true);\n\t\tif (id){\n\t\t\tvar list = [id];\n\n\t\t\tif (this.getSelectedId){ //has selection model\n\t\t\t\t//if dragged item is one of selected - drag all selected\n\t\t\t\tvar selection = this.getSelectedId(true, true);\t\n\n\t\t\t\tif (selection && selection.length > 1 && _power_array.find.call(selection,id)!=-1){\n\t\t\t\t\tvar hash = {}; \n\t\t\t\t\tlist = [];\n\t\t\t\t\tfor (let i=0;i 1 )\n\t\t\thtml = this._toMultipleHTML(html, context.source.length);\n\t\treturn html;\n\t},\n\t_toMultipleHTML:function(html, len){\n\t\thtml = \"
\"+html+\"
\";\n\t\tlet multiple = \"
\";\n\t\tif ( len > 2 )\n\t\t\tmultiple = \"
\" + multiple;\n\t\treturn multiple+html+\"\"+len+\"\";\n\t},\n\t$dragMark:function(context){\n\t\tvar target = null;\n\t\tif (context.target)\n\t\t\ttarget = this._target_to_id(context.target);\n\n\t\t//touch webkit will stop touchmove event if source node removed\n\t\tif (this._marked && this._marked != target){\n\t\t\tthis._remove_css([this._marked], \"webix_drag_over\", true);\n\t\t\tthis._marked = null;\n\t\t}\n\n\t\tif (!this._marked && target){\n\t\t\tthis._marked = target;\n\t\t\tthis._add_css([target], \"webix_drag_over\", true);\n\t\t\treturn target;\n\t\t}\n\t\t\n\t\treturn !!context.to;\n\t},\n\t_add_css:function(source, css){\n\t\tfor (let i=0; i undoLimit)\n\t\t\t\tthis._undoHistory.splice(0,1);\n\t\t\tif(!this._skipCursorInc)\n\t\t\t\tthis._undoCursor = this._undoHistory.length - 1;\n\t\t}\n\t},\n\tignoreUndo: function(func, master){\n\t\tthis._skipHistory = true;\n\t\tfunc.call(master||this);\n\t\tthis._skipHistory = false;\n\t},\n\tremoveUndo: function(id){\n\t\tfor( var i = this._undoHistory.length-1; i >=0; i--){\n\t\t\tif(this._undoHistory[i].id == id){\n\t\t\t\tif(this._undoHistory[i].action == \"id\"){\n\t\t\t\t\tid = this._undoHistory[i].data;\n\t\t\t\t}\n\t\t\t\tthis._undoHistory.removeAt(i);\n\t\t\t}\n\t\t}\n\t\tthis._undoCursor = this._undoHistory.length - 1;\n\t},\n\tundo: function(id){\n\t\tif(id){\n\t\t\tthis.ignoreUndo(function(){\n\t\t\t\tvar data, i;\n\t\t\t\tfor( i = this._undoHistory.length-1; !data && i >=0; i--){\n\t\t\t\t\tif(this._undoHistory[i].id == id)\n\t\t\t\t\t\tdata = this._undoHistory[i];\n\t\t\t\t}\n\n\t\t\t\tif(data){\n\t\t\t\t\t/*if(data.action == \"id\")\n\t\t\t\t\t\tid = data.data;*/\n\t\t\t\t\tthis._undoAction(data);\n\t\t\t\t\tthis._undoHistory.removeAt(i+1);\n\t\t\t\t\tthis._undoCursor = this._undoHistory.length - 1;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\telse{\n\t\t\tvar data = this._undoHistory[this._undoCursor];\n\t\t\tif(data){\n\t\t\t\tthis.ignoreUndo(function(){\n\t\t\t\t\tthis._undoAction(data);\n\t\t\t\t\tthis._undoHistory.removeAt(this._undoCursor);\n\t\t\t\t});\n\t\t\t\tthis._undoCursor--;\n\t\t\t\t/*if(data.action == \"id\")\n\t\t\t\t\tthis.undo();*/\n\t\t\t}\n\t\t}\n\t},\n\t_undoAction: function(obj){\n\t\tif(obj.action == \"delete\"){\n\t\t\tvar branch = null,\n\t\t\t\tparentId = obj.data.$parent;\n\n\t\t\tif(obj.data.$branch){\n\t\t\t\tbranch = {\n\t\t\t\t\tparent: obj.id,\n\t\t\t\t\tdata: copy(obj.data.$branch)\n\t\t\t\t};\n\t\t\t\tdelete obj.data.$branch;\n\t\t\t\tif(parentId && !this.data.pull[parentId])\n\t\t\t\t\tparentId = 0;\n\t\t\t}\n\n\t\t\tthis.add(obj.data, obj.data.$index, parentId);\n\t\t\tif(branch){\n\t\t\t\tthis.parse(branch);\n\t\t\t}\n\t\t}\n\t\telse if(obj.action == \"add\"){\n\t\t\tthis.remove(obj.id);\n\t\t}\n\t\telse if(obj.action == \"update\"){\n\t\t\tthis.updateItem(obj.id, obj.data);\n\t\t}\n\t\telse if(obj.action == \"move\"){\n\t\t\tif(obj.data.$parent){\n\t\t\t\tif(this.getItem(obj.data.$parent))\n\t\t\t\t\tthis.move(obj.id, obj.data.$index, null, {parent: obj.data.$parent});\n\t\t\t}\n\t\t\telse\n\t\t\t\tthis.move(obj.id, obj.data.$index);\n\t\t}\n\t\t/*else if(obj.action == \"id\"){\n\t\t\tthis.data.changeId(obj.id, obj.data);\n\t\t}*/\n\t}\n};\n\nexport default Undo;","import {create} from \"../webix/html\";\nimport {isArray, isUndefined, copy, toNode, delay, extend} from \"../webix/helpers\";\nimport {ui, $$} from \"../ui/core\";\nimport i18n from \"../webix/i18n\";\nimport {_event} from \"../webix/htmlevents\";\nimport {assert} from \"../webix/debug\";\nimport {callEvent} from \"../webix/customevents\";\n\nfunction init_suggest(editor, input){\n\tconst suggest = editor.config.suggest;\n\tif (suggest){\n\t\tconst box = editor.config.suggest = create_suggest(suggest);\n\t\tconst boxobj = $$(box);\n\t\tif (boxobj && input)\n\t\t\tboxobj.linkInput(input);\n\t\treturn boxobj;\n\t}\n}\n\nfunction attach_editend(suggest){\n\tif (suggest && suggest.setMasterValue && !suggest._editor_initialized){\n\t\tsuggest._editor_initialized = true;\n\t\tsuggest.attachEvent(\"onValueSuggest\", function(){\n\t\t\tdelay(()=>callEvent(\"onEditEnd\", []));\n\t\t});\n\t}\n}\n\nfunction create_suggest(config){\n\tif (typeof config == \"string\") return config;\n\tif (config.linkInput) return config._settings.id;\n\n\tif (typeof config == \"object\"){\n\t\tif (isArray(config))\n\t\t\tconfig = { data: config };\n\t\tconfig.view = config.view || \"suggest\";\n\t} else if (config === true)\n\t\tconfig = { view:\"suggest\" };\n\n\tconst obj = ui(config);\n\treturn obj.config.id;\n}\n\nfunction getLabel(config){\n\tconst text = (config.header && config.header[0]) ? config.header[0].text : config.editValue||config.label;\n\treturn (text || \"\").toString().replace(/<[^>]*>/g, \"\");\n}\n\n/*\nthis.node - html node, available after render call\nthis.config - editor config\nthis.value - original value\nthis.popup - id of popup \n*/\nconst editors = {\n\t\"text\":{\n\t\tfocus:function(){\n\t\t\tthis.getInputNode(this.node).focus();\n\t\t\tthis.getInputNode(this.node).select();\n\t\t},\n\t\tgetValue:function(){\n\t\t\treturn this.getInputNode(this.node).value;\n\t\t},\n\t\tsetValue:function(value){\n\t\t\tconst input = this.getInputNode(this.node);\n\t\t\tinput.value = value;\n\n\t\t\tconst suggest = init_suggest(this, input);\n\t\t\tattach_editend(suggest);\n\t\t},\n\t\tgetInputNode:function(){\n\t\t\treturn this.node.firstChild;\n\t\t},\n\t\trender:function(){\n\t\t\treturn create(\"div\", {\n\t\t\t\t\"class\":\"webix_dt_editor\"\n\t\t\t}, \"\");\n\t\t}\n\t},\n\t\"inline-checkbox\":{\n\t\trender:function(){ return {}; },\n\t\tgetValue:function(){\n\t\t\treturn this.node.checked;\n\t\t},\n\t\tsetValue:function(){},\n\t\tfocus:function(){\n\t\t\tthis.node.focus();\n\t\t},\n\t\tgetInputNode:function(){},\n\t\t$inline:true\n\t},\n\t\"inline-text\":{\n\t\trender:function(){ return {}; },\n\t\tgetValue:function(){\n\t\t\treturn this.node.value;\n\t\t},\n\t\tsetValue:function(){},\n\t\tfocus:function(){\n\t\t\tthis.node.focus();\n\t\t\tthis.node.select();\n\t\t},\n\t\tgetInputNode:function(){},\n\t\t$inline:true\n\t},\n\t\"checkbox\":{\n\t\tfocus:function(){\n\t\t\tthis.getInputNode().focus();\n\t\t},\n\t\tgetValue:function(){\n\t\t\treturn this.getInputNode().checked;\n\t\t},\n\t\tsetValue:function(value){\n\t\t\tthis.getInputNode().checked = !!value;\n\t\t},\n\t\tgetInputNode:function(){\n\t\t\treturn this.node.firstChild.firstChild;\n\t\t},\n\t\trender:function(){\n\t\t\treturn create(\"div\", {\n\t\t\t\t\"class\":\"webix_dt_editor\"\n\t\t\t}, \"
\");\n\t\t}\n\t},\n\t\"select\":{\n\t\tfocus:function(){\n\t\t\tthis.getInputNode().focus();\n\t\t},\n\t\tgetValue:function(){\n\t\t\treturn this.getInputNode().value;\n\t\t},\n\t\tsetValue:function(value){\n\t\t\tthis.getInputNode().value = value;\n\t\t},\n\t\tgetInputNode:function(){\n\t\t\treturn this.node.firstChild;\n\t\t},\n\t\trender:function(){\n\t\t\tlet html = \"\";\n\t\t\tconst options = this.config.options || this.config.collection;\n\t\t\tassert(options,\"options not defined for select editor\");\n\n\t\t\tif (options.data && options.data.each)\n\t\t\t\toptions.data.each(function(obj){\n\t\t\t\t\thtml +=\"\";\n\t\t\t\t});\n\t\t\telse {\n\t\t\t\tif (isArray(options)){\n\t\t\t\t\tfor (let i = 0; i < options.length; i++){\n\t\t\t\t\t\tconst rec = options[i];\n\t\t\t\t\t\tconst isplain = isUndefined(rec.id);\n\t\t\t\t\t\tconst id = isplain ? rec : rec.id;\n\t\t\t\t\t\tconst label = isplain ? rec : rec.value;\n\n\t\t\t\t\t\thtml +=\"\";\n\t\t\t\t\t}\n\t\t\t\t} else for (let key in options){\n\t\t\t\t\thtml +=\"\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn create(\"div\", {\n\t\t\t\t\"class\":\"webix_dt_editor\"\n\t\t\t}, \"\");\n\t\t}\n\t},\n\tpopup:{\n\t\tfocus:function(){\n\t\t\tthis.getInputNode().focus();\n\t\t},\n\t\tdestroy:function(){\n\t\t\tthis.getPopup().hide();\n\t\t},\n\t\tgetValue:function(){\n\t\t\treturn this.getInputNode().getValue()||\"\";\n\t\t},\n\t\tsetValue:function(value){\n\t\t\tthis.getPopup().show(this.node);\n\t\t\tthis.getInputNode().setValue(value);\n\t\t},\n\t\tgetInputNode:function(){\n\t\t\treturn this.getPopup().getChildViews()[0];\n\t\t},\n\t\tgetPopup:function(){\n\t\t\tlet id = this.config.$popup;\n\n\t\t\tif (!(id && $$(id)))\n\t\t\t\tid = this.config.$popup = this.createPopup();\n\n\t\t\treturn $$(id);\n\t\t},\n\t\tcreatePopup:function(){\n\t\t\tconst popup = this.config.popup || this.config.suggest;\n\t\t\tif (popup){\n\t\t\t\tlet pobj;\n\t\t\t\tif (typeof popup == \"object\" && !popup.name){\n\t\t\t\t\tpopup.view = popup.view || \"suggest\";\n\t\t\t\t\tpobj = ui(copy(popup));\n\t\t\t\t} else\n\t\t\t\t\tpobj = $$(popup);\n\n\t\t\t\t//custom popup may be linked already\n\t\t\t\tif(!pobj._linked){\n\t\t\t\t\tif (pobj.linkInput)\n\t\t\t\t\t\tpobj.linkInput(document.body);\n\t\t\t\t\telse if(this.linkInput)\n\t\t\t\t\t\tthis.linkInput(document.body);\n\t\t\t\t\tpobj._linked = true;\n\t\t\t\t}\n\t\t\t\tattach_editend(pobj);\n\n\t\t\t\treturn pobj;\n\t\t\t}\n\n\t\t\tconst editor = editors.$popup[this.popupType];\n\t\t\tlet popupId = editor.$popup;\n\n\t\t\tif(!(popupId && $$(popupId))){\n\t\t\t\tconst popup = ui(copy(editor));\n\t\t\t\tif(!popup.linkInput && !popupId)\n\t\t\t\t\tthis.linkInput(document.body);\n\t\t\t\teditor.$popup = popupId = popup._settings.id;\n\t\t\t\tthis.popupInit(popup);\n\t\t\t}\n\n\t\t\treturn popupId;\n\t\t},\n\t\tlinkInput:function(node){\n\t\t\t_event(toNode(node), \"keydown\", e => {\n\t\t\t\t//abort, when editor was not initialized yet\n\t\t\t\tif (!this.config.$popup) return;\n\n\t\t\t\tconst code = e.which || e.keyCode, list = this.getInputNode();\n\t\t\t\tif(!list.isVisible()) return;\n\n\t\t\t\tif(list.moveSelection && code < 41 && code > 32){\n\t\t\t\t\tlet dir;\n\t\t\t\t\tif(code == 33) dir = \"pgup\";\n\t\t\t\t\telse if(code == 34) dir = \"pgdown\";\n\t\t\t\t\telse if(code == 35) dir = \"bottom\";\n\t\t\t\t\telse if(code == 36) dir = \"top\";\n\t\t\t\t\telse if(code == 37) dir = \"left\";\n\t\t\t\t\telse if(code == 38) dir = \"up\";\n\t\t\t\t\telse if(code == 39) dir = \"right\";\n\t\t\t\t\telse if(code == 40) dir = \"down\";\n\n\t\t\t\t\tlist.moveSelection(dir);\n\t\t\t\t}\n\t\t\t\t// shift+enter support for 'popup' editor\n\t\t\t\telse if(code === 13 && ( e.target.nodeName !==\"TEXTAREA\" || !e.shiftKey))\n\t\t\t\t\tcallEvent(\"onEditEnd\", []);\n\t\t\t\n\t\t\t});\n\t\t},\n\n\t\tpopupInit:function(){},\n\t\tpopupType:\"text\",\n\t\trender:function(){ return {}; },\n\t\t$inline:true\n\t}\n};\n\neditors.color = extend({\n\tfocus:function(){},\n\tpopupType:\"color\",\n\tpopupInit:function(popup){\n\t\tpopup.getChildViews()[0].attachEvent(\"onItemClick\", function(value){\n\t\t\tcallEvent(\"onEditEnd\",[value]);\n\t\t});\n\t}\n}, editors.popup);\n\neditors.date = extend({\n\tfocus:function(){},\n\tpopupType:\"date\",\n\tsetValue:function(value){\n\t\tthis._is_string = this.config.stringResult || (value && typeof value == \"string\");\n\t\teditors.popup.setValue.call(this, value);\n\t},\n\tgetValue:function(){\n\t\treturn this.getInputNode().getValue(this._is_string?i18n.parseFormatStr:\"\")||\"\";\n\t},\n\tpopupInit:function(popup){\n\t\tpopup.getChildViews()[0].attachEvent(\"onAfterDateSelect\", function(value){\n\t\t\tcallEvent(\"onEditEnd\",[value]);\n\t\t});\n\t}\n}, editors.popup);\n\neditors.combo = extend({\n\t_create_suggest:function(config){\n\t\tlet suggest, id;\n\t\tif (this.config.popup){\n\t\t\tsuggest = this.config.popup;\n\t\t\tid = suggest.config.id;\n\t\t}\n\t\telse if (config){\n\t\t\tid = create_suggest(config);\n\t\t\tsuggest = $$(id);\n\t\t} else\n\t\t\tid = this._shared_suggest(config);\n\n\t\tattach_editend(suggest);\n\t\treturn id;\n\t},\n\t_shared_suggest:function(){\n\t\tconst e = editors.combo;\n\n\t\tif(e._suggest && $$(e._suggest))\n\t\t\treturn e._suggest;\n\n\t\treturn e._suggest = this._create_suggest(true);\n\t},\n\trender:function(){\n\t\tconst node = create(\"div\", {\n\t\t\t\"class\":\"webix_dt_editor\"\n\t\t}, \"\");\n\n\t\t//save suggest id for future reference\t\t\n\t\tconst suggest = this.config.suggest = this._create_suggest(this.config.suggest);\n\n\t\tif (suggest){\n\t\t\t$$(suggest).linkInput(node.firstChild, true);\n\t\t\t_event(node.firstChild, \"click\", () => this.showPopup());\n\t\t}\n\t\treturn node;\n\t},\n\tgetPopup:function(){\n\t\treturn $$(this.config.suggest);\n\t},\n\tshowPopup:function(){\n\t\tconst popup = this.getPopup();\n\t\tconst list = popup.getList();\n\t\tconst input = this.getInputNode();\n\t\tconst value = this._initial_value;\n\n\t\tpopup.show(input);\n\t\tinput.setAttribute(\"aria-expanded\", \"true\");\n\t\tif (value){\n\t\t\tassert(list.exists(value), \"Option with ID \"+value+\" doesn't exist\");\n\t\t\tif (list.exists(value)){\n\t\t\t\tlist.select(value);\n\t\t\t\tlist.showItem(value);\n\t\t\t}\n\t\t} else {\n\t\t\tlist.unselect();\n\t\t\tlist.showItem(list.getFirstId());\n\t\t}\n\t\tpopup._last_input_target = input;\n\t},\n\tafterRender:function(){\n\t\tthis.showPopup();\n\t},\n\tsetValue:function(value){\n\t\tthis._initial_value = value;\n\t\tif (this.config.suggest){\n\t\t\tconst sobj = $$(this.config.suggest);\n\t\t\tconst data = this.config.collection || this.config.options;\n\t\t\tif (data)\n\t\t\t\tsobj.getList().data.importData(data);\n\n\t\t\tthis.getInputNode(this.node).value = sobj.getItemText(value);\n\t\t}\n\t},\n\tgetValue:function(){\n\t\tlet value = this.getInputNode().value;\n\t\tif (this.config.suggest){\n\t\t\tconst suggest = $$(this.config.suggest),\n\t\t\t\tlist = suggest.getList();\n\t\t\tif (value || (list.getSelectedId && list.getSelectedId()))\t\n\t\t\t\tvalue = suggest.getSuggestion(value);\n\t\t}\n\t\treturn value;\n\t}\n}, editors.text);\n\neditors.richselect = extend({\n\tfocus:function(){},\n\tgetValue:function(){\n\t\treturn this.getPopup().getValue();\n\t},\n\tsetValue:function(value){\n\t\tconst suggest = this.config.collection || this.config.options;\n\t\tthis.getInputNode();\n\t\tif (suggest)\n\t\t\tthis.getPopup().getList().data.importData(suggest);\n\n\t\tthis.getPopup().show(this.node);\n\t\tthis.getPopup().setValue(value);\n\t},\n\tgetInputNode:function(){\n\t\treturn this.getPopup().getList();\n\t},\n\tpopupInit:function(popup){\n\t\tpopup.linkInput(document.body);\n\t\tattach_editend(popup);\n\t},\n\tpopupType:\"richselect\"\n}, editors.popup);\n\neditors.password = extend({\n\trender:function(){\n\t\tconst node = create(\"div\", {\n\t\t\t\"class\":\"webix_dt_editor webix_password_editor\"\n\t\t}, \"\");\n\n\t\tconst icon = node.querySelector(\".webix_icon\");\n\t\t_event(icon, \"click\", () => {\n\t\t\tthis.toggleInput();\n\t\t\tthis.getInputNode(this.node).focus();\n\t\t});\n\t\treturn node;\n\t},\n\ttoggleInput:function(){\n\t\tconst input = this.getInputNode(this.node);\n\t\tconst isPassword = input.getAttribute(\"type\") === \"password\";\n\t\tinput.setAttribute(\"type\", isPassword ? \"text\" : \"password\");\n\n\t\tconst icon = input.nextSibling;\n\t\ticon.className = `webix_icon wxi-eye${isPassword ? \"-slash\" : \"\"}`;\n\t},\n\tmasterFormat: function(value){\n\t\treturn !value && value !== 0 ? \"\" : \"•\".repeat(value.toString().length);\n\t}\n}, editors.text);\n\neditors.$popup = {\n\ttext:{\n\t\tview:\"popup\", width:250, height:150,\n\t\tbody:{ view:\"textarea\" }\n\t},\n\tcolor:{\n\t\tview:\"popup\",\n\t\tbody:{ view:\"colorboard\" }\n\t},\n\tdate:{\n\t\tview:\"popup\", width:250, height:250, padding:0,\n\t\tbody:{ view:\"calendar\", icons:true, borderless:true }\n\t},\n\trichselect:{\n\t\tview:\"suggest\",\n\t\tbody:{ view:\"list\", select:true }\n\t},\n\tmultiselect:{\n\t\tview:\"multisuggest\",\n\t\tsuggest:{\n\t\t\tbutton:true\n\t\t}\n\t}\n};\n\nexport default editors;","import {remove, removeCss, addCss} from \"../webix/html\";\nimport UIManager from \"../core/uimanager\";\nimport {extend, bind, delay, isUndefined} from \"../webix/helpers\";\nimport {ui, $$} from \"../ui/core\";\nimport {_event} from \"../webix/htmlevents\";\nimport {assert} from \"../webix/debug\";\nimport {attachEvent, callEvent, detachEvent} from \"../webix/customevents\";\nimport Undo from \"../core/undo\";\n\n\nimport globalState from \"../core/state\";\nimport editors from \"../webix/editors\";\n/*\n\tBehavior:EditAbility - enables item operation for the items\n\t\n\t@export\n\t\tedit\n\t\tstopEdit\n*/\n\nconst EditAbility ={\n\tdefaults:{\n\t\teditaction:\"click\"\n\t},\n\t$init:function(config){\n\t\tthis._editors = {};\n\t\tthis._in_edit_mode = 0;\n\t\tthis._edit_open_time = 0;\n\t\tthis._contentobj.style.position = \"relative\";\n\t\tif (config)\n\t\t\tconfig.onDblClick = config.onDblClick || {};\n\n\t\tthis.attachEvent(\"onAfterRender\", this._refocus_inline_editor);\n\n\t\t//when we call extend the editable prop can be already set\n\t\tif (this._settings.editable)\n\t\t\tthis._init_edit_events_once();\n\n\t\textend(this,Undo);\n\t},\n\t_try_reselecting_text:function(input, start){\n\t\ttry {\t\t\t//Chrome throws an error if selectionStart is not accessible\n\t\t\tif (typeof input.selectionStart === \"number\") {\n\t\t\t\tinput.selectionStart = start >= 0 ? start : input.value.length;\n\t\t\t\tinput.selectionEnd = input.value.length;\n\t\t\t}\n\t\t} catch(e){}\t// eslint-disable-line\n\t},\n\t_refocus_inline_editor:function(){\n\t\tconst editor = this.getEditor();\n\t\tif (editor && editor.$inline && !editor.getPopup){\n\t\t\tconst newnode = this._locateInput(editor);\n\t\t\tif (newnode && newnode != editor.node){\n\t\t\t\teditor.node = newnode;\n\t\t\t\tnewnode.focus();\n\n\t\t\t\tconst justOpened = (new Date())-this._edit_open_time > 200;\n\t\t\t\tthis._try_reselecting_text(newnode, justOpened ? -1 : 0);\n\t\t\t}\n\t\t}\n\t},\n\teditable_setter:function(value){\n\t\tif (value)\n\t\t\tthis._init_edit_events_once();\n\t\treturn value;\n\t},\n\t_init_edit_events_once:function(){\n\t\t//will close editor on any click outside\n\t\tconst e1 = attachEvent(\"onEditEnd\", bind(function(){\n\t\t\tif (this._in_edit_mode)\n\t\t\t\tthis.editStop();\n\t\t}, this));\n\t\tconst e2 = attachEvent(\"onClick\", bind(function(e){\n\t\t\t//but ignore click which opens editor\n\t\t\tif (this._in_edit_mode && (new Date())-this._edit_open_time > 200){\n\t\t\t\tif (!this._last_editor || this._last_editor.popupType || !e || ( !this._last_editor.node || !this._last_editor.node.contains(e.target)))\n\t\t\t\t\tthis.editStop();\n\t\t\t}\n\t\t}, this));\n\n\t\tthis.attachEvent(\"onDestruct\", function(){ detachEvent(e1); detachEvent(e2); });\n\t\t\n\t\t//property sheet has simple data object, without events\n\t\tif (this.data.attachEvent)\n\t\t\tthis.data.attachEvent(\"onIdChange\", bind(function(oldid, newid){\n\t\t\t\tthis._changeEditorId(oldid, newid);\n\t\t\t}, this));\n\n\t\t//when clicking on row - will start editor\n\t\tthis.attachEvent(\"onItemClick\", function(id){\n\t\t\tif (this._settings.editable && this._settings.editaction == \"click\")\n\t\t\t\tthis.edit(id);\n\t\t});\n\t\tthis.attachEvent(\"onItemDblClick\", function(id){\n\t\t\tif (this._settings.editable && this._settings.editaction == \"dblclick\")\n\t\t\t\tthis.edit(id);\n\t\t});\n\t\t//each time when we clicking on input, reset timer to prevent self-closing\n\t\tthis._reset_active_editor = bind(function(){\n\t\t\tthis._edit_open_time = new Date();\n\t\t},this);\n\n\t\tthis._init_edit_events_once = function(){};\n\n\t\tif (this._component_specific_edit_init)\n\t\t\tthis._component_specific_edit_init();\n\t},\n\t_handle_live_edits:function(){\n\t\tdelay(function(){\n\t\t\tvar editor = this.getEditor();\n\t\t\tif (editor && editor.config.liveEdit){\n\t\t\t\tvar state = { value:editor.getValue(), old: editor.value };\n\t\t\t\tif (state.value == state.old) return;\n\n\t\t\t\teditor.value = state.value;\n\t\t\t\tthis._set_new_value(editor, state.value, false);\n\t\t\t\tthis.callEvent(\"onLiveEdit\", [state, editor]);\n\t\t\t}\n\t\t}, this);\n\t},\n\t_show_editor_form:function(id){\n\t\tvar form = this._settings.form;\n\t\tif (typeof form != \"string\")\n\t\t\tthis._settings.form = form = ui(form).config.id;\n\n\t\tform = $$(form);\n\t\tvar realform = form.setValues?form:form.getChildViews()[0];\n\t\t\n\t\trealform.setValues(this.getItem(id.row || id), false, \"auto\");\n\t\tform.config.master = this.config.id;\n\t\tform.show( this.getItemNode(id) );\n\n\t\tvar first = realform.getChildViews()[0];\n\t\tif (first.focus)\n\t\t\tfirst.focus();\n\t},\n\tedit:function(id, preserve, show){\n\t\tif (!this._settings.editable || !this.callEvent(\"onBeforeEditStart\", [id])) return;\n\t\tif (this._settings.form)\n\t\t\treturn this._show_editor_form(id);\n\n\t\tvar editor = this._get_editor_type(id);\n\t\tif (editor){\n\t\t\tif (this.getEditor(id)) return;\n\t\t\tif (!preserve) this.editStop();\n\n\t\t\t//render html input\n\t\t\tassert(editors[editor], \"Invalid editor type: \"+editor);\n\t\t\tvar type = extend({}, editors[editor]);\n\n\t\t\tvar node = this._init_editor(id, type, show);\n\t\t\tif (type.config.liveEdit)\n\t\t\t\tthis._live_edits_handler = this.attachEvent(\"onKeyPress\", this._handle_live_edits);\n\n\t\t\tvar area = type.getPopup?type.getPopup(node)._viewobj:node;\n\n\t\t\tif (area)\n\t\t\t\t_event(area, \"click\", this._reset_active_editor);\n\t\t\tif (node)\n\t\t\t\t_event(node, \"input\", this._on_editor_change, { bind:{ view:this, id:id }});\n\t\t\tif (show !== false)\n\t\t\t\ttype.focus();\n\n\t\t\tif (this.$fixEditor)\n\t\t\t\tthis.$fixEditor(type);\n\n\t\t\t//save time of creation to prevent instant closing from the same click\n\t\t\tthis._edit_open_time = globalState.edit_open_time = new Date();\n\n\t\t\tUIManager.setFocus(this, true);\n\t\t\tthis.callEvent(\"onAfterEditStart\", [id]);\n\t\t\treturn type;\n\t\t}\n\t\treturn null;\n\t},\n\tgetEditor:function(id){\n\t\tif (!id)\n\t\t\treturn this._last_editor;\n\n\t\treturn this._editors[id];\n\t},\n\t_changeEditorId:function(oldid, newid)\t{\n\t\tvar editor = this._editors[oldid];\n\t\tif (editor){\n\t\t\tthis._editors[newid] = editor;\n\t\t\teditor.id = newid;\n\t\t\tdelete this._editors[oldid];\n\t\t}\n\t},\n\t_on_editor_change:function(){\n\t\tif (this.view.hasEvent(\"onEditorChange\"))\n\t\t\tthis.view.callEvent(\"onEditorChange\", [this.id, this.view.getEditorValue(this.id) ]);\n\t},\n\t_get_edit_config:function(){\n\t\treturn this._settings;\n\t},\n\t_init_editor:function(id, type, show){\n\t\ttype.config = this._get_edit_config(id);\n\t\tvar node = type.render();\n\n\t\tif (type.$inline)\n\t\t\tnode = this._locateInput(id);\n\t\ttype.node = node;\n\n\t\tvar item = this.getItem(id);\n\t\t//value can be configured by editValue option\n\t\tvar value = item[this._settings.editValue||\"value\"];\n\t\t//if property was not defined - use empty value\n\t\tif (isUndefined(value))\n\t\t\tvalue = \"\";\n\n\t\ttype.setValue(value, item);\n\t\ttype.value = value;\n\n\t\tthis._addEditor(id, type);\n\n\t\tif(type.getPopup){\n\t\t\tconst popup = type.getPopup();\n\t\t\tpopup.attachEvent(\"onHide\", function(){\n\t\t\t\tif(this._edit_active) this.show();\n\t\t\t});\n\t\t\tpopup._editorMaster = this._settings.id;\n\t\t}\n\n\t\t//show it over cell\n\t\tif (show !== false)\n\t\t\tthis.showItem(id);\n\t\tif (!type.$inline)\n\t\t\tthis._sizeToCell(id, node, true);\n\n\t\tif (type.afterRender)\n\t\t\ttype.afterRender();\n\t\treturn node;\n\t},\n\t_locate_cell:function(id){\n\t\treturn this.getItemNode(id);\n\t},\n\t_locateInput:function(id){\n\t\tvar cell = this._locate_cell(id);\n\t\tif (cell)\n\t\t\tcell = cell.getElementsByTagName(\"input\")[0] || cell;\n\n\t\treturn cell;\n\t},\n\t_get_editor_type:function(){\n\t\treturn this._settings.editor;\n\t},\n\t_addEditor:function(id, type){\n\t\ttype.id = id;\n\t\tthis._editors[id]= this._last_editor = type;\n\t\tthis._in_edit_mode++;\n\t},\n\t_removeEditor:function(editor){\n\t\tif (this._last_editor == editor)\n\t\t\tthis._last_editor = 0;\n\t\t\n\t\tif (editor.destroy)\n\t\t\teditor.destroy();\n\n\t\tdelete editor.popup;\n\t\tdelete editor.node;\n\n\t\tdelete this._editors[editor.id];\n\t\tthis._in_edit_mode--;\n\t},\n\tfocusEditor:function(){\n\t\tvar editor = this.getEditor.apply(this, arguments);\n\t\tif (editor && editor.focus)\n\t\t\teditor.focus();\n\t},\n\teditCancel:function(){\n\t\tthis.editStop(null, null, true);\n\t},\n\t_applyChanges: function(el){\n\t\tif (el){\n\t\t\tvar ed = this.getEditor();\n\t\t\tif (ed && ed.getPopup && ed.getPopup() == el.getTopParentView()) return;\n\t\t}\n\t\tthis.editStop();\n\t},\n\teditStop:function(id){\n\t\tif (this._edit_stop) return;\n\t\tthis._edit_stop = 1;\n\n\n\t\tvar cancel = arguments[2];\n\t\tvar result = 1;\n\t\tif (!id){\n\t\t\tthis._for_each_editor(function(editor){\n\t\t\t\tresult = result * this._editStop(editor, cancel);\n\t\t\t});\n\t\t} else \n\t\t\tresult = this._editStop(this._editors[id], cancel);\n\n\t\tthis._edit_stop = 0;\n\t\treturn result;\n\t},\n\t_cellPosition:function(id){\n\t\tvar html = this.getItemNode(id);\n\t\treturn {\n\t\t\tleft:html.offsetLeft, \n\t\t\ttop:html.offsetTop,\n\t\t\theight:html.offsetHeight,\n\t\t\twidth:html.offsetWidth,\n\t\t\tparent:this._contentobj\n\t\t};\n\t},\n\t_sizeToCell:function(id, node, inline){\n\t\t//fake inputs\n\t\tif (!node.style) return;\n\n\t\tvar pos = this._cellPosition(id, null, true);\n\n\t\tnode.style.top = pos.top + \"px\";\n\t\tnode.style.left = pos.left + \"px\";\n\n\t\tnode.style.width = pos.width-1+\"px\";\n\t\tnode.style.height = pos.height-1+\"px\";\n\n\t\tnode.top = pos.top; //later will be used during y-scrolling\n\n\t\tif (inline) pos.parent.appendChild(node);\n\t\treturn pos;\n\t},\n\t_for_each_editor:function(handler){\n\t\tfor (var editor in this._editors)\n\t\t\thandler.call(this, this._editors[editor]);\n\t},\n\t_editStop:function(editor, ignore){\n\t\tif (!editor || globalState._final_destruction) return;\n\t\tvar state = { \n\t\t\tvalue : this._get_new_value(editor), \n\t\t\told : editor.value\n\t\t};\n\n\t\tconst popup = editor.getPopup ? editor.getPopup() : null;\n\n\t\tif (this.callEvent(\"onBeforeEditStop\", [state, editor, ignore])){\n\t\t\tif (!ignore){\n\t\t\t\t//special case, state.old = 0, state.value = \"\"\n\t\t\t\t//we need to state.old to string, to detect the change\n\t\t\t\tvar old = state.old;\n\t\t\t\tif (typeof state.value == \"string\") old += \"\";\n\n\t\t\t\tif (old != state.value || editor.config.liveEdit){\n\t\t\t\t\tvar item = this._set_new_value(editor, state.value, true);\t\n\t\t\t\t\tthis.updateItem(editor.row || editor.id, item);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (editor.$inline)\n\t\t\t\teditor.node = null;\n\t\t\telse\n\t\t\t\tremove(editor.node);\n\n\t\t\tif (popup){\n\t\t\t\tpopup.hide();\n\t\t\t\tdelete popup._edit_active;\n\t\t\t}\n\n\t\t\tthis._removeEditor(editor);\n\t\t\tif (this._live_edits_handler)\n\t\t\t\tthis.detachEvent(this._live_edits_handler);\n\n\t\t\tthis.callEvent(\"onAfterEditStop\", [state, editor, ignore]);\n\t\t\treturn 1;\n\t\t}\n\t\telse if(popup){\n\t\t\tif(!popup.isVisible())\n\t\t\t\tpopup.show();\n\t\t\teditor.getPopup()._edit_active = true;\n\n\t\t}\n\t\treturn 0;\n\t},\n\tvalidateEditor:function(id){\n\t\tlet result = true;\n\t\tif (this._settings.rules){\n\t\t\tconst editor = this.getEditor(id);\n\t\t\tconst key = editor.column||this._settings.editValue||\"value\";\n\t\t\tconst rule = this._settings.rules[key];\n\t\t\tconst all = this._settings.rules.$all;\n\t\t\tconst input = editor.getInputNode();\n\n\t\t\tif ((rule || all) && !input._viewobj){ //only for html inputs\n\t\t\t\tconst obj = this.data.getItem(editor.row||editor.id);\n\t\t\t\tconst value = editor.getValue();\n\n\t\t\t\tif (rule)\n\t\t\t\t\tresult = rule.call(this, value, obj, key);\n\t\t\t\tif (all)\n\t\t\t\t\tresult = all.call(this, value, obj, key) && result;\n\t\t\t\n\t\t\t\tif (result)\n\t\t\t\t\tremoveCss(input, \"webix_invalid\");\n\t\t\t\telse\n\t\t\t\t\taddCss(input, \"webix_invalid\");\n\n\t\t\t\tcallEvent(\"onLiveValidation\", [editor, result, obj, value]);\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t},\n\tgetEditorValue:function(id){\n\t\tvar editor;\n\t\tif (arguments.length === 0)\n\t\t\teditor = this._last_editor;\n\t\telse\n\t\t\teditor = this.getEditor(id);\n\n\t\tif (editor)\n\t\t\treturn editor.getValue();\n\t},\n\tgetEditState:function(){\n\t\treturn this._last_editor || false;\n\t},\n\teditNext:function(next, from){ \n\t\tnext = next !== false; //true by default\n\t\tif (this._in_edit_mode == 1 || from){\n\t\t\t//only if one editor is active\n\t\t\tvar editor_next = this._find_cell_next((this._last_editor || from), function(id){\n\t\t\t\tif (this._get_editor_type(id))\n\t\t\t\t\treturn true;\n\t\t\t\treturn false;\n\t\t\t}, next);\n\n\t\t\tif (this.editStop()){\t//if we was able to close previous editor\n\t\t\t\tif (editor_next){\t//and there is a new target\n\t\t\t\t\tthis.edit(editor_next);\t//init new editor\n\t\t\t\t\tthis._after_edit_next(editor_next);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t},\n\t//stab, used in datatable\n\t_after_edit_next:function(){},\n\t_find_cell_next:function(start, check, direction){\n\t\tvar row = this.getIndexById(start.id);\n\t\tvar order = this.data.order;\n\t\t\n\t\tif (direction){\n\t\t\tfor (let i=row+1; i=0; i--){\n\t\t\t\tif (check.call(this, order[i]))\n\t\t\t\t\treturn order[i];\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t},\n\t_get_new_value(editor){\n\t\treturn editor.getValue();\n\t},\n\t_set_new_value:function(editor, new_value, copy){\n\t\tvar item = copy ? {} : this.getItem(editor.id);\n\t\titem[this._settings.editValue||\"value\"] = new_value;\n\t\treturn item;\n\t}\n};\n\nexport default EditAbility;","import {preventEvent} from \"../webix/html\";\nimport {_power_array} from \"../webix/helpers\";\nimport {_event} from \"../webix/htmlevents\";\nimport UIManager from \"./uimanager\";\n\n\n/*aria-style handling for options of multiple-value controls (radio, segmented, tabbar)*/\n\nconst HTMLOptions = {\n\t$init: function(){\n\t\tthis.$ready.push(()=>{\n\t\t\tif(!this.customRadio_setter || this.config.customRadio)\n\t\t\t\t_event( this.$view, \"keydown\", this._moveSelection, {bind:this});\n\t\t});\n\t},\n\t_focus: function(){\n\t\tif(!UIManager.canFocus(this))\n\t\t\treturn false;\n\n\t\tconst input = this._getInputNode();\n\t\tif (input)\n\t\t\tfor (let i=0; i34 && code <41){\n\t\t\tconst inp = this._getInputNode();\n\t\t\tlet index = false;\n\n\t\t\tif (!inp.length) return;\n\t\t\tpreventEvent(e);\n\n\t\t\tconst dir = (code === 37 || code === 38 || code === 35)?-1:1;\n\t\t\tif (code === 35) index = inp.length-1;\n\t\t\telse if (code === 36 ) index = 0;\n\t\t\telse {\n\t\t\t\tfor (let i=0; i= inp.length) i = 0;\n\t\t\t\t\tif (i < 0) i = inp.length-1;\n\n\t\t\t\t\tif (!inp[i].getAttribute(\"webix_disabled\")){\n\t\t\t\t\t\tconst id = inp[i].getAttribute(/*@attr*/\"button_id\");\n\n\t\t\t\t\t\tthis.setValue(id, \"user\");\n\t\t\t\t\t\tinp[i].focus();\n\t\t\t\t\t\ti = \"success\";\n\t\t\t\t\t}\n\t\t\t\t\telse i += dir;\n\n\t\t\t\t} while(i !== \"success\" && i !== index);\n\t\t\t}\n\t\t}\n\t},\n\t_get_tooltip_data: function(t,e){\n\t\tlet id,\n\t\t\tnode = e.target;\n\t\twhile (node && !node.webix_tooltip){\n\t\t\tid = node.getAttribute(\"webix_t_id\");\n\t\t\tif (id)\n\t\t\t\treturn this.getOption(id);\n\t\t\tnode = node.parentNode;\n\t\t}\n\t\treturn null;\n\t},\n\toptionIndex: function(id){\n\t\tconst options = this._settings.options;\n\t\tfor (let i=0; i=0; i--)\n\t\t\t\tif (!options[i].hidden)\n\t\t\t\t\treturn this.setValue(options[i].id,\"auto\");\n\t\t}\n\n\t\t//nothing found\t\t\n\t\tthis.setValue(\"\",\"auto\");\n\t},\n\t_getFirstActive(first){\n\t\tconst options = this._settings.options;\n\n\t\tif (options.length){\n\t\t\tfor (let i=0; i a[target];\n\t\t} else {\n\t\t\tif (source.indexOf(\"#\") === -1 && source.indexOf(\"{\") === -1){\n\t\t\t\tsource = \"#\"+source+\"#\";\n\t\t\t}\n\t\t\tgetSource = template(source);\n\t\t}\n\n\t\tif (map.indexOf(\"(date)\")===0){\n\t\t\tif (extra && !extra.format) extra.format = i18n.dateFormatStr;\n\n\t\t\treturn function(obj){\n\t\t\t\tconst dateStr = (getSource(obj) || \"\").toString();\n\t\t\t\tobj[target] = i18n.parseFormatDate(dateStr);\n\t\t\t};\n\t\t} else if (map.indexOf(\"(number)\")===0){\n\t\t\treturn function(obj){\n\t\t\t\tobj[target] = getSource(obj)*1;\n\t\t\t};\n\t\t} else {\n\t\t\treturn function(obj){\n\t\t\t\tobj[target] = getSource(obj) || \"\";\n\t\t\t};\n\t\t}\n\t},\n\t_build_data_map:function(columns){ //for datatable\n\t\tfor (let i=0; i {\n\t\t\t\t\tif(this.refreshFilter)\n\t\t\t\t\t\tthis.refreshFilter(config.columnId);\n\t\t\t\t});\n\n\t\t\t\t// collect handler ids for further destruction\n\t\t\t\tif (!this._collection_handlers[options.config.id]) this._collection_handlers[options.config.id] = [];\n\t\t\t\tthis._collection_handlers[options.config.id].push(id);\n\t\t\t}\n\t\t}\n\t},\n\t_bind_collection:function(options, column){\n\t\tif (column){\n\t\t\tdelete column.options;\n\t\t\tcolumn.collection = options;\n\t\t\tcolumn.template = column.template || this._bind_template(column.optionslist);\n\t\t\tconst id = options.data.attachEvent(\"onStoreUpdated\", () => {\n\t\t\t\tthis.refresh();\n\t\t\t\tif(this.refreshFilter)\n\t\t\t\t\tthis.refreshFilter(column.id);\n\t\t\t});\n\n\t\t\t// collect handler ids for further destruction\n\t\t\tif (!this._collection_handlers[options.config.id]) this._collection_handlers[options.config.id] = [];\n\t\t\tthis._collection_handlers[options.config.id].push(id);\n\t\t}\n\t},\n\t_bind_template:function(multi){\n\t\tif (multi) {\n\t\t\tconst separator = typeof multi === \"string\" ? multi : \",\";\n\t\t\treturn function(obj, common, value, column){\n\t\t\t\tif (!value) return \"\";\n\n\t\t\t\tconst ids = value.toString().split(separator);\n\t\t\t\tfor (let i = 0; i < ids.length; i++){\n\t\t\t\t\tconst data = column.collection.data.pull[ids[i]];\n\t\t\t\t\tids[i] = data ? (data.value || \"\") : \"\";\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn ids.join(\", \");\n\t\t\t};\n\t\t} else {\n\t\t\treturn function(obj, common, value, column){\n\t\t\t\tconst data = column.collection.data.pull[value];\n\t\t\t\tif (data && (data.value || data.value === 0))\n\t\t\t\t\treturn data.value;\n\t\t\t\treturn \"\";\n\t\t\t};\n\t\t}\n\t},\n\t_map_editor: function(id, config){\n\t\tconst editor = editors[config.editor];\n\t\tif(editor && editor.masterFormat)\n\t\t\tconfig.format = editor.masterFormat;\n\t}\n};\n\nexport default MapCollection;","import {preventEvent, remove, create} from \"../webix/html\";\nimport {bind} from \"../webix/helpers\";\nimport {$$} from \"../ui/core\";\nimport i18n from \"../webix/i18n\";\nimport {event} from \"../webix/htmlevents\";\n\n\n/*\n UI: navigation control\n*/\nconst NavigationButtons = {\n\t$init:function(){\n\t\tthis.$ready.push(function(){\n\t\t\tthis.attachEvent(\"onKeyPress\", this._onKeyPress);\n\t\t});\n\t},\n\t_moveActive:function(code, e){\n\t\tif(code === 37 || code === 39){\n\t\t\tpreventEvent(e);\n\t\t\tthis._showNavItem(code===37?-1:1);\n\n\t\t\tvar node = this._navPanel.querySelector(\"[tabindex='0']\");\n\t\t\tif(node) node.focus();\n\t\t}\n\t},\n\t_renderPanel:function(){\n\t\tremove(this._navPanel);\n\n\n\t\tthis._navPanel = create(\"DIV\",{\n\t\t\t\"class\":\"webix_nav_panel \"+\"webix_nav_panel_\"+this._settings.navigation.type,\n\t\t\t\"role\":\"tablist\"\n\t\t},\"\");\n\n\t\tthis._viewobj.appendChild(this._navPanel);\n\n\n\t\tthis._renderNavItems();\n\t\tthis._renderNavButtons();\n\t\tthis._setLinkEventHandler();\n\t},\n\t_setLinkEventHandler: function(){\n\t\tvar h = [];\n\t\tif(this._navPanel)\n\t\t\th[0] = event(this._navPanel,\"click\", bind(function(e){\n\t\t\t\tvar elem = e.target;\n\t\t\t\tvar found = false;\n\t\t\t\twhile(elem != this._navPanel && !found){\n\t\t\t\t\tvar bindId = elem.getAttribute(this._linkAttr);\n\t\t\t\t\tif(bindId){\n\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\tthis._showPanelBind(bindId);\n\t\t\t\t\t}\n\t\t\t\t\telem = elem.parentNode;\n\t\t\t\t}\n\t\t\t},this));\n\t\tif(this._prevNavButton)\n\t\t\th[1] = event(this._prevNavButton,\"click\", bind(function(){\n\t\t\t\tthis._showNavItem(-1);\n\t\t\t},this));\n\t\tif(this._nextNavButton)\n\t\t\th[1] = event(this._nextNavButton,\"click\", bind(function(){\n\t\t\t\tthis._showNavItem(1);\n\t\t\t},this));\n\t\tthis.attachEvent(\"onDestruct\", function(){\n\t\t\tfor(var i=0;i< h.length; i++){\n\t\t\t\tthis.detachEvent(h[i]);\n\t\t\t}\n\t\t\th = null;\n\t\t});\n\t},\n\t_showNavItem: function(inc){\n\t\tif(this._cells){\n\t\t\tvar index = this._active_cell + inc;\n\t\t\tif(index >= this._cells.length || index < 0){\n\t\t\t\tindex = (index < 0?this._cells.length-1:0);\n\t\t\t}\n\t\t\tthis.setActiveIndex(index);\n\t\t}\n\t},\n\t_showPanelBind: function(id){\n\t\tif(this._cells)\n\t\t\t$$(id).show();\n\t},\n\t_renderNavItems:function(){\n\t\tvar item, config;\n\t\tconfig = this._settings.navigation;\n\t\tif(config.items){\n\t\t\tthis._linkAttr = config.linkAttr || /*@attr*/\"bind_id\";\n\n\t\t\tif(!this._navPanel)\n\t\t\t\tthis._renderPanel();\n\t\t\telse\n\t\t\t\tthis._clearPanel();\n\n\t\t\tvar data = (this._cells?this._cells:this.data.order);\n\t\t\tif(data.length>1){\n\t\t\t\tfor (var i=0; i < data.length; i++){\n\n\t\t\t\t\titem = create(\"DIV\",{\n\t\t\t\t\t\t\"class\":\"webix_nav_item webix_nav_\"+(i==this._active_cell?\"active\":\"inactive\"),\n\t\t\t\t\t\t\"role\":\"tab\",\n\t\t\t\t\t\t\"tabindex\":(i==this._active_cell?\"0\":\"-1\")\n\t\t\t\t\t});\n\t\t\t\t\tvar id = this._cells?this._cells[i]._settings.id:data[i];\n\t\t\t\t\tif(id)\n\t\t\t\t\t\titem.setAttribute(this._linkAttr, id);\n\t\t\t\t\tthis._navPanel.appendChild(item);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\t_clearPanel:function(){\n\t\tif (this._navPanel){\n\t\t\tvar coll = this._navPanel.childNodes;\n\t\t\tfor (var i = coll.length - 1; i >= 0; i--)\n\t\t\t\tremove(coll[i]);\n\t\t}\n\t},\n\t_renderNavButtons: function(){\n\t\tvar config = this._settings.navigation;\n\t\tif(config.buttons){\n\n\t\t\tif(this._prevNavButton)\n\t\t\t\tremove(this._prevNavButton);\n\t\t\tif(this._prevNavButton)\n\t\t\t\tremove(this._nextNavButton);\n\n\n\t\t\tthis._prevNavButton = create(\n\t\t\t\t\"DIV\",\n\t\t\t\t{\n\t\t\t\t\t\"class\":\"webix_nav_button_\"+config.type+\" webix_nav_button_prev \"\n\t\t\t\t},\n\t\t\t\t\"
\"\n\t\t\t);\n\t\t\tthis._viewobj.appendChild(this._prevNavButton);\n\n\t\t\tthis._nextNavButton = create(\n\t\t\t\t\"DIV\",\n\t\t\t\t{\n\t\t\t\t\t\"class\":\"webix_nav_button_\"+config.type+\" webix_nav_button_next \"\n\t\t\t\t},\n\t\t\t\t\"
\"\n\t\t\t);\n\t\t\tthis._viewobj.appendChild(this._nextNavButton);\n\t\t}\n\t}\n};\n\nexport default NavigationButtons;","import {create, insertBefore, remove} from \"../webix/html\";\nimport env from \"../webix/env\";\nimport {isUndefined, extend, delay} from \"../webix/helpers\";\n\n\nconst ProgressBar = {\n\t$init:function(){\n\t\tif (isUndefined(this._progress) && this.attachEvent){\n\t\t\tthis.attachEvent(\"onBeforeLoad\", () => this.showProgress());\n\t\t\tthis.attachEvent(\"onAfterLoad\", () => this.hideProgress());\n\t\t\tthis._progress = null;\n\t\t}\n\t},\n\tshowProgress:function(config){\n\t\t// { position: 0 - 1, delay: 2000ms by default, css : name of css class to use }\n\t\tvar width;\n\t\tif (!this._progress){\n\n\t\t\tconfig = extend({\n\t\t\t\tposition:0,\n\t\t\t\tdelay: 2000,\n\t\t\t\ttype:\"icon\",\n\t\t\t\ticon:\"wxi-sync\",\n\t\t\t\thide:false\n\t\t\t}, (config||{}), true);\n\n\t\t\tvar incss = (config.type == \"icon\") ? (config.icon+\" webix_spin\") : \"\";\n\n\t\t\tthis._progress = create(\n\t\t\t\t\"DIV\",\n\t\t\t\t{\n\t\t\t\t\t\"class\":\"webix_progress_\"+config.type,\n\t\t\t\t\t\"role\":\"progressbar\",\n\t\t\t\t\t\"aria-valuemin\":\"0\",\n\t\t\t\t\t\"aria-valuemax\":\"100\",\n\t\t\t\t\t\"tabindex\":\"0\"\n\t\t\t\t},\n\t\t\t\t\"
\"\n\t\t\t);\n\n\t\t\tif(!this.setPosition)\n\t\t\t\tthis._viewobj.style.position = \"relative\";\n\n\t\t\tinsertBefore(this._progress, this._viewobj.firstChild, this._viewobj);\n\t\t\tthis._viewobj.setAttribute(\"aria-busy\", \"true\");\n\n\t\t\tif(!this._touch_scroll){\n\t\t\t\tif (this.getScrollState){\n\t\t\t\t\tvar scroll = this.getScrollState();\n\t\t\t\t\tif (this._viewobj.scrollWidth != this.$width){\n\t\t\t\t\t\tthis._progress.style.left = scroll.x +\"px\";\n\t\t\t\t\t}\n\t\t\t\t\tif (this._viewobj.scrollHeight != this.$height){\n\t\t\t\t\t\tif(config.type != \"bottom\"){\n\t\t\t\t\t\t\tthis._progress.style.top = scroll.y + \"px\";\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis._progress.style.top = scroll.y + this.$height - this._progress.offsetHeight +\"px\";\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._progress_animate = config.type != \"icon\";\n\t\t}\n\n\t\tif (!config) return;\n\n\t\tif (this._progress_animate){\n\t\t\tvar position = config.position || 1;\n\t\t\tif (config.delay){\n\t\t\t\t// force reflow\n\t\t\t\twidth = this._viewobj.firstChild.offsetWidth;\n\t\t\t\tthis._progress.firstChild.style[env.transitionDuration] = config.delay+\"ms\";\n\t\t\t}\n\n\t\t\t// animate to new value\n\t\t\tthis._progress.firstChild.style.width = position*100+\"%\";\n\t\t}\n\n\t\tif (this._progress_hide)\n\t\t\tclearTimeout(this._progress_hide);\n\n\t\tif (config.hide)\n\t\t\tthis._progress_hide = delay(this.hideProgress, this, [true], config.delay);\n\n\t\t// necessary to prevent code optimization\n\t\treturn width;\n\t},\n\thideProgress:function(now){\n\t\tif (this._progress){\n\t\t\tif (now || !this._progress_animate){\n\t\t\t\tremove(this._progress);\n\t\t\t\tthis._progress = null;\n\t\t\t\tthis._viewobj.removeAttribute(\"aria-busy\");\n\t\t\t} else {\n\t\t\t\tthis.showProgress({ position:1.1, delay:300 , hide:true });\n\t\t\t}\n\t\t}\n\t}\n};\n\nexport default ProgressBar;","import {addCss, removeCss} from \"../webix/html\";\nimport {_to_array, bind, isArray} from \"../webix/helpers\";\nimport {_event, event} from \"../webix/htmlevents\";\nimport {assert} from \"../webix/debug\";\nimport env from \"../webix/env\";\n\nimport ready from \"../webix/ready\";\nimport state from \"../core/state\";\n\n\n/*\n\tBehavior:SelectionModel - manage selection states\n\t@export\n\t\tselect\n\t\tunselect\n\t\tselectAll\n\t\tunselectAll\n\t\tisSelected\n\t\tgetSelectedId\n*/\nconst SelectionModel ={\n\t$init:function(){\n\t\t//collection of selected IDs\n\t\tthis._selected = _to_array();\n\t\tassert(this.data, \"SelectionModel :: Component doesn't have DataStore\");\n\n\t\t//remove selection from deleted items\n\t\tthis.data.attachEvent(\"onStoreUpdated\",bind(this._data_updated,this));\n\t\tthis.data.attachEvent(\"onStoreLoad\", bind(this._data_loaded,this));\n\t\tthis.data.attachEvent(\"onAfterFilter\", bind(this._data_filtered,this));\n\t\tthis.data.attachEvent(\"onSyncApply\", bind(this._select_check,this));\n\t\tthis.data.attachEvent(\"onIdChange\", bind(this._id_changed,this));\n\t\tthis.$ready.push(this._set_noselect);\n\t},\n\t_set_noselect: function(){\n\t\tif (this._settings.select==\"multiselect\" || this._settings.multiselect || this._settings.select==\"area\")\n\t\t\t_event(this.$view,\"mousedown\", function(e){\n\t\t\t\tif (e.shiftKey || (env.isIE && e.ctrlKey)){\n\t\t\t\t\tconst node = env.isIE ? document.body : this;\n\t\t\t\t\tstate._noselect_element = node;\n\t\t\t\t\taddCss(node, \"webix_noselect\", true);\n\t\t\t\t}\n\t\t\t});\n\t},\n\t_id_changed:function(oldid, newid){\n\t\tfor (var i = this._selected.length - 1; i >= 0; i--)\n\t\t\tif (this._selected[i]==oldid)\n\t\t\t\tthis._selected[i]=newid;\n\t},\n\t_data_filtered:function(){\n\t\tfor (var i = this._selected.length - 1; i >= 0; i--){\n\t\t\tif (this.data.getIndexById(this._selected[i]) < 0) {\n\t\t\t\tvar id = this._selected[i];\n\t\t\t\tthis.removeCss(id, \"webix_selected\", true);\n\t\t\t\tthis._selected.splice(i,1);\n\t\t\t\tthis.callEvent(\"onSelectChange\",[id]);\n\t\t\t}\n\t\t}\n\t},\n\t//helper - linked to onStoreUpdated\n\t_data_updated:function(id,obj,type){\n\t\tif (type == \"delete\"){\t\t\t\t//remove selection from deleted items\n\t\t\tif (this.loadBranch){\n\t\t\t\t//hierarchy, need to check all\n\t\t\t\tthis._select_check();\n\t\t\t} else{\n\t\t\t\tthis._selected.remove(id);\n\t\t\t\tthis.callEvent(\"onSelectChange\",[this._selected]);\n\t\t\t}\n\t\t}\n\t\telse if (!id && !this.data.count() && !this.data._filter_order && !this.data._filter_branch){\t//remove selection for clearAll\n\t\t\tthis._selected = _to_array();\n\t\t}\n\t},\n\t_data_loaded:function(){\n\t\tif (this._settings.select)\n\t\t\tthis.data.each(function(obj){\n\t\t\t\tif (obj && obj.$selected) this.select(obj.id);\n\t\t\t}, this);\n\t},\n\t_select_check:function(){\n\t\tlet selectionChanged;\n\t\tfor (let i = this._selected.length - 1; i >= 0; i--)\n\t\t\tif (!this.exists(this._selected[i])){\n\t\t\t\tselectionChanged = true;\n\t\t\t\tthis._selected.splice(i,1);\n\t\t\t}\n\t\tif(selectionChanged)\n\t\t\tthis.callEvent(\"onSelectChange\",[this._selected]);\n\t},\n\t//helper - changes state of selection for some item\n\t_select_mark:function(id,state,refresh,need_unselect){\n\t\tvar sname = state ? \"onBeforeSelect\" : \"onBeforeUnSelect\";\n\t\tif (!this.callEvent(sname,[id,state])) return false;\n\n\t\tif (need_unselect){\n\t\t\tthis._silent_selection = true;\n\t\t\tthis.unselectAll();\n\t\t\tthis._silent_selection = false;\n\t\t}\n\t\t\n\t\tif (state)\n\t\t\tthis.addCss(id, \"webix_selected\", true);\n\t\telse\n\t\t\tthis.removeCss(id, \"webix_selected\", true);\n\n\t\tif (refresh)\n\t\t\trefresh.push(id);\t\t\t\t//if we in the mass-select mode - collect all changed IDs\n\t\telse{\n\t\t\tif (state)\n\t\t\t\tthis._selected.push(id);\t\t//then add to list of selected items\n\t\t\telse\n\t\t\t\tthis._selected.remove(id);\n\t\t\tthis._refresh_selection(id);\t//othervise trigger repainting\n\t\t}\n\n\t\tvar ename = state ? \"onAfterSelect\" : \"onAfterUnSelect\";\n\t\tthis.callEvent(ename,[id]);\n\n\t\treturn true;\n\t},\n\t//select some item\n\tselect:function(id,preserve){\n\t\tvar ctrlKey = arguments[2];\n\t\tvar shiftKey = arguments[3];\n\t\t//if id not provide - works as selectAll\n\t\tif (!id) return this.selectAll();\n\n\t\t//allow an array of ids as parameter\n\t\tif (isArray(id)){\n\t\t\tfor (var i=0; i < id.length; i++)\n\t\t\t\tthis.select(id[i], (i?1:preserve), ctrlKey, shiftKey);\n\t\t\treturn;\n\t\t}\n\n\t\tassert(this.data.exists(id), \"Incorrect id in select command: \"+id);\n\t\t\n\t\t//block selection mode\n\t\tif (shiftKey && this._selected.length)\n\t\t\treturn this.selectAll(this._selected[this._selected.length-1],id);\n\n\t\t//single selection mode\n\t\tvar need_unselect = false;\n\t\tif (!ctrlKey && !preserve && (this._selected.length!=1 || this._selected[0]!=id))\n\t\t\tneed_unselect = true;\n\n\t\tif (!need_unselect && this.isSelected(id)){\n\t\t\tif (ctrlKey) this.unselect(id);\t//ctrl-selection of already selected item\n\t\t\treturn;\n\t\t}\n\n\t\tthis._select_mark(id, true, null, need_unselect);\n\t},\n\t//unselect some item\n\tunselect:function(id){\n\t\t//if id is not provided - unselect all items\n\t\tif (!id) return this.unselectAll();\n\t\tif (!this.isSelected(id)) return;\n\t\t\n\t\tthis._select_mark(id,false);\n\t},\n\t//select all items, or all in defined range\n\tselectAll:function(from,to){\n\t\tvar range;\n\t\tvar refresh=[];\n\t\t\n\t\tif (from||to)\n\t\t\trange = this.data.getRange(from||null,to||null);\t//get limited set if bounds defined\n\t\telse\n\t\t\trange = this.data.getRange();\t\t\t//get all items in other case\n\t\t//in case of paging - it will be current page only\n\t\trange.each(function(obj){ \n\t\t\tif (!this.data.getMark(obj.id, \"webix_selected\")){\n\t\t\t\tif(this._select_mark(obj.id,true,refresh))\n\t\t\t\t\tthis._selected.push(obj.id);\n\t\t\t}\n\t\t},this);\n\t\t//repaint self\n\t\tthis._refresh_selection(refresh);\n\t},\n\t//remove selection from all items\n\tunselectAll:function(){\n\t\tvar refresh=[];\n\t\t\n\t\tthis._selected.each(function(id){\n\t\t\tthis._select_mark(id,false,refresh);\t//unmark selected only\n\t\t},this);\n\t\t\n\t\tthis._selected=_to_array();\n\t\tthis._refresh_selection(refresh);\t//repaint self\n\t},\n\t//returns true if item is selected\n\tisSelected:function(id){\n\t\treturn this._selected.find(id)!=-1;\n\t},\n\t/*\n\t\treturns ID of selected items or array of IDs\n\t\tto make result predictable - as_array can be used, \n\t\t\twith such flag command will always return an array \n\t\t\tempty array in case when no item was selected\n\t*/\n\tgetSelectedId:function(as_array){\t\n\t\tswitch(this._selected.length){\n\t\t\tcase 0: return as_array?[]:\"\";\n\t\t\tcase 1: return as_array?[this._selected[0]]:this._selected[0];\n\t\t\tdefault: return ([].concat(this._selected)); //isolation\n\t\t}\n\t},\n\tgetSelectedItem:function(as_array){\n\t\tvar sel = this.getSelectedId(true);\n\t\tif (sel.length > 1 || as_array){\n\t\t\tfor (var i = sel.length - 1; i >= 0; i--)\n\t\t\t\tsel[i] = this.getItem(sel[i]);\n\t\t\treturn sel;\n\t\t} else if (sel.length)\n\t\t\treturn this.getItem(sel[0]);\n\t},\n\t//detects which repainting mode need to be used\n\t_is_mass_selection:function(obj){\n\t\t// crappy heuristic, but will do the job\n\t\treturn obj.length>100 || obj.length > this.data.count/2;\n\t},\n\t_refresh_selection:function(refresh){\n\t\tif (typeof refresh != \"object\") refresh = [refresh];\n\t\tif (!refresh.length) return;\t//nothing to repaint\n\t\t\n\t\tif (this._is_mass_selection(refresh))\t\n\t\t\tthis.data.refresh();\t//many items was selected - repaint whole view\n\t\telse\n\t\t\tfor (var i=0; i < refresh.length; i++)\t//repaint only selected\n\t\t\t\tthis.render(refresh[i],this.data.getItem(refresh[i]),\"update\");\n\t\t\t\n\t\tif (!this._silent_selection)\t\n\t\t\tthis.callEvent(\"onSelectChange\",[refresh]);\n\t}\n};\n\nready(function(){\n\tevent(document.body,\"mouseup\", function(){\n\t\tif(state._noselect_element){\n\t\t\tremoveCss(state._noselect_element,\"webix_noselect\");\n\t\t\tstate._noselect_element = null;\n\t\t}\n\t});\n});\n\nexport default SelectionModel;","import {isArray} from \"../webix/helpers\";\nimport {create, remove} from \"../webix/html\";\n\nconst color = {\n\t_toHex:[\"0\",\"1\",\"2\",\"3\",\"4\",\"5\",\"6\",\"7\",\"8\",\"9\",\"A\",\"B\",\"C\",\"D\",\"E\",\"F\"],\n\ttoHex:function(number, length){\n\t\tnumber=parseInt(number,10);\n\t\tvar str = \"\";\n\t\twhile (number>0){\n\t\t\tstr=this._toHex[number%16]+str;\n\t\t\tnumber=Math.floor(number/16);\n\t\t}\n\t\twhile (str.length 255)\n\t\t\tr = 0;\n\t\tif (g < 0 || g > 255)\n\t\t\tg = 0;\n\t\tif (b < 0 || b > 255)\n\t\t\tb = 0;\n\t\treturn [r,g,b];\n\t},\n\thsvToRgb:function(h, s, v){\n\t\tvar hi,f,p,q,t,r,g,b;\n\t\thi = Math.floor((h/60))%6;\n\t\tf = h/60-hi;\n\t\tp = v*(1-s);\n\t\tq = v*(1-f*s);\n\t\tt = v*(1-(1-f)*s);\n\t\tr = 0;\n\t\tg = 0;\n\t\tb = 0;\n\t\tswitch(hi) {\n\t\t\tcase 0:\n\t\t\t\tr = v; g = t; b = p;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tr = q; g = v; b = p;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tr = p; g = v; b = t;\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tr = p; g = q; b = v;\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\tr = t; g = p; b = v;\n\t\t\t\tbreak;\n\t\t\tcase 5:\n\t\t\t\tr = v; g = p; b = q;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t\tr = Math.floor(r*255);\n\t\tg = Math.floor(g*255);\n\t\tb = Math.floor(b*255);\n\t\treturn [r, g, b];\n\t},\n\trgbToHsv:function(r, g, b){\n\t\tvar r0,g0,b0,min0,max0,s,h,v;\n\t\tr0 = r/255;\n\t\tg0 = g/255;\n\t\tb0 = b/255;\n\t\tmin0 = Math.min(r0, g0, b0);\n\t\tmax0 = Math.max(r0, g0, b0);\n\t\th = 0;\n\t\ts = max0===0?0:(1-min0/max0);\n\t\tv = max0;\n\t\tif (max0 == min0) {\n\t\t\th = 0;\n\t\t} else if (max0 == r0 && g0>=b0) {\n\t\t\th = 60*(g0 - b0)/(max0 - min0)+0;\n\t\t} else if (max0 == r0 && g0 < b0) {\n\t\t\th = 60*(g0 - b0)/(max0 - min0)+360;\n\t\t} else if (max0 == g0) {\n\t\t\th = 60*(b0 - r0)/(max0-min0)+120;\n\t\t} else if (max0 == b0) {\n\t\t\th = 60*(r0 - g0)/(max0 - min0)+240;\n\t\t}\n\t\treturn [h, s, v];\n\t}\n};\n\nexport default color;","import {extend, copy} from \"../../webix/helpers\";\n\nimport SVG from \"./svg\";\n\nvar defaults = {\n\tpaddingY: 2\n};\n\nfunction Pie(config){\n\tthis.config = extend(copy(defaults),config||{},true);\n}\nPie.prototype._defColorsCursor = 0;\nPie.prototype._defColors = [\n\t\"#f55b50\",\"#ff6d3f\",\"#ffa521\",\"#ffc927\",\"#ffee54\",\"#d3e153\",\"#9acb61\",\"#63b967\",\n\t\"#21a497\",\"#21c5da\",\"#3ea4f5\",\"#5868bf\",\"#7b53c0\",\"#a943ba\",\"#ec3b77\",\"#9eb0b8\"\n];\nPie.prototype._getColor = function(i,data){\n\tvar count = data.length;\n\tvar colorsCount = this._defColors.length;\n\tif(colorsCount > count){\n\t\tif(i){\n\t\t\tif(i < colorsCount - count)\n\t\t\t\ti = this._defColorsCursor +2;\n\t\t\telse\n\t\t\t\ti = this._defColorsCursor+1;\n\t\t}\n\t\tthis._defColorsCursor = i;\n\t}\n\telse\n\t\ti = i%colorsCount;\n\treturn this._defColors[i];\n};\nPie.prototype.draw = function(data, width, height){\n\tvar attrs, graph, i, sectors,\n\t\tconfig = this.config,\n\t\tcolor = config.color||this._getColor,\n\t\tpoints = this.getAngles(data),\n\t\trenderer = SVG,\n\t\ty = config.paddingY|| 0,\n\t\t// radius\n\t\tr = height/2 - y,\n\t\t// center\n\t\tx0 = width/2, y0 = height/2;\n\n\t// draw sectors\n\tif(typeof color != \"function\")\n\t\tcolor = function(){return color;};\n\tsectors = \"\";\n\tfor( i =0; i < points.length; i++){\n\t\tattrs = {};\n\t\tattrs[renderer.styleMap[\"color\"]] = color.call(this,i,data,this._context);\n\t\tsectors += renderer.getSector({x:x0,y:y0},r,points[i][0],points[i][1],\"webix_sparklines_sector\", attrs);\n\t}\n\tgraph = renderer.group(sectors);\n\n\t// draw event areas\n\tsectors = \"\";\n\tfor(i =0; i < points.length; i++){\n\t\tsectors += renderer.getSector({x:x0,y:y0},r,points[i][0],points[i][1],\"webix_sparklines_event_area\",{\"webix_area\":i});\n\t}\n\tgraph += renderer.group(sectors);\n\n\tif(config.donut)\n\t\tgraph += SVG.getCircle({x:x0,y:y0}, config.innerRadius || r*0.5, \"webix_sparklines_donut_hole\");\n\n\treturn renderer.draw(graph, width, height, \"webix_sparklines_pie_chart\"+(config.css?\" \"+config.css:\"\"));\n};\nPie.prototype.getAngles = function(data){\n\tvar a0 = -Math.PI/ 2, a1,\n\t\ti, result = [];\n\n\tvar ratios = this._getRatios(data);\n\n\tfor( i =0; i < data.length; i++){\n\t\ta1= -Math.PI/2+ratios[i]-0.0001;\n\t\tresult.push([a0,a1]);\n\t\ta0 = a1;\n\t}\n\treturn result;\n};\nPie.prototype._getTotalValue = function(data){\n\tvar t=0;\n\tfor(var i = 0; i < data.length;i++)\n\t\tt += data[i]*1;\n\treturn t;\n};\nPie.prototype._getRatios = function(data){\n\tvar i, value,\n\t\tratios = [],\n\t\tprevSum = 0,\n\t\ttotalValue = this._getTotalValue(data);\n\tfor(i = 0; i < data.length;i++){\n\t\tvalue = data[i]*1;\n\t\tratios[i] = Math.PI*2*(totalValue?((value+prevSum)/totalValue):(1/data.length));\n\t\tprevSum += value;\n\t}\n\treturn ratios;\n};\n\nexport default Pie;","import {extend, copy} from \"../../webix/helpers\";\n\nimport SVG from \"./svg\";\nimport BaseLine from \"./line\";\nimport Area from \"./area\";\n\nconst defaults = {\n\tpadding: 6,\n\tradius: 2,\n\teventRadius: 8\n};\n\nfunction Radar(config){\n\tthis.config = extend(copy(defaults),config||{},true);\n}\n\nRadar.prototype.draw = function(data, width, height){\n\tconst line = BaseLine.prototype;\n\tconst area = Area.prototype;\n\n\tconst config = this.config;\n\tconst renderer = SVG;\n\tconst x0 = width/2;\n\tconst y0 = height/2;\n\n\tconst radius = Math.min(x0,y0) - config.padding;\n\n\tlet origin = \"\";\n\tconst points = [];\n\tconst originPoints = [];\n\tconst ratios = this._getRatios(data.length);\n\n\tdata = data.map(v => isNaN(v) ? 0 : v);\n\tconst max = Math.max(...data);\n\tlet min = Math.min(...data);\n\tif(min > 0)\n\t\tmin = 0;\n\n\tfor (let i = 0; i < data.length; i++) {\n\t\tconst angle = -Math.PI/2 +ratios[i];\n\n\t\toriginPoints.push(this._getPositionByAngle(angle, x0, y0, radius));\n\t\tconst x1 = originPoints[i].x;\n\t\tconst y1 = originPoints[i].y;\n\n\t\torigin += renderer.getLine({x:x0, y:y0},{x: x1, y: y1},\"webix_sparklines_origin\");\n\n\t\tlet x, y;\n\t\tif(data[i] == min){\n\t\t\tx = x0; y = y0;\n\t\t}\n\t\telse if(data[i] == max){\n\t\t\tx = x1; y = y1;\n\t\t}\n\t\telse{\n\t\t\tconst ratio = Math.abs(data[i]-min)/Math.abs(max - data[i]);\n\t\t\tx = (x0 + x1 * ratio) / (1 + ratio);\n\t\t\ty = (y0 + y1 * ratio) / (1 + ratio);\n\t\t}\n\n\t\tpoints.push({x, y});\n\t}\n\n\tconst styles = config.color ? area._applyColor(renderer, config.color) : null;\n\tconst originPath = renderer.definePath(line._getLinePoints(originPoints), true);\n\tconst path = renderer.definePath(line._getLinePoints(points), true);\n\n\tconst graph =\n\t\trenderer.group(origin + renderer.getPath(originPath, \"webix_sparklines_origin\")) +\n\t\trenderer.group(renderer.getPath(path, \"webix_sparklines_area\"+(styles?\" \"+styles.area:\"\"))) +\n\t\trenderer.group(renderer.getPath(path, \"webix_sparklines_line\"+(styles?\" \"+styles.line:\"\"))) +\n\t\tline._drawItems(renderer, points, config.radius, \"webix_sparklines_item\"+(styles?\" \"+styles.item:\"\")) +\n\t\tline._drawEventItems(renderer, points, config.eventRadius);\n\n\treturn renderer.draw(graph, width, height, \"webix_sparklines_radar_chart\"+(config.css?\" \"+config.css:\"\"));\n};\n\nRadar.prototype._getPositionByAngle = function(a,x,y,r){\n\ta *= (-1);\n\tx = x+Math.cos(a)*r;\n\ty = y-Math.sin(a)*r;\n\treturn {x,y};\n};\n\nRadar.prototype._getRatios = function(count){\n\tconst ratios = [];\n\tfor(let i = 0; i < count; i++){\n\t\tratios[i] = Math.PI*2*(i/count);\n\t}\n\treturn ratios;\n};\n\nexport default Radar;","\n\nconst TreeClick = {\n\twebix_tree_open:function(e, id){\n\t\tthis.close(id);\n\t\treturn false;\n\t},\n\twebix_tree_close:function(e, id){\n\t\tthis.open(id);\n\t\treturn false;\n\t},\n\twebix_tree_checkbox:function(e,id){\n\t\tthis._tree_check_uncheck(id, null, e);\n\t\treturn false;\n\t}\n};\n\nexport default TreeClick;","import {insertBefore, remove, create} from \"../webix/html\";\nimport {assert} from \"../webix/debug\";\n\n\nconst TreeRenderStack ={\n\t$init:function(){\n\t\tassert(this.render,\"TreeRenderStack :: Object must use RenderStack first\");\n\t},\n\t_toHTMLItem:function(obj){\n\t\tvar mark = this.data._marks[obj.id];\n\t\tthis.callEvent(\"onItemRender\",[obj]);\n\t\treturn this.type.templateStart(obj,this.type,mark)+(obj.$template?this.type[\"template\"+obj.$template](obj,this.type,mark):this.type.template(obj,this.type,mark))+this.type.templateEnd();\n\t},\n\t_toHTMLItemObject:function(obj){\n\t\tthis._html.innerHTML = this._toHTMLItem(obj);\n\t\treturn this._html.firstChild;\n\t},\n\t//convert single item to HTML text (templating)\n\t_toHTML:function(obj){\n\t\t//check if related template exist\n\t\tassert((!obj.$template || this.type[\"template\"+obj.$template]),\"RenderStack :: Unknown template: \"+obj.$template);\n\t\tvar html=\"\";\n\n\t\treturn html;\n\t},\n\t_toHTMLLevel:function(id){\n\t\tvar html = \"\";\n\t\tvar leaves = this.data.branch[id];\n\t\tif (leaves){\n\t\t\thtml+=\"\";\n\t\t}\n\t\treturn html;\n\t},\n\t//return true when some actual rendering done\n\trender:function(id,data,type){\n\t\tTreeRenderStack._obj = this;\t//can be used from complex render\n\n\t\tif (!this.isVisible(this._settings.id) || this.$blockRender)\n\t\t\treturn;\n\n\t\tif (id){\n\t\t\tvar cont, node;\n\t\t\tvar item = this.getItem(id);\n\t\t\tif (type!=\"add\"){\n\t\t\t\tcont = this.getItemNode(id);\n\t\t\t\tif (!cont) return;\n\t\t\t}\n\t\t\t\n\t\t\tswitch(type){\n\t\t\t\tcase \"branch\":\n\t\t\t\t\tvar branch = cont.parentNode;\n\t\t\t\t\tnode = this._toHTMLObject(item);\n\t\t\t\t\t\n\t\t\t\t\tinsertBefore(node, branch); \n\t\t\t\t\tremove(branch);\n\t\t\t\t\tthis._htmlmap = null;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"paint\":\n\t\t\t\tcase \"update\":\n\t\t\t\t\tnode = this._htmlmap[id] = this._toHTMLItemObject(item);\n\t\t\t\t\tinsertBefore(node, cont); \n\t\t\t\t\tremove(cont);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"delete\":\n\t\t\t\t\t//deleting not item , but full branch\n\t\t\t\t\tremove(cont.parentNode);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"add\":\n\t\t\t\t\tvar parent;\n\t\t\t\t\t//we want process both empty value and 0 as string\n\t\t\t\t\t//jshint -W041:true\n\t\t\t\t\tif (item.$parent == 0){\n\t\t\t\t\t\tparent = this._dataobj.firstChild;\n\t\t\t\t\t} else if(this.getItem(item.$parent).open){\n\t\t\t\t\t\tparent = this.getItemNode(item.$parent);\n\t\t\t\t\t\tif (parent){\n\t\t\t\t\t\t\t//when item created by the script, it will miss the container for child notes\n\t\t\t\t\t\t\t//create it on demand\n\t\t\t\t\t\t\tif (!parent.nextSibling){\n\t\t\t\t\t\t\t\tvar leafs = create(\"DIV\", { \"class\" : \"webix_tree_leaves\" },\"\");\n\t\t\t\t\t\t\t\tparent.parentNode.appendChild(leafs);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tparent = parent.nextSibling;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (parent){\n\t\t\t\t\t\tvar next = this.data.getNextSiblingId(id);\n\t\t\t\t\t\tnext = this.getItemNode(next);\n\t\t\t\t\t\tif (next)\n\t\t\t\t\t\t\tnext = next.parentNode;\n\n\t\t\t\t\t\tnode = this._toHTMLObject(item);\n\t\t\t\t\t\tthis._htmlmap[id] = node.firstChild;\n\t\t\t\t\t\tinsertBefore(node, next, parent);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.callEvent(\"onPartialRender\", [id,data,type]);\n\t\t} else {\n\t\t\t//full reset\n\t\t\tif (this.callEvent(\"onBeforeRender\",[this.data])){\n\t\t\t\t//will be used for lines management\n\t\t\t\tthis.type._tree_branch_render_state = [];\n\t\t\t\t//getTopRange - returns all elements on top level\n\t\t\t\tthis._dataobj.innerHTML = this._toHTMLLevel(0);\n\t\t\t\t\t\n\t\t\t\tthis._htmlmap = null; //clear map, it will be filled at first getItemNode\n\t\t\t\tthis.callEvent(\"onAfterRender\",[]);\n\t\t\t}\n\t\t}\n\n\t\t//clear after usage\n\t\tthis.type._tree_branch_render_state = 0;\n\t\tTreeRenderStack._obj = null;\n\t\treturn true;\n\t},\n\tgetItemNode:function(search_id){\n\t\tif (this._htmlmap)\n\t\t\treturn this._htmlmap[search_id];\n\t\t\t\n\t\t//fill map if it doesn't created yet\n\t\tthis._htmlmap={};\n\t\t\n\t\tvar t = this._dataobj.getElementsByTagName(\"DIV\");\n\t\tfor (var i=0; i < t.length; i++){\n\t\t\tvar id = t[i].getAttribute(this._id); //get item's\n\t\t\tif (id) \n\t\t\t\tthis._htmlmap[id]=t[i];\n\t\t}\n\t\t//call locator again, when map is filled\n\t\treturn this.getItemNode(search_id);\n\t},\n\t_branch_render_supported:1\n};\n\nexport default TreeRenderStack;","import {bind, extend, _to_array, copy, clone, isArray, uid, _power_array} from \"../webix/helpers\";\nimport {assert} from \"../webix/debug\";\nimport DataStore from \"../core/datastore\";\nimport DataDriver from \"../load/drivers/index\";\n\n\n// #include core/datastore.js\n// #include core/bind.js\n// #include core/treemove.js\n\nconst TreeStore = {\n\tname:\"TreeStore\",\n\t$init:function() {\n\t\tthis._filterMode={\n\t\t\t//level:1,\n\t\t\tshowSubItems:true\n\t\t};\n\t\tthis.branch = { 0:[] };\n\t\tthis.attachEvent(\"onParse\", function(driver){\n\t\t\tthis._set_child_scheme(driver.child);\n\t\t});\n\t\tthis.attachEvent(\"onClearAll\", bind(function(){\n\t\t\tthis._filter_branch = null;\n\t\t},this));\n\t},\n\tfilterMode_setter:function(mode){\n\t\treturn extend(this._filterMode, mode, true);\n\t},\n\t_filter_reset:function(preserve){\n\t\t//remove previous filtering , if any\n\t\tif (this._filter_branch && !preserve){\n\t\t\tthis.branch = this._filter_branch;\n\t\t\tthis.order = _to_array(copy(this.branch[0]));\n\t\t\tfor (var key in this.branch)\n\t\t\t\tif (key != \"0\")\t//exclude 0 - virtual root\n\t\t\t\t\tthis.getItem(key).$count = this.branch[key].length;\n\t\t\tdelete this._filter_branch;\n\t\t}\n\t},\n\t_filter_core:function(filter, value, preserve, filterMode){\n\t\t//for tree we have few filtering options\n\t\t//- filter leafs only\n\t\t//- filter data on specific level\n\t\t//- filter data on all levels\n\t\t//- in all cases we can show or hide empty folder\n\t\t//- in all cases we can show or hide childs for matched item\n\t\t\n\t\t//set new order of items, store original\n\t\tif (!preserve || !this._filter_branch){\n\t\t\tthis._filter_branch = this.branch;\n\t\t\tthis.branch = clone(this.branch);\n\t\t}\n\n\t\tthis.branch[0] = this._filter_branch_rec(filter, value, this.branch[0], 1, (filterMode||{}));\n\t},\n\t_filter_branch_rec:function(filter, value, branch, level, config){\n\t\t//jshint -W041\n\t\tvar neworder = [];\n\t\t\n\t\tvar allow = (config.level && config.level != level);\n\n\t\tfor (var i=0; i < branch.length; i++){\n\t\t\tvar id = branch[i];\n\t\t\tvar item = this.getItem(id);\n\t\t\tvar child_run = false;\n\t\t\tvar sub = this.branch[id];\n\n\t\t\tif (allow){\n\t\t\t\tchild_run = true;\n\t\t\t} else if (filter(this.getItem(id),value)){\n\t\t\t\tneworder.push(id);\n\t\t\t\t// open all parents of the found item\n\t\t\t\tif (config.openParents !== false){\n\t\t\t\t\tvar parentId = this.getParentId(id);\n\t\t\t\t\twhile(parentId && parentId != \"0\"){\n\t\t\t\t\t\tthis.getItem(parentId).open = 1;\n\t\t\t\t\t\tparentId = this.getParentId(parentId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t//in case of of fixed level filtering - do not change child-items\n\t\t\t\tif (config.level || config.showSubItems)\n\t\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\t//filtering level, not match\n\t\t\t\tchild_run = true;\n\t\t\t}\t\n\n\t\t\t//if \"filter by all levels\" - filter childs\n\t\t\tif (allow || !config.level){ \n\t\t\t\tif (sub){\n\t\t\t\t\tvar newsub = this.branch[id] = this._filter_branch_rec(filter, value, sub, level+1, config);\n\t\t\t\t\titem.$count = newsub.length;\n\t\t\t\t\tif (child_run && newsub.length)\n\t\t\t\t\t\tneworder.push(id);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn neworder;\n\t},\n\tcount:function(){\n\t\tif (this.order.length)\n\t\t\treturn this.order.length;\n\n\t\t//we must return some non-zero value, or logic of selection will think that we have not data at all\n\t\tvar count=0;\n\t\tthis.eachOpen(function(){ count++; });\n\t\treturn count;\n\t},\n\t_change_branch_id:function(branches, parent, old, newid){\n\t\tif (branches[old]){\n\t\t\tvar branch = branches[newid] = branches[old];\n\t\t\tfor (var i = 0; i < branch.length; i++)\n\t\t\t\tthis.getItem(branch[i]).$parent = newid;\n\t\t\tdelete branches[old];\n\t\t}\n\t\tif (branches[parent]){\n\t\t\tvar index = _power_array.find.call(branches[parent], old);\n\t\t\tif (index >= 0)\n\t\t\t\tbranches[parent][index] = newid;\n\t\t}\n\t},\n\tchangeId:function(old, newid){\n\t\tif(old == newid) return;\n\t\t\n\t\tvar parent = this.getItem(old).$parent;\n\t\tthis._change_branch_id(this.branch, parent, old, newid);\n\n\t\t//in case of filter applied, update id in filtered state as well\n\t\tif (this._filter_branch)\n\t\t\tthis._change_branch_id(this._filter_branch, parent, old, newid);\n\n\t\treturn DataStore.prototype.changeId.call(this, old, newid);\n\t},\n\tclearAll:function(soft){\n\t\tthis.branch = { 0:[] };\n\t\tDataStore.prototype.clearAll.call(this, soft);\t\n\t},\n\tgetPrevSiblingId:function(id){\n\t\tvar order = this.branch[this.getItem(id).$parent];\n\t\tvar pos = _power_array.find.call(order, id)-1;\n\t\tif (pos>=0)\n\t\t\treturn order[pos];\n\t\treturn null;\n\t},\n\tgetNextSiblingId:function(id){\n\t\tvar order = this.branch[this.getItem(id).$parent];\n\t\tvar pos = _power_array.find.call(order, id)+1;\n\t\tif (pos=0; i--)\n\t\t\t\tnewbranch[i] = this.pull[bset[i]];\n\n\t\t\tnewbranch.sort(sorter);\n\t\t\tbranch[key] = newbranch.map(a => a.id);\n\t\t}\n\t\treturn order;\n\t},\n\tadd:function(obj, index, pid){\n\t\tvar refresh_parent = false;\n\n\t\tvar parent = this.getItem(pid||0);\n\t\tif(parent){\n\t\t\t//when adding items to leaf item - it need to be repainted\n\t\t\tif (!this.branch[parent.id])\n\t\t\t\trefresh_parent = true;\n\n\t\t\tparent.$count++;\n\t\t\t//fix for the adding into dynamic loading branch\n\t\t\t//dynamic branch has $count as -1\n\t\t\tif (!parent.$count) parent.$count = 1;\n\t\t}\n\n\t\tthis.branch[pid||0] = this.order = _to_array(this.branch[pid||0]);\n\n\t\tobj.$count = obj.webix_kids ? -1 : 0; \n\t\tobj.$level= (parent?parent.$level+1:1); \n\t\tobj.$parent = (parent?parent.id:0);\n\n\t\tif (this._filter_branch){\t//adding during filtering\n\t\t\tvar origin = this._filter_branch[pid||0];\n\t\t\t//newly created branch\n\t\t\tif (!origin) origin = this._filter_branch[pid] = this.order;\n\n\t\t\t//branch can be shared bettwen collections, ignore such cases\n\t\t\tif (this.order !== origin){\n\t\t\t\t//we can't know the location of new item in full dataset, making suggestion\n\t\t\t\t//put at end by default\n\t\t\t\tvar original_index = origin.length;\n\t\t\t\t//put at start only if adding to the start and some data exists\n\t\t\t\tif (!index && this.branch[pid||0].length)\n\t\t\t\t\toriginal_index = 0;\n\n\t\t\t\torigin = _to_array(origin);\n\t\t\t\tobj.id = obj.id || uid();\n\t\t\t\torigin.insertAt(obj.id,original_index);\n\t\t\t}\n\t\t}\n\n\t\t//call original adding logic\n\t\tvar result = DataStore.prototype.add.call(this, obj, index);\n\n\n\t\tif (refresh_parent)\n\t\t\tthis.refresh(pid);\n\n\t\treturn result;\n\t},\n\t_rec_remove:function(id){\n\t\tvar obj = this.pull[id];\n\t\tif(this.branch[obj.id] && this.branch[obj.id].length > 0){\n\t\t\tvar branch = this.branch[id];\n\t\t\tfor(var i=0;i= state.y + this._content_height)\n\t\t\tthis.scrollTo(0, dy);\n\t},\n\t//repain self after changes in DOM\n\t//for add, delete, move operations - render is delayed, to minify performance impact\n\trender:function(id,data,type){\n\t\tif (!this.isVisible(this._settings.id) || this.$blockRender)\n\t\t\treturn;\n\t\t\n\t\tif (id){\n\t\t\tvar cont = this.getItemNode(id);\t//old html element\n\t\t\tswitch(type){\n\t\t\t\tcase \"update\":\n\t\t\t\t\tif (!cont) return;\n\t\t\t\t\t//replace old with new\n\t\t\t\t\tvar t = this._htmlmap[id] = this._toHTMLObject(data);\n\t\t\t\t\tinsertBefore(t, cont); \n\t\t\t\t\tremove(cont);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault: // \"move\", \"add\", \"delete\"\n\t\t\t\t\t/*\n\t\t\t\t\t\tfor all above operations, full repainting is necessary\n\t\t\t\t\t\tbut from practical point of view, we need only one repainting per thread\n\t\t\t\t\t\tcode below initiates double-thread-rendering trick\n\t\t\t\t\t*/\n\t\t\t\t\tthis._render_delayed();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\t//full repainting\n\t\t\tif (this.callEvent(\"onBeforeRender\",[this.data])){\n\t\t\t\tthis._htmlmap = {}; \t\t\t\t\t//nulify links to already rendered elements\n\t\t\t\tthis._render_visible_rows(null, true);\t\n\t\t\t\t// clear delayed-rendering, because we already have repaint view\n\t\t\t\tthis._wait_for_render = false;\t\t\t\n\t\t\t\tthis.callEvent(\"onAfterRender\",[]);\n\t\t\t}\n\t\t}\n\t},\n\t//implement double-thread-rendering pattern\n\t_render_delayed:function(){\n\t\t//this flag can be reset from outside, to prevent actual rendering \n\t\tif (this._wait_for_render) return;\n\t\tthis._wait_for_render = true;\t\n\t\t\n\t\twindow.setTimeout(bind(function(){\n\t\t\tthis.render();\n\t\t},this),1);\n\t},\n\t//create empty placeholders, which will take space before rendering\n\t_create_placeholder:function(height){\n\t\tif(env.maxHTMLElementSize)\n\t\t\theight = Math.min(env.maxHTMLElementSize, height);\n\t\tvar node = document.createElement(\"DIV\");\n\t\tnode.style.cssText = \"height:\"+height+\"px; width:100%; overflow:hidden;\";\n\t\treturn node;\n\t},\n\t/*\n\t\tMethods get coordinatest of visible area and checks that all related items are rendered\n\t\tIf, during rendering, some not-loaded items was detected - extra data loading is initiated.\n\t\treset - flag, which forces clearing of previously rendered elements\n\t*/\n\t_render_visible_rows:function(e,reset){\n\t\tthis._unrendered_area=[]; //clear results of previous calls\n\t\t\n\t\tvar viewport = this._getVisibleRange();\t//details of visible view\n\n\t\tif (!this._dataobj.firstChild || reset){\t//create initial placeholder - for all view space\n\t\t\tthis._dataobj.innerHTML=\"\";\n\t\t\tthis._dataobj.appendChild(this._create_placeholder(viewport._max));\n\t\t\t//register placeholder in collection\n\t\t\tthis._htmlrows = [this._dataobj.firstChild];\n\t\t}\n\t\t\n\t\t/*\n\t\t\tvirtual rendering breaks all view on rows, because we know widht of item\n\t\t\twe can calculate how much items can be placed on single row, and knowledge \n\t\t\tof that, allows to calculate count of such rows\n\t\t\t\n\t\t\teach time after scrolling, code iterate through visible rows and render items \n\t\t\tin them, if they are not rendered yet\n\t\t\t\n\t\t\tboth rendered rows and placeholders are registered in _htmlrows collection\n\t\t*/\n\n\t\t//position of first visible row\n\t\tvar t = viewport._from;\n\t\t\t\n\t\twhile(t<=viewport._height){\t//loop for all visible rows\n\t\t\t//skip already rendered rows\n\t\t\twhile(this._htmlrows[t] && this._htmlrows[t]._filled && t<=viewport._height){\n\t\t\t\tt++; \n\t\t\t}\n\t\t\t//go out if all is rendered\n\t\t\tif (t>viewport._height) break;\n\t\t\t\n\t\t\t//locate nearest placeholder\n\t\t\tvar holder = t;\n\t\t\twhile (!this._htmlrows[holder]) holder--;\n\t\t\tvar holder_row = this._htmlrows[holder];\n\t\t\t\n\t\t\t//render elements in the row\t\t\t\n\t\t\tvar base = t*viewport._dx+(this.data.$min||0);\t//index of rendered item\n\t\t\tif (base > (this.data.$max||Infinity)) break;\t//check that row is in virtual bounds, defined by paging\n\t\t\tvar nextpoint = Math.min(base+viewport._dx-1,(this.data.$max?this.data.$max-1:Infinity));\n\t\t\tvar node = this._create_placeholder(viewport._y);\n\t\t\t//all items in rendered row\n\t\t\tvar range = this.data.getIndexRange(base, nextpoint);\n\t\t\tif (!range.length) break; \n\t\t\t\n\t\t\tvar loading = { $template:\"Loading\" };\n\t\t\tfor (let i=0; i0){\n\t\t\t\tholder_row.style.height = delta2+\"px\";\n\t\t\t\tthis._htmlrows[t+1] = holder_row;\n\t\t\t} else {\n\t\t\t\tif (delta<0)\n\t\t\t\t\tremove(holder_row);\n\t\t\t\telse\n\t\t\t\t\tholder_row.style.height = delta+\"px\";\n\t\t\t\tif (delta2>0){ \n\t\t\t\t\tvar new_space = this._htmlrows[t+1] = this._create_placeholder(delta2);\n\t\t\t\t\tinsertBefore(new_space,node.nextSibling,this._dataobj);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t\n\t\t\tt++;\n\t\t}\n\t\t\n\t\t//when all done, check for non-loaded items\n\t\tif (this._unrendered_area.length){\n\t\t\t//we have some data to load\n\t\t\t//detect borders\n\t\t\tvar from = this._unrendered_area[0];\n\t\t\tvar to = this._unrendered_area.pop()+1;\n\t\t\tif (to>from){\n\t\t\t\t//initiate data loading\n\t\t\t\tvar count = to - from;\n\t\t\t\tif (this._maybe_loading_already(count, from)) return;\n\n\t\t\t\tcount = Math.max(count, (this._settings.datafetch||this._settings.loadahead||0));\n\t\t\t\tthis.loadNext(count, from);\n\t\t\t}\n\t\t}\n\t},\n\t//calculates visible view\n\t_getVisibleRange:function(){\n\t\tvar state = this.getScrollState();\n\t\tvar top = Math.max(0, state.y);\n\t\tvar tpadding = this._tilesPadding||0;\n\t\tvar width = this._content_width - tpadding; \n\t\tvar height = this._content_height - tpadding/2;\n\n\t\t//size of single item\n\t\tvar t = this.type;\n\n\t\tvar dx = Math.floor(width/t.width)||1; //at least single item per row\n\t\t\n\t\tvar min = Math.floor(top/t.height);\t\t\t\t//index of first visible row\n\t\tvar dy = Math.ceil((height+top)/t.height)-1;\t\t//index of last visible row\n\t\t//total count of items, paging can affect this math\n\t\tvar count = this.data.$max?(this.data.$max-this.data.$min):this.data.count();\n\t\tvar max = Math.ceil(count/dx)*t.height;\t\t\t//size of view in rows\n\n\t\treturn { _from:min, _height:dy, _top:top, _max:max, _y:t.height, _dx:dx};\n\t},\n\t_cellPosition:function(id){\n\t\tvar html = this.getItemNode(id);\n\t\tif (!html){\n\t\t\tthis.showItem(id);\n\t\t\tthis._render_visible_rows();\n\t\t\thtml = this.getItemNode(id);\n\t\t}\n\t\treturn {\n\t\t\tleft:html.offsetLeft, \n\t\t\ttop:html.offsetTop,\n\t\t\theight:html.offsetHeight,\n\t\t\twidth:html.offsetWidth,\n\t\t\tparent:this._contentobj\n\t\t};\n\t}\n};\n\nexport default VirtualRenderStack;","import {offset, insertBefore, remove} from \"../webix/html\";\nimport {bind, copy, _to_array} from \"../webix/helpers\";\nimport base from \"../views/view\";\nimport {_event} from \"../webix/htmlevents\";\n\nimport DragControl from \"../core/dragcontrol\";\n\n/*\n\tRenders collection of items on demand\n*/\nconst VRenderStack = {\n\t$init:function(){\n\t\tthis._htmlmap = {};\n\t\t_event(this._viewobj, \"scroll\", bind(function(){\n\t\t\tthis.render(null, null, \"paint\");\n\t\t}, this));\n\t},\n\t//return html container by its ID\n\t//can return undefined if container doesn't exists\n\tgetItemNode:function(search_id){\n\t\treturn this._htmlmap && this._htmlmap[search_id];\n\t},\n\t/*change scrolling state of top level container, so related item will be in visible part*/\n\tshowItem:function(id){\n\t\tconst index = this.data.getIndexById(id);\n\t\tif (index > -1){\n\t\t\tconst top = index * this.type.height;\n\t\t\tconst bottom = top + this.type.height;\n\t\t\tconst scroll = this.getScrollState();\n\t\t\tconst box = offset(this.$view);\n\t\t\tif (top < scroll.y)\n\t\t\t\tthis.scrollTo(0, top);\n\t\t\telse if (bottom > scroll.y+box.height)\n\t\t\t\tthis.scrollTo(0, bottom-box.height);\n\t\t}\n\t},\n\t//update view after data update\n\t//when called without parameters - all view refreshed\n\trender:function(id,data,type){\n\t\tif (!this.isVisible(this._settings.id) || this.$blockRender)\n\t\t\treturn;\n\t\t\n\t\tconst parent = (this._renderobj||this._dataobj);\n\n\t\tif (id){\n\t\t\tif (type == \"paint\" || type == \"update\"){\n\t\t\t\tconst cont = this.getItemNode(id); //get html element of updated item\n\t\t\t\tif (cont){\n\t\t\t\t\tconst t = this._htmlmap[id] = this._toHTMLObject(data);\n\t\t\t\t\tt.style.top = cont.style.top;\n\t\t\t\t\tt.style.position = \"absolute\";\n\t\t\t\t\tt.style.left = 0; t.style.width = \"100%\";\n\n\t\t\t\t\tinsertBefore(t, cont); \n\t\t\t\t\tremove(cont);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t//updating not rendered yet item\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tlet isDrag, source, marked = this._marked_item_id;\n\t\tif (DragControl.active && type != \"drag-end\"){\n\t\t\tconst context = DragControl.getContext();\n\t\t\tisDrag = this._init_drop_area && context.from === this;\t\t//move and order modes\n\t\t\tsource = isDrag && _to_array(copy(context.source||[]));\n\t\t}\n\n\t\tif (type != \"paint\" || isDrag){\n\t\t\t//repaint all\n\t\t\tthis._htmlmap = {};\n\t\t\tparent.innerHTML = \"\";\n\t\t}\n\n\t\t//full reset\n\t\tif (this.callEvent(\"onBeforeRender\",[this.data])){\n\t\t\tconst count = this.data.count();\n\t\t\tconst scroll = this.getScrollState();\n\t\t\tconst box = offset(this._viewobj);\n\n\t\t\tlet top = Math.floor(scroll.y / this.type.height)-2;\n\t\t\tlet bottom = Math.ceil((scroll.y + box.height) / this.type.height)+2;\n\n\t\t\ttop = Math.max(0, top);\n\t\t\tbottom = Math.min(count-1, bottom+(isDrag?source.length-1:0));\n\n\t\t\tconst html = [];\n\t\t\tfor (let i=top; i<=bottom; i++){\n\t\t\t\tconst sid = this.data.order[i];\n\t\t\t\tif (isDrag && source.find(sid) !== -1){\n\t\t\t\t\tif (sid == marked) marked = this.data.order[i+1];\n\t\t\t\t\tcontinue;\n\t\t\t\t} else if (!this._htmlmap[sid]){\n\t\t\t\t\tconst item = this.data.getItem(sid);\n\t\t\t\t\tif (!item){\n\t\t\t\t\t\tthis._run_load_next({ \n\t\t\t\t\t\t\tcount:bottom-i+(this._settings.loadahead || 0),\n\t\t\t\t\t\t\tstart:i \n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\thtml.push(this._toHTML(item));\n\t\t\t\t} else {\n\t\t\t\t\thtml.push(`
`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._html.innerHTML = html.join(\"\");\n\n\t\t\tif (this._init_drop_area && type == \"drag-in\"){\t\t\t// can be external\n\t\t\t\tconst node = this._html.querySelector(`[${this._id}=\"${marked}\"]`);\n\t\t\t\tif (node) {\n\t\t\t\t\tthis._html.insertBefore(DragControl._dropHTML[0], node);\n\t\t\t\t} else this._html.appendChild(DragControl._dropHTML[0]);\n\t\t\t}\n\n\t\t\tparent.style.position = \"relative\";\n\t\t\tparent.style.height = count*this.type.height+\"px\";\n\n\t\t\tconst kids = this._html.childNodes;\n\t\t\tfor (let i=kids.length-1; i>=0; i--){\n\t\t\t\tconst child = kids[i];\n\t\t\t\tif (child.getAttribute(\"webix_skip\")) continue;\n\n\t\t\t\tconst cid = child.getAttribute(this._id);\n\t\t\t\tif (cid){\n\t\t\t\t\tchild.style.position = \"absolute\";\n\t\t\t\t\tchild.style.top = (top+i)*this.type.height+\"px\";\n\t\t\t\t\tchild.style.left = 0; child.style.width = \"100%\";\n\n\t\t\t\t\tparent.appendChild(child);\n\t\t\t\t\tthis._htmlmap[cid] = child;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tthis.callEvent(\"onAfterRender\",[]);\n\t\t}\n\t},\n\t$setSize:function(){\n\t\tif (base.api.$setSize.apply(this, arguments)){\n\t\t\tthis.render(null, null, \"paint\");\n\t\t}\n\t},\n\t_run_load_next:function(conf){\n\t\tconst count = Math.max(conf.count, (this._settings.datafetch||this._settings.loadahead||0));\n\t\tif (this._maybe_loading_already(conf.count, conf.start)) return;\n\t\tthis.loadNext(count, conf.start);\n\t},\n\t_set_drop_area:function(){\n\t\tthis.render(null, null, \"drag-in\");\n\t},\n\t_remove_drop_area:function(){\n\t\tremove(DragControl._dropHTML);\n\t\tthis.render(null, null, \"drag-out\");\n\t},\n};\n\nexport default VRenderStack;","import {$active} from \"../../webix/skin\";\nimport {extend, isUndefined} from \"../../webix/helpers\";\n\nexport const errorMessage = \"non-existing view for export\";\n\nfunction getDataHelper(key, column, raw){\n\tif (!raw && column.format)\n\t\treturn function(obj){ return column.format(obj[key]); };\n\n\treturn function(obj){ return obj[key]; };\n}\n\nfunction getHeaderText(view, header){\n\tlet text = header.text;\n\tif (header.contentId){\n\t\tconst content = view.getHeaderContent(header.contentId);\n\t\tif (content && !content.type.$icon)\n\t\t\ttext = content.getValue(true);\n\t}\n\treturn (text||\"\").toString().replace( /<[^>]*>/gi, \"\");\n}\n\nexport function getStyles(r, c, styles){\n\t//row index, column index, styles array\n\tif(styles[r] && styles[r][c])\n\t\treturn styles[r][c];\n\treturn {};\n}\n\nexport function getExportScheme(view, options){\n\tconst scheme = [];\n\tlet h_count = 0, f_count = 0;\n\tconst isTable = view.getColumnConfig;\n\tlet columns = options.columns;\n\tconst raw = !!options.rawValues;\n\tconst isTree = view.data.name == \"TreeStore\";\n\n\tlet treeLines = options.treeLines;\n\tif(treeLines === true || isUndefined(treeLines))\n\t\ttreeLines = \"value\";\n\n\tscheme.heights = {};\n\n\tif(options.hidden || options.hide){\n\t\tscheme.hiddenCols = {};\n\t\tscheme.hiddenRows = {};\n\t}\n\n\tif (!columns){\n\t\tcolumns = [];\n\t\tif (isTable){\n\t\t\tconst order = view._hidden_column_order;\n\t\t\tif(options.hidden && order.length){\n\t\t\t\tfor (let i = 0; i < order.length; i++){\n\t\t\t\t\tconst col = view.getColumnConfig(order[i]);\n\t\t\t\t\tif(!view.isColumnVisible(col.id))\n\t\t\t\t\t\tscheme.hiddenCols[col.id] = 1;\n\t\t\t\t\tcolumns.push(col);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\tcolumns = columns.concat(view._columns);\n\t\t}\n\t\telse {\n\t\t\tconst obj = view.data.pull[view.data.order[0]];\n\t\t\tfor (let key in obj)\n\t\t\t\tif(key !== \"id\" && key[0] != \"$\")\n\t\t\t\t\tcolumns.push({id:key, isTree: isTree && key === treeLines});\n\t\t}\n\t}\n\telse if(!columns.length){\n\t//export options are set as - columns:{ rank:true, title:{ header:\"custom\"}}\n\t\tconst arr = [];\n\t\tfor(let key in columns)\n\t\t\tarr.push(extend({ id:key}, extend({}, columns[key])));\n\t\tcolumns = arr;\n\t}\n\n\tif (options.ignore)\n\t\tfor (let i=columns.length-1; i>=0; i--)\n\t\t\tif (options.ignore[columns[i].id])\n\t\t\t\tcolumns.splice(i,1);\n\n\tif (options.id)\n\t\tscheme.push({ id:\"id\", width:50, header:\" \", template:function(obj){ return obj.id; }});\n\n\tif (options.flatTree){\n\t\tconst flatKey = options.flatTree.id;\n\t\tconst copy = [].concat(options.flatTree.columns);\n\t\tconst fill = [];\n\t\tconst fillMode = !!options.flatTree.fill;\n\t\tfor (let i = 1; i <= copy.length; i++)\n\t\t\tcopy[i-1].template = (function(i){ \n\t\t\t\treturn function(obj){ \n\t\t\t\t\treturn obj.$level == i ? (fill[i]=obj[flatKey]) : ((fillMode && i= 0; i--)\n\t\t\tif (columns[i].id === flatKey)\n\t\t\t\tindex = i;\n\n\t\tcolumns = [].concat(columns.slice(0,index)).concat(copy).concat(columns.slice(index+1));\n\t}\n\n\tlet treeColumn;\n\n\tfor (let j = 0; j < columns.length; j++) {\n\t\tlet column = columns[j];\n\t\tlet key = column.id;\n\n\t\tif (column.noExport) continue;\n\n\t\t// raw mode has sense only for datatable\n\t\t// in other cases we don't have built-in data templates\n\t\tlet rawColumn = raw && isTable;\n\t\tif (isTable){\n\t\t\tconst sourceColumn = view.getColumnConfig(key);\n\t\t\t// when these's no column to take raw data from, or custom template defined - ignore raw mode\n\t\t\tif (column.template && (!sourceColumn || sourceColumn.template != column.template))\n\t\t\t\trawColumn = false;\n\t\t\tif(sourceColumn)\n\t\t\t\tcolumn = extend(extend({}, column), sourceColumn);\n\t\t}\n\n\t\tconst record = {\n\t\t\tid: column.id,\n\t\t\ttemplate: (( rawColumn || !column.template) ? getDataHelper(key, column, raw) : column.template ),\n\t\t\twidth: ((column.width || 200) * (options.export_mode===\"excel\"?8.43/70:1 )),\n\t\t\theader: (column.header!==false?(column.header||key) : \"\")\n\t\t};\n\n\t\tif (column.collection) record.collection = column.collection;\n\n\t\tif(isTree && key === treeLines)\n\t\t\trecord.isTree = treeColumn = true;\n\n\t\tif(options.export_mode === \"excel\"){\n\t\t\textend(record, {\n\t\t\t\ttype: column.exportType || \"\",\n\t\t\t\tformat:column.exportFormat || \"\"\n\t\t\t});\n\t\t\tif(column.hidden){\n\t\t\t\tif(!scheme.hiddenCols)\n\t\t\t\t\tscheme.hiddenCols = {};\n\t\t\t\tscheme.hiddenCols[column.id] = 1;\n\t\t\t}\n\t\t}\n\n\t\tif(typeof record.header === \"string\") record.header = [{text:record.header}];\n\t\telse record.header = [].concat(record.header);\n\n\t\tfor(let i = 0; i:*|\"]/g, \"\").substring(0, 150);\n\treturn `${name || \"Data\"}.${extension}`;\n}\n\nexport function getExportData(view, options, scheme){\n\tconst filterHTML = !!options.filterHTML;\n\tconst htmlFilter = /<[^>]*>/gi;\n\tlet data = [];\n\tlet header, headers;\n\tconst mode = options.export_mode;\n\n\tif((mode === \"excel\" || mode == \"csv\") && options.docHeader){\n\t\tdata = [[(options.docHeader.text || options.docHeader).toString()], [\"\"]];\n\t\tif(mode === \"excel\" && options.docHeader.height)\n\t\t\tscheme.heights[0] = options.docHeader.height;\n\t}\n\n\tif( options.header !== false && scheme.length){\n\t\tfor(let h=0; h < scheme[0].header.length; h++){\n\t\t\theaders = [];\n\t\t\tfor (let i = 0; i < scheme.length; i++){ \n\t\t\t\theader = \"\";\n\t\t\t\tif(scheme[i].header[h]){\n\t\t\t\t\theader = scheme[i].header[h];\n\t\t\t\t\tif (filterHTML)\n\t\t\t\t\t\theader = scheme[i].header[h] = header.replace(htmlFilter, \"\");\n\t\t\t\t}\n\t\t\t\theaders.push(header);\n\t\t\t}\n\n\t\t\tif(mode ==\"excel\" && view._columns && options.heights !==false &&\n\t\t\t(view._headers[h] !== $active.barHeight || options.heights == \"all\")\n\t\t\t) scheme.heights[data.length] = view._headers[h];\n\n\t\t\tif (mode !== \"pdf\")\n\t\t\t\tdata[data.length] = headers;\n\t\t}\n\t}\n\toptions.yCorrection = (options.yCorrection||0)-data.length;\n\n\tconst treeline = (options.flatTree || options.plainOutput) ? \"\" : \"-\";\n\n\tview.data.each(function(item, index){\n\t\tif(!options.filter || options.filter(item)){\n\t\t\tconst reallyHidden = options.hidden && view.data._filter_order && view.getIndexById(item.id) == -1;\n\t\t\tif((options.hide && options.hide(item)) || reallyHidden){\n\t\t\t\tconst header = (options.docHeader?2:0)+(options.header===false?0:scheme[0].header.length);\n\t\t\t\tscheme.hiddenRows[header+index] = 1;\n\t\t\t}\n\n\t\t\tif(this.data._scheme_export){\n\t\t\t\titem = view.data._scheme_export(item);\n\t\t\t}\n\n\t\t\tlet line = [];\n\t\t\tfor (let i = 0; i < scheme.length; i++){\n\t\t\t\tlet column = scheme[i], cell = null;\n\t\t\t\t//spreadsheet use muon to store data, get value via $getExportValue\n\t\t\t\tif(view.$getExportValue)\n\t\t\t\t\tcell = view.$getExportValue(item.id, column.id, options);\n\t\t\t\telse {\n\t\t\t\t\t//datatable math\n\t\t\t\t\tlet formula;\n\t\t\t\t\tif(options.math && item[\"$\"+column.id] && item[\"$\"+column.id].charAt(0) ==\"=\"){\n\t\t\t\t\t\tif(mode == \"excel\")\n\t\t\t\t\t\t\tformula = item[\"$\"+column.id];\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tcell = item[\"$\"+column.id];\n\t\t\t\t\t}\n\n\t\t\t\t\tif(this._spans_pull){\n\t\t\t\t\t\tlet span = this.getSpan(item.id, column.id);\n\t\t\t\t\t\tif(span && span[4] && span[0] == item.id && span[1] == column.id){\n\t\t\t\t\t\t\tcell = span[4];\n\t\t\t\t\t\t\tif(filterHTML && typeof cell === \"string\")\n\t\t\t\t\t\t\t\tcell = cell.replace(htmlFilter, \"\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(!cell){\n\t\t\t\t\t\tcell = column.template(item, view.type, item[column.id], column, i);\n\t\t\t\t\t\tif (!cell && cell !== 0) cell = \"\";\n\t\t\t\t\t\tif(column.isTree && treeline)\n\t\t\t\t\t\t\tcell = \" \"+Array(item.$level).join(treeline)+\" \"+cell;\n\t\t\t\t\t\tif (filterHTML && typeof cell === \"string\"){\n\t\t\t\t\t\t\tcell = cell.replace(htmlFilter, \"\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//remove end/start spaces(ex.hierarchy data)\n\t\t\t\t\t\tif (typeof cell === \"string\" && mode === \"csv\")\n\t\t\t\t\t\t\tcell = cell.trim();\n\t\t\t\t\t\t//for multiline data\n\t\t\t\t\t\tif (typeof cell === \"string\" && (mode === \"excel\" || mode === \"csv\")){\n\t\t\t\t\t\t\tcell = cell.replace(//mg,\"\\n\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(formula)\n\t\t\t\t\t\tcell = { formula, value: cell };\n\t\t\t\t}\n\n\t\t\t\tline.push(cell);\n\t\t\t}\n\n\t\t\tif(mode ==\"excel\" && view._columns && options.heights !== false &&\n\t\t\t((item.$height && item.$height !== $active.rowHeight) || options.heights == \"all\")\n\t\t\t) scheme.heights[data.length] = item.$height || this.config.rowHeight;\n\n\t\t\tdata.push(line);\n\t\t}\n\t}, view, options.hidden);\n\n\tif( options.footer !==false ){\n\t\tlet f_count = scheme[0].footer?scheme[0].footer.length:0;\n\t\tfor (let f = 0; f < f_count; f++){\n\t\t\tlet footers = [];\n\t\t\tfor(let i = 0; i
\";\n\t\tthis._contentobj = this._viewobj;\n\t\tthis._headobj = this._contentobj.childNodes[0];\n\t\tif(!config.header)\n\t\t\tthis._headobj.style.display = \"none\";\n\t\tthis._headlabel = this._contentobj.childNodes[0].childNodes[1];\n\t\tthis._headbutton = this._contentobj.childNodes[0].childNodes[0];\n\t\tthis._bodyobj = this._contentobj.childNodes[1];\n\t\tthis._viewobj.className +=\" webix_accordionitem\";\n\t\tthis._head_cell = this._body_cell = null;\n\t\tthis._cells = true;\n\n\t\tthis._bodyobj.setAttribute(\"role\", \"tabpanel\");\n\t\tthis._headobj.setAttribute(\"role\", \"tab\");\n\n\t\tthis.attachEvent(\"onKeyPress\", this._onKeyPress);\n\t},\n\t_remove:function(){\n\t\tthis.body_setter();\n\t},\n\t_replace:function(new_view){\n\t\tthis._body_cell.destructor();\n\t\tthis._body_cell = new_view;\n\t\t\n\t\tthis._bodyobj.appendChild(this._body_cell._viewobj);\n\t\tthis.resize();\n\t},\n\t_id:/*@attr*/\"webix_ai_id\",\n\tgetChildViews:function(){\n\t\treturn [this._body_cell];\n\t},\n\tbody_setter:function(value){\n\t\tif (typeof value != \"object\")\n\t\t\tvalue = {template:value };\n\n\t\tvalue._inner = { top:true, left:true, right:true, bottom:true};\n\t\tstate._parent_cell = this;\n\t\tthis._body_cell = ui._view(value);\n\n\t\tthis._bodyobj.appendChild(this._body_cell._viewobj);\n\t\treturn value;\n\t},\n\theader_setter:function(value){\n\t\tif(value)\n\t\t\tvalue = template(value);\n\t\treturn value;\n\t},\n\theaderAlt_setter:function(value){\n\t\tif(value)\n\t\t\tvalue = template(value);\n\t\treturn value;\n\t},\n\t$getSize:function(dx, dy){\n\t\tvar size = this._body_cell.$getSize(0, 0);\n\n\t\t//apply external border to inner content sizes\n\t\tvar _borders = this._settings._inner;\n\t\tif (_borders){\n\t\t\tdx += (_borders.left?0:1)+(_borders.right?0:1);\n\t\t\tdy += (_borders.top?0:1)+(_borders.bottom?0:1);\n\t\t}\n\n\t\tvar header = 0;\n\t\tvar self_size = baseview.api.$getSize.call(this, 0, 0);\n\n\t\t//use child settings if layout's one was not defined\n\t\tself_size[0] = (self_size[0] || size[0] ) +dx;\n\t\tif (self_size[1] >= 100000)\n\t\t\tself_size[1] = size[1];\n\t\tself_size[1] +=\tdx;\n\t\t\n\t\tself_size[2] = (self_size[2] || size[2] ) +dy;\n\t\tvar fixedHeight = (self_size[3]< 100000);\n\t\tif (!fixedHeight)\n\t\t\tself_size[3] = size[3];\n\n\t\tself_size[3] += dy;\n\t\tif(this.getParentView()._vertical_orientation){\n\t\t\tif (this._settings.collapsed){\n\t\t\t\tself_size[2] = self_size[3] = this._getHeaderSize()+dy;\n\t\t\t} else if(this._settings.header)\n\t\t\t\theader = this._settings.headerHeight;\n\t\t} else {\n\t\t\tif (this._settings.collapsed)\n\t\t\t\tself_size[0] = self_size[1] = this._getHeaderSize()+dx;\n\t\t\tif(this._settings.header)\n\t\t\t\theader = this._settings.headerHeight;\n\t\t}\n\n\t\t//include header in total height calculation\n\t\tif(!fixedHeight){\n\t\t\tself_size[2] += header;\n\t\t\tself_size[3] += header;\n\t\t}\n\n\t\tif (DEBUG) debug_size_box(this, self_size, true);\n\t\treturn self_size;\n\t},\n\ton_click:{\n\t\twebix_accordionitem_header:function(e){\n\t\t\tthis._toggle(e);\n\t\t\treturn false;\n\t\t},\n\t\twebix_accordionitem_header_v:function(e){\n\t\t\tthis._toggle(e);\n\t\t\treturn false;\n\t\t}\n\t},\n\t_toggle:function(){\n\t\tthis.define(\"collapsed\", !this._settings.collapsed);\n\t},\n\tcollapsed_setter:function(value){\n\t\tif (this._settings.header === false) return;\n\t\t//use last layout element if parent is not known yet\n\t\tvar parent = this.getParentView();\n\t\tif(parent){\n\t\t\tif(!value)\n\t\t\t\tthis._expand();\n\t\t\telse{\n\t\t\t\tif ( parent._canCollapse(this))\n\t\t\t\t\tthis._collapse();\n\t\t\t\telse{\n\t\t\t\t\tvar success = 0;\n\t\t\t\t\tif(parent._cells.length > 1)\n\t\t\t\t\t\tfor (var i=0; i < parent._cells.length; i++){\n\t\t\t\t\t\t\tvar sibl = parent._cells[i];\n\t\t\t\t\t\t\tif (this != sibl && sibl.isVisible() && sibl.expand){\n\t\t\t\t\t\t\t\tsibl.expand();\n\t\t\t\t\t\t\t\tthis._collapse();\n\t\t\t\t\t\t\t\tsuccess = 1;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\tif (!success) return;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._settings.collapsed = value;\n\t\t\tif (!value) parent._afterOpen(this);\n\n\t\t\tthis.refresh();\n\t\t\tif (!state._ui_creation)\n\t\t\t\tthis.resize();\n\n\t\t\tparent.callEvent(\"onAfter\"+(value?\"Collapse\":\"Expand\"), [this._settings.id]);\n\n\t\t\tthis._settings.$noresize = value;\n\t\t}\n\t\treturn value;\n\t},\n\tcollapse:function(){\n\t\tthis.define(\"collapsed\", true);\n\t\tUIManager._moveChildFocus(this);\n\t},\n\texpand:function(){\n\t\tthis.define(\"collapsed\", false);\n\t},\n\t_show: function() {\n\t\tthis.show();\n\t},\n\t_hide: function() {\n\t\tthis.hide();\n\t},\n\t_expand:function(){\n\t\tthis._bodyobj.style.display = \"\";\n\t\tremoveCss(this.$view, \"collapsed\");\n\t\tremoveCss(this._headobj, \"collapsed\");\n\n\t\tthis._headobj.setAttribute(\"aria-expanded\", \"true\");\n\t\tthis._childRefresh(this._body_cell);\n\t},\n\t_childRefresh: function(view){\n\t\tif(view.refresh)\n\t\t\tview.refresh();\n\t\telse if(view.getChildViews){\n\t\t\tconst views = view.getChildViews();\n\t\t\tviews.forEach(v=>this._childRefresh(v));\n\t\t}\n\t},\n\t_collapse:function(){\n\t\tif(this._settings.headerAlt)\n\t\t\tthis._headlabel.innerHTML = this._settings.headerAlt();\n\t\tthis._bodyobj.style.display = \"none\";\n\t\taddCss(this.$view, \"collapsed\");\n\t\taddCss(this._headobj, \"collapsed\");\n\n\t\tthis._headobj.setAttribute(\"aria-expanded\", \"false\");\n\t},\n\trefresh:function(){\n\t\tvar template = this._settings[this._settings.collapsed?\"headerAlt\":\"header\"] ||this._settings.header;\n\t\tif (template){\n\t\t\tthis._headlabel.innerHTML = template();\n\t\t\tthis._headbutton.setAttribute(\"aria-label\", template());\n\t\t}\n\t\t\t\n\t\tvar css = (this.getParentView()._vertical_orientation?\"vertical\":\"horizontal\");\n\t\tif(this._viewobj.className.indexOf(\" \"+css) < 0 ){\n\t\t\taddCss(this._viewobj, css);\n\t\t}\n\t},\n\t_getHeaderSize:function(){\n\t\treturn (this._settings.collapsed?this._settings.headerAltHeight:this._settings.headerHeight);\n\t},\n\t$setSize:function(x,y){\n\t\tif (base.api.$setSize.call(this,x,y) || this._getHeaderSize() != this._last_set_header_size){\n\t\t\tx = this._content_width;\n\t\t\ty = this._content_height;\n\n\t\t\tvar headerSize = this._last_set_header_size = this._getHeaderSize();//-(this._settings._inner.top?0:1);\n\t\t\tif (this._settings.header){\n\n\t\t\t\tthis._headobj.style.height=headerSize+\"px\";\n\t\t\t\tthis._headobj.style.width=\"auto\";\n\t\t\t\tthis._headobj.style[env.transform]=\"\";\n\n\t\t\t\t\n\t\t\t\tthis._headobj.style.borderBottomWidth = (this._settings.collapsed?0:1)+\"px\";\n\n\t\t\t\tif(this.getParentView()._vertical_orientation||!this._settings.collapsed){\n\t\t\t\t\ty-=this._getHeaderSize();\n\t\t\t\t} else if (this._settings.collapsed){\n\t\t\t\t\t//-2 - borders\n\t\t\t\t\tthis._headobj.style.width = y + \"px\";\n\t\t\t\t\tthis._headobj.style.height = x + 3 + \"px\";\n\t\t\t\t\tvar d = Math.floor(y/2-x/2)+(x-this._settings.headerAltHeight)/2;\n\t\t\t\t\tthis._headobj.style[env.transform]=\"rotate(90deg) translate(\"+d+\"px, \"+(d+1)+\"px)\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(!this._settings.collapsed){\n\t\t\t\tthis._body_cell.$setSize(x,y);\n\t\t\t\tthis._last_size_y = y;\n\t\t\t}\n\t\t} else if (!this._settings.collapsed){\n\t\t\tvar body = this._body_cell;\n\t\t\tif (this._last_size_y)\n\t\t\t\tbody.$setSize(this._content_width, this._last_size_y);\n\t\t}\n\t},\n\t$skin:function(){\n\t\tthis.defaults.headerAltHeight = this.defaults.headerHeight = $active.barHeight - $active.borderWidth*2;\n\t},\n\tdefaults:{\n\t\theader:false,\n\t\theaderAlt:false,\n\t\tbody:\"\"\n\t}\n};\n\n\nconst view = protoUI(api, MouseEvents, EventSystem, base.view);\nexport default {api, view};","import {pos as getPos, offset, addCss, removeCss} from \"../webix/html\";\nimport {ui, protoUI} from \"../ui/core\";\nimport env from \"../webix/env\";\n\nimport MouseEvents from \"../core/mouseevents\";\nimport Destruction from \"../core/destruction\";\n\nimport base from \"./view\";\n\n//used inderectly through ui\nimport \"./resizearea\";\n\nimport {bind} from \"../webix/helpers\";\nimport {_event, event, eventRemove} from \"../webix/htmlevents\";\nimport {assert} from \"../webix/debug\";\nimport {callEvent} from \"../webix/customevents\";\n\n\nconst api = {\n\tname:\"resizer\",\n\tdefaults:{\n\t\twidth:7, height:7\n\t},\n\t$init:function(config){\n\t\tassert(this.getParentView(), \"Resizer can't be initialized outside a layout\");\n\t\tthis._viewobj.className += \" webix_resizer\";\n\t\tvar space = this.getParentView()._margin;\n\t\t\n\t\t_event(this._viewobj, env.mouse.down, e => this._rsDown(e, \"mouse\"));\n\t\tif (env.touch)\n\t\t\t_event(this._viewobj, env.touch.down, e => this._rsDown(e, \"touch\"));\n\n\t\tvar dir = this._getResizeDir();\n\t\tthis._rs_started = false;\n\t\tthis._resizer_dir = dir;\n\n\t\tthis._resizer_dim = (dir==\"x\"?\"width\":\"height\");\n\t\t\n\t\tif (dir==\"x\")\n\t\t\tconfig.height = 0;\n\t\telse \n\t\t\tconfig.width = 0;\n\n\t\tif (space>0){\n\t\t\tthis._viewobj.className += \" webix_resizer_v\"+dir;\n\t\t\tthis._viewobj.style.marginRight = \"-\"+space+\"px\";\n\t\t\tif (dir == \"x\")\t\n\t\t\t\tconfig.width = space;\n\t\t\telse\n\t\t\t\tconfig.height = space;\n\t\t\tthis.$nospace = true;\n\t\t} else\n\t\t\tthis._viewobj.className += \" webix_resizer_\"+dir;\n\t\t\n\t\tthis._viewobj.innerHTML = \"
\";\n\t\tif (dir == \"y\" && space>0) this._viewobj.style.marginBottom = \"-\"+(config.height||this.defaults.height)+\"px\";\n\t\tthis._viewobj.setAttribute(/*@attr*/\"webix_disable_drag\", \"true\");\n\t\tthis._viewobj.setAttribute(\"tabindex\", \"-1\");\n\t\tthis._viewobj.setAttribute(\"aria-grabbed\", \"false\");\n\n\t},\n\t_rsDown:function(e, pointer){\n\t\tvar cells = this._getResizerCells();\n\t\t//some sibling can block resize\n\t\tif(cells && !this._settings.disabled){\n\t\t\tthis._rs_started = true;\n\t\t\tthis._rs_process = getPos(e);\n\t\t\tthis._rsLimit = [];\n\t\t\tthis._viewobj.setAttribute(\"aria-grabbed\", \"true\");\n\t\t\t\n\t\t\tfor(var i=0; i<2; i++)\n\t\t\t\tcells[i].$view.setAttribute(\"aria-dropeffect\", \"move\");\n\t\t\tthis._viewobj.setAttribute(\"aria-dropeffect\", \"move\");\n\t\t\t\n\t\t\tthis._rsStart(e, cells[0]);\n\t\t\tconst handler = event(document, env[pointer].up, e => {\n\t\t\t\teventRemove(handler);\n\t\t\t\treturn this._rsUp(e);\n\t\t\t});\n\t\t}\n\t},\n\t_rsUp:function(){\n\t\tthis._rs_started = false;\n\t\tthis._rs_process = false;\n\t},\n\t_rsStart:function(e, cell){\n\t\tvar dir, cellOffset, pos,posParent,start;\n\t\tdir = this._resizer_dir;\n\n\t\t/*layout position:relative to place absolutely positioned elements in it*/\n\t\tthis.getParentView()._viewobj.style.position = \"relative\";\n\t\tpos = offset(this._viewobj);\n\t\tposParent = offset(this.getParentView()._viewobj);\n\t\tstart = pos[dir]-posParent[dir];\n\t\tcellOffset = offset(cell.$view)[dir]- offset(this.getParentView().$view)[dir];\n\n\t\tthis._rs_progress = [dir, cell, start, cellOffset];\n\t\t/*resizer stick (resizerea ext)*/\n\n\t\tthis._resizeStick = new ui.resizearea({\n\t\t\tcontainer:this.getParentView()._viewobj,\n\t\t\tdir:dir,\n\t\t\teventPos:this._rs_process[dir],\n\t\t\tstart:start-1,\n\t\t\theight: this.$height,\n\t\t\twidth: this.$width,\n\t\t\tborder: 1,\n\t\t\tmargin: this.getParentView()._padding[dir === \"x\"? \"left\" : \"top\"]\n\t\t});\n\n\t\t/*stops resizing on stick mouseup*/\n\t\tthis._resizeStick.attachEvent(\"onResizeEnd\", bind(this._rsEnd, this));\n\t\t/*needed to stop stick moving when the limit for dimension is reached*/\n\t\tthis._resizeStick.attachEvent(\"onResize\", bind(this._rsResizeHandler, this));\n\n\t\taddCss(document.body,\"webix_noselect\",1);\n\t},\n\t_getResizeDir: function(){\n\t\treturn this.getParentView()._vertical_orientation?\"y\":\"x\";\n\t},\n\t_rsResizeHandler:function(){\n\t\tlet cells,cDiff,diff,dir,i,limits,limitSizes,sizes,totalSize;\n\t\tif (this._rs_progress){\n\t\t\tcells = this._getResizerCells();\n\t\t\tdir = this._rs_progress[0];\n\t\t\t/*vector distance between resizer and stick*/\n\t\t\tdiff = this._resizeStick._last_result -this._rs_progress[2];\n\t\t\t/*new sizes for the resized cells, taking into account the stick position*/\n\t\t\tsizes = this._rsGetDiffCellSizes(cells,dir,diff);\n\t\t\t/*sum of cells dimensions*/\n\t\t\ttotalSize = cells[0][\"$\"+this._resizer_dim]+cells[1][\"$\"+this._resizer_dim];\n\t\t\tfor(i=0;i<2;i++){\n\t\t\t\tcDiff = (i?-diff:diff);/*if cDiff is positive, the size of i cell is increased*/\n\n\t\t\t\t/*max and min limits*/\n\t\t\t\tlimits = cells[i].$getSize(0,0);\n\t\t\t\t/*if size is bigger than max limit or size is smaller than min limit*/\n\t\t\t\tlet min = (dir==\"y\")?limits[2]:limits[0];\n\t\t\t\tlet max = (dir==\"y\")?limits[3]:limits[1];\n\n\t\t\t\t//if size is fixed, treat it as responsive (default behavior)\n\t\t\t\tif (min === max){\n\t\t\t\t\tmin = cells[i]._settings[ (dir==\"y\")?\"minHeight\":\"minWidth\" ]||3;\n\t\t\t\t\tmax = cells[i]._settings[ (dir==\"y\")?\"maxHeight\":\"maxWidth\" ]||100000;\n\t\t\t\t}\n\n\t\t\t\tif (cDiff>0&&max&&max<=sizes[i] || cDiff<0&&min&&min>=sizes[i]){\n\t\t\t\t\tthis._rsLimit[i] = (cDiff>0?max:min);\n\t\t\t\t\t/*new sizes, taking into account max and min limits*/\n\t\t\t\t\tlimitSizes = this._rsGetLimitCellSizes(cells,dir);\n\t\t\t\t\t/*stick position*/\n\t\t\t\t\tthis._resizeStick._dragobj.style[(dir==\"y\"?\"top\":\"left\")] = this._rs_progress[3] + limitSizes[0]+\"px\";\n\t\t\t\t\treturn;\n\t\t\t\t} else if(sizes[i]<3) {/*cells size can not be less than 1*/\n\t\t\t\t\tthis._resizeStick._dragobj.style[(dir==\"y\"?\"top\":\"left\")] = this._rs_progress[3] + i*totalSize+1+\"px\";\n\t\t\t\t} else {\n\t\t\t\t\tthis._rsLimit[i] = null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\t_getResizerCells:function(){\n\t\tvar cells,i,res;\n\t\tcells = this.getParentView()._cells;\n\t\tfor(i=0; i< cells.length;i++){\n\t\t\tif(cells[i]==this){\n\t\t\t\tres = [this._getRsCell(cells, i, 1, -1), this._getRsCell(cells, i, 1, 1)];\n\t\t\t\tif (!res[0] || !res[1])\n\t\t\t\t\tres = null;\n\t\t\t\treturn res;\n\t\t\t}\n\t\t}\n\t},\n\t_getRsCell:function(cells, i, step, dir){\n\t\tvar cell = cells[i+(dir*step)];\n\t\tif(cell && cell._settings.hidden)\n\t\t\treturn this._getRsCell(cells, i, step+1, dir);\n\t\telse if(cell && cell._settings.$noresize)\n\t\t\treturn null;\n\t\telse\n\t\t\treturn cell;\n\t},\n\t_rsEnd:function(result){\n\t\tif (typeof result == \"undefined\") return;\n\n\t\tvar cells,dir,diff,size;\n\t\tvar vertical = this.getParentView()._vertical_orientation;\n\t\tthis._resizerStick = null;\n\t\tif (this._rs_progress){\n\t\t\tdir = this._rs_progress[0];\n\t\t\tdiff = result-this._rs_progress[2];\n\t\t\tcells = this._getResizerCells();\n\t\t\tif(cells[0]&&cells[1]){\n\t\t\t\t/*new cell sizes*/\n\t\t\t\tsize = this._rsGetCellSizes(cells,dir,diff);\n\n\t\t\t\tfor (let i=0; i<2; i++){\n\t\t\t\t\t//cell has not fixed size, of fully fixed layout\n\t\t\t\t\tvar cell_size = cells[i].$getSize(0,0);\n\t\t\t\t\tif (vertical?(cell_size[2] == cell_size[3]):(Math.abs(cell_size[1]-cell_size[0])<3)){\n\t\t\t\t\t\t/*set fixed sizes for both cells*/\n\t\t\t\t\t\tcells[i]._settings[this._resizer_dim]=size[i];\n\t\t\t\t\t\tif (cells[i]._bubble_size)\n\t\t\t\t\t\t\tcells[i]._bubble_size(this._resizer_dim, size[i], vertical);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar actualSize = cells[i].$view[vertical?\"offsetHeight\":\"offsetWidth\"];//cells[i][\"$\"+this._resizer_dim];\n\t\t\t\t\t\tcells[i]._settings.gravity = size[i]/actualSize*cells[i]._settings.gravity;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcells[0].resize();\n\n\t\t\t\tfor (let i = 0; i < 2; i++){\n\t\t\t\t\tif (cells[i].callEvent)\n\t\t\t\t\t\tcells[i].callEvent(\"onViewResize\",[]);\n\t\t\t\t\tcells[i].$view.removeAttribute(\"aria-dropeffect\");\n\t\t\t\t}\n\t\t\t\tcallEvent(\"onLayoutResize\", [cells]);\n\t\t\t}\n\t\t\tthis._rs_progress = false;\n\t\t}\n\t\tthis._rs_progress = false;\n\t\tthis._rs_started = false;\n\t\tthis._rsLimit = null;\n\t\tremoveCss(document.body,\"webix_noselect\");\n\n\t\tthis._viewobj.setAttribute(\"aria-grabbed\", \"false\");\n\t\tthis._viewobj.removeAttribute(\"aria-dropeffect\");\n\t},\n\t_rsGetLimitCellSizes: function(cells){\n\t\tvar size1,size2,totalSize;\n\t\ttotalSize = cells[0][\"$\"+this._resizer_dim]+cells[1][\"$\"+this._resizer_dim];\n\t\tif(this._rsLimit[0]){\n\t\t\tsize1 = this._rsLimit[0];\n\t\t\tsize2 = totalSize-size1;\n\t\t}\n\t\telse if(this._rsLimit[1]){\n\t\t\tsize2 = this._rsLimit[1];\n\t\t\tsize1 = totalSize-size2;\n\t\t}\n\t\treturn [size1,size2];\n\t},\n\t_rsGetDiffCellSizes:function(cells,dir,diff){\n\t\tvar sizes =[];\n\t\tvar styleDim = this._resizer_dim==\"height\"?\"offsetHeight\":\"offsetWidth\";\n\t\tfor(var i=0;i<2;i++)\n\t\t\tsizes[i] = cells[i].$view[styleDim]+(i?-1:1)*diff;\n\t\treturn sizes;\n\t},\n\t_rsGetCellSizes:function(cells,dir,diff){\n\t\tvar i,sizes,totalSize;\n\t\t/*if max or min dimentsions are set*/\n\t\tif(this._rsLimit[0]||this._rsLimit[1]){\n\t\t\tsizes = this._rsGetLimitCellSizes(cells,dir);\n\t\t}\n\t\telse{\n\t\t\tsizes = this._rsGetDiffCellSizes(cells,dir,diff);\n\t\t\tfor(i =0; i<2;i++ ){\n\t\t\t\t/*if stick moving is stopped outsize cells borders*/\n\t\t\t\tif(sizes[i]<0){\n\t\t\t\t\ttotalSize = sizes[0]+sizes[1];\n\t\t\t\t\tsizes[i] =1;\n\t\t\t\t\tsizes[1-i] = totalSize-1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t\treturn sizes;\n\t}\n};\n\nconst view = protoUI(api, MouseEvents, Destruction, base.view);\nexport default {api, view};","import {remove} from \"../webix/html\";\nimport {protoUI, $$} from \"../ui/core\";\nimport {clone, extend, isUndefined, isArray} from \"../webix/helpers\";\nimport {_each} from \"../ui/helpers\";\nimport promise from \"../thirdparty/promiz\";\nimport {debug_size_box_start, debug_size_box_end} from \"../webix/debug\";\nimport {assert} from \"../webix/debug\";\n\nimport baselayout from \"../views/baselayout\";\nimport baseview from \"../views/baseview\";\nimport base from \"../views/view\";\n\nimport Settings from \"../core/settings\";\nimport animate from \"../webix/animate\";\n\n\n// #include ui/view.js\n\nconst api = {\n\tname:\"multiview\",\n\tdefaults:{\n\t\tanimate:{\n\t\t}\n\t},\n\tsetValue:function(val){\n\t\t$$(val).show();\n\t},\n\tgetValue:function(){\n\t\treturn this.getActiveId();\n\t},\n\t$init:function(){\n\t\tthis._active_cell = 0;\n\t\tthis._vertical_orientation = 1;\n\t\tthis._viewobj.style.position = \"relative\";\n\t\tthis._viewobj.className += \" webix_multiview\";\n\t\tthis._back_queue = [];\n\t},\n\t_ask_render:function(cell_id, view_id){\n\t\tvar cell = $$(cell_id);\n\t\tif (!cell._render_hash){\n\t\t\tcell._render_queue = [];\n\t\t\tcell._render_hash = {};\t\t\t\n\t\t}\n\t\tif (!cell._render_hash[view_id]){\n\t\t\tcell._render_hash[view_id]=true;\n\t\t\tcell._render_queue.push(view_id);\n\t\t}\n\t},\n\t_render_activation:function(cell_id){ \n\t\tvar cell = $$(cell_id);\n\t\tif(this._settings.keepViews)\n\t\t\tcell._viewobj.style.display = \"\";\n\t\t/*back array*/\n\t\tif(this._back_queue[this._back_queue.length-2]!=cell_id){\n\t\t\tif(this._back_queue.length==10)\n\t\t\t\tthis._back_queue.splice(0,1);\n\t\t\tthis._back_queue.push(cell_id);\n\t\t}\n\t\telse \n\t\t\tthis._back_queue.splice(this._back_queue.length-1,1);\t\n\t\t\n\t\tif (cell._render_hash){\n\t\t\tfor (var i=0; i < cell._render_queue.length; i++){\n\t\t\t\tvar subcell = $$(cell._render_queue[i]);\n\t\t\t\t//cell can be already destroyed\n\t\t\t\tif (subcell)\n\t\t\t\t\tsubcell.render();\n\t\t\t}\n\t\t\t\t\n\t\t\tcell._render_queue = [];\n\t\t\tcell._render_hash = {};\t\t\t\n\t\t}\n\t},\n\taddView:function(view, index){\n\t\tvar inc = !isUndefined(index) && index <= this._active_cell ? 1 : 0;\n\t\tvar id = baselayout.api.addView.apply(this, arguments);\n\n\t\tif(this._cells.length > 1){\n\t\t\tif(this._settings.keepViews)\n\t\t\t\t$$(id)._viewobj.style.display = \"none\";\n\t\t\telse\n\t\t\t\tremove($$(id)._viewobj);\n\n\t\t\tthis._active_cell += inc;\n\t\t}\n\n\t\treturn id;\n\t},\n\t_replace:function(view){\n\t\tif(!isArray(view) && !view._settings.borderless){\n\t\t\tconst settings = clone(this._settings._inner);\n\t\t\tview._settings._inner = settings;\n\t\t\tlet style = view._viewobj.style;\n\t\t\tstyle.borderTopWidth = style.borderBottomWidth = style.borderLeftWidth = style.borderRightWidth = \"1px\";\n\t\t\tthis._fix_container_borders(style, settings);\n\t\t}\n\t\tbaselayout.api._replace.apply(this, arguments);\n\t},\n\t_beforeRemoveView:function(index){\n\t\t//removing current view\n\t\tif (index == this._active_cell){\n\t\t\tvar next = index ? index-1 : 1;\n\t\t\tif (this._cells[next]){\n\t\t\t\tthis._animation_promise = null;\n\t\t\t\tthis._show(this._cells[next], false);\n\t\t\t}\n\t\t}\n\n\t\tif (index < this._active_cell)\n\t\t\tthis._active_cell--;\n\t},\n\t//necessary, as we want to ignore hide calls for elements in multiview\n\t_hide:function(){},\n\t_parse_cells:function(collection){\n\t\tcollection = collection || this._collection; \n\n\t\tfor (let i=0; i < collection.length; i++)\n\t\t\tcollection[i]._inner = this._settings.borderless?{top:1, left:1, right:1, bottom:1}:(this._settings._inner||{});\n\n\t\tbaselayout.api._parse_cells.call(this, collection);\n\n\t\tfor (let i=1; i < this._cells.length; i++){\n\t\t\tif(this._settings.keepViews)\n\t\t\t\tthis._cells[i]._viewobj.style.display = \"none\";\n\t\t\telse\n\t\t\t\tremove(this._cells[i]._viewobj);\n\t\t}\n\n\t\tfor (let i=0; i this._show.apply(this, arguments));\n\n\t\tvar _next_cell = -1;\n\t\tfor (var i=0; i < this._cells.length; i++)\n\t\t\tif (this._cells[i]==obj){\n\t\t\t\t_next_cell = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\tif (_next_cell < 0 || _next_cell == this._active_cell)\n\t\t\treturn;\n\n\n\t\tvar prev = this._cells[this._active_cell];\n\t\tvar next = this._cells[ _next_cell ];\n\t\tprev.$getSize(0,0);\n\n\t\t//need to be moved in animate\n\t\tif((animation_options || isUndefined(animation_options)) && this._settings.animate) {\n\t\t\tvar aniset = extend({}, this._settings.animate);\n\t\t\tif(this._settings.keepViews)\n\t\t\t\taniset.keepViews = true;\n\t\t\taniset.direction = this._getDirection(_next_cell,this._active_cell);\n\t\t\taniset = Settings._mergeSettings(animation_options||{}, aniset);\n\n\t\t\tvar line = animate.formLine(\n\t\t\t\tnext._viewobj,\n\t\t\t\tprev._viewobj,\n\t\t\t\taniset);\n\t\t\tnext.$getSize(0,0);\n\t\t\tnext.$setSize(this._content_width,this._content_height);\n\n\t\t\tvar callback_original = aniset.callback;\n\t\t\taniset.callback = function(){\n\t\t\t\tanimate.breakLine(line,this._settings.keepViews);\n\t\t\t\tthis._animation_promise = null;\n\t\t\t\taniset.wait_animation.resolve();\n\t\t\t\tif (callback_original) callback_original.call(this);\n\t\t\t\tcallback_original = aniset.master = aniset.callback = null;\n\t\t\t\tthis.resize();\n\t\t\t};\n\t\t\taniset.master = this;\n\n\t\t\tthis._active_cell = _next_cell;\n\t\t\tthis._render_activation(this.getActiveId());\n\n\t\t\tanimate(line, aniset);\n\t\t\tthis._animation_promise = aniset.wait_animation = promise.defer();\n\t\t}\n\t\telse { // animate:false in config\n\t\t\tif(this._settings.keepViews){\n\t\t\t\tprev._viewobj.style.display = \"none\";\n\t\t\t}\n\t\t\telse{\n\t\t\t\tremove(prev._viewobj);\n\t\t\t\tthis._viewobj.appendChild(this._cells[i]._viewobj);\n\t\t\t}\n\n\t\t\tthis._active_cell = _next_cell;\n\t\t\tthis.resizeChildren();\n\t\t\tthis._render_activation(this.getActiveId());\n\t\t}\n\n\t\tif (next.callEvent){\n\t\t\tnext.callEvent(\"onViewShow\",[]);\n\t\t\t_each(next, this._signal_hidden_cells);\n\t\t}\n\n\t\tthis.callEvent(\"onViewChange\",[prev._settings.id, next._settings.id]);\n\t\t\n\t},\n\t$getSize:function(dx, dy){\n\t\tif (!this._cells.length) return baseview.api.$getSize.call(this, 0, 0);\n\t\tif (DEBUG) debug_size_box_start(this, true);\n\t\tvar size = this._cells[this._active_cell].$getSize(0, 0);\n\t\tif (this._settings.fitBiggest){\n\t\t\tfor (var i=0; i= 100000) self_size[1]=0;\n\t\tif (self_size[3] >= 100000) self_size[3]=0;\n\n\t\tself_size[0] = (self_size[0] || size[0] ) +dx;\n\t\tself_size[1] = (self_size[1] || size[1] ) +dx;\n\t\tself_size[2] = (self_size[2] || size[2] ) +dy;\n\t\tself_size[3] = (self_size[3] || size[3] ) +dy;\n\t\t\n\t\tif (DEBUG) debug_size_box_end(this, self_size);\n\t\t\n\t\treturn self_size;\n\t},\n\t$setSize:function(x,y){\n\t\tif (!this._cells.length) return;\n\t\tthis._layout_sizes = [x,y];\n\t\tbaseview.api.$setSize.call(this,x,y);\n\t\tthis._cells[this._active_cell].$setSize(x,y);\n\t},\n\tisVisible:function(base_id, cell_id){\n\t\tif (cell_id && cell_id != this.getActiveId()){\n\t\t\tif (base_id)\n\t\t\t\tthis._ask_render(cell_id, base_id);\n\t\t\treturn false;\n\t\t}\n\t\treturn base.api.isVisible.call(this, base_id, this._settings.id);\n\t},\n\tgetActiveId:function(){\n\t\treturn this._cells.length?this._cells[this._active_cell]._settings.id:null;\n\t},\n\tback:function(step){\t\t\n\t\tstep=step||1;\n\t\tif(this.callEvent(\"onBeforeBack\",[this.getActiveId(), step])){\n\t\t\tif(this._back_queue.length>step){\n\t\t\t\tvar viewId = this._back_queue[this._back_queue.length-step-1];\n\t\t\t\t$$(viewId).show();\n\t\t\t\treturn viewId;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\treturn null;\n\n\t},\n\t_insertBeforeView:function(view, before){\n\t\tif (this._settings.keepViews || (!before || before == this._cells[this._active_cell]))\n\t\t\tbaselayout.api._insertBeforeView.call(this, view, before);\n\t}\n};\n\n\nconst view = protoUI(api, baselayout.view);\nexport default {api, view};","import layout from \"../views/layout\";\nimport {protoUI, $$} from \"../ui/core\";\nimport {uid, extend} from \"../webix/helpers\";\nimport {assert} from \"../webix/debug\";\n\n\nconst api = {\n\tname:\"tabview\",\n\tsetValue:function(val, config){\n\t\tthis._cells[0].setValue(val, config);\n\t},\n\tgetValue:function(){\n\t\treturn this._cells[0].getValue();\n\t},\n\tgetTabbar:function(){\n\t\treturn this._cells[0];\n\t},\n\tgetMultiview:function(){\n\t\treturn this._cells[1];\n\t},\n\taddView:function(obj){\n\t\tvar nid = this.getMultiview().addView(obj.body);\n\n\t\tobj.id = nid;\n\t\tobj.value = obj.header;\n\t\tdelete obj.body;\n\t\tdelete obj.header;\n\n\t\tvar t = this.getTabbar();\n\t\tt.addOption(obj);\n\n\t\treturn nid;\n\t},\n\tremoveView:function(id){\n\t\tvar t = this.getTabbar();\n\t\tt.removeOption(id);\n\t\tt.refresh();\n\t},\n\t$init:function(config){\n\t\tthis.$ready.push(this._init_tabview_handlers);\n\n\t\tvar cells = config.cells;\n\t\tvar tabs = [];\n\n\t\tassert(cells && cells.length, \"tabview must have cells collection\");\n\n\t\tfor (var i = cells.length - 1; i >= 0; i--){\n\t\t\tvar view = cells[i].body||cells[i];\n\t\t\tif (!view.id) view.id = \"view\"+uid();\n\t\t\ttabs[i] = { value:cells[i].header, id:view.id, close:cells[i].close, width:cells[i].width, hidden: !!cells[i].hidden};\n\t\t\tcells[i] = view;\n\t\t}\n\n\t\tvar tabbar = { view:\"tabbar\", multiview:true };\n\t\tvar mview = { view:\"multiview\", cells:cells, animate:(!!config.animate) };\n\n\t\tif (config.value)\n\t\t\ttabbar.value = config.value;\n\n\t\tif (config.tabbar)\n\t\t\textend(tabbar, config.tabbar, true);\n\t\tif (config.multiview)\n\t\t\textend(mview, config.multiview, true);\n\t\t\n\t\ttabbar.options = tabbar.options || tabs;\n\n\t\tconfig.rows = [\n\t\t\ttabbar, mview\n\t\t];\n\n\t\tdelete config.cells;\n\t\tdelete config.tabs;\n\t},\n\t_init_tabview_handlers:function(){\n\t\tthis.getTabbar().attachEvent(\"onOptionRemove\", function(id){\n\t\t\tvar view = $$(id);\n\t\t\tif (view){\n\t\t\t\tvar parent = view.getParentView();\n\t\t\t\tif(parent)\n\t\t\t\t\tparent.removeView(view);\n\t\t\t}\n\t\t});\n\t}\n};\n\n\nconst view = protoUI(api, layout.view);\nexport default {api, view};","import base from \"../views/view\";\nimport {protoUI, ui} from \"../ui/core\";\nimport state from \"../core/state\";\n\n\nconst api = {\n\tname:\"proxy\",\n\tbody_setter:function(value){\n\t\tstate._parent_cell = this;\n\t\tthis._body_cell = ui._view(value);\n\t\tthis._viewobj.appendChild(this._body_cell._viewobj);\n\t\treturn value;\n\t},\n\tgetChildViews:function(){\n\t\treturn [this._body_cell];\n\t},\n\t$setSize:function(x,y){\n\t\tbase.api.$setSize.call(this, x,y);\n\t\tthis._body_cell.$setSize(this.$width, this.$height);\n\t},\n\t$getSize:function(dx,dy){\n\t\tvar selfSize = base.api.$getSize.call(this, dx, dy);\n\t\tvar size = this._body_cell.$getSize(dx, dy);\n\n\t\tsize[0] = Math.max(selfSize[0], size[0]);\n\t\tsize[1] = Math.min(selfSize[1], size[1]);\n\t\tsize[2] = Math.max(selfSize[2], size[2]);\n\t\tsize[3] = Math.min(selfSize[3], size[3]);\n\t\tsize[4] = Math.max(selfSize[4], size[4]);\n\n\t\treturn size;\n\t},\n\t_replace:function(n){\n\t\tthis._body_cell.destructor();\n\t\tthis._body_cell = n;\n\t\tthis._viewobj.appendChild(n._viewobj);\n\t\tthis.resize();\n\t}\n};\n\n\nconst view = protoUI(api, base.view);\nexport default {api, view};","import {protoUI} from \"../ui/core\";\nimport env from \"../webix/env\";\n\nimport layout from \"../views/layout\";\nimport toolbar from \"../views/toolbar\";\n\n\nconst api = {\n\tname:\"form\",\n\tdefaults:{\n\t\ttype:\"form\",\n\t\tautoheight:true\n\t},\n\t_default_height:-1,\n\t_form_classname:\"webix_form\",\n\t_form_vertical:true,\n\t$init:function(){\n\t\tthis._viewobj.setAttribute(\"role\", \"form\");\n\t},\n\t$getSize:function(dx, dy){\n\t\tif (this._scroll_y && !this._settings.width) dx += env.scrollSize;\n\n\t\tvar sizes = layout.api.$getSize.call(this, dx, dy);\n\n\t\tif (this._settings.scroll || !this._settings.autoheight){\n\t\t\tsizes[2] = this._settings.height || this._settings.minHeight || 0;\n\t\t\tsizes[3] = this._settings.height || 100000;\n\t\t}\n\t\t\n\t\treturn sizes;\n\t}\n};\n\n\nconst view = protoUI(api, toolbar.view);\nexport default {api, view};","import template from \"../views/template\";\nimport Values from \"../core/values\";\nimport {addCss, removeCss} from \"../webix/html\";\nimport {protoUI} from \"../ui/core\";\nimport {toNode} from \"../webix/helpers\";\n\n\nfunction _tagname(el) {\n\tif (!el.tagName) return null;\n\treturn el.tagName.toLowerCase();\n}\nfunction _attribute(el, name) {\n\tif (!el.getAttribute) return null;\n\tvar attr = el.getAttribute(name);\n\treturn attr ? attr.toLowerCase() : null;\n}\nfunction _get_html_value() {\n\tvar tagname = _tagname(this);\n\tif (_get_value[tagname])\n\t\treturn _get_value[tagname](this);\n\treturn _get_value.other(this);\n}\n\nvar _get_value = {\n\tradio: function(el){\n\t\tfor (var i = 0; i < el.length; i++)\n\t\t\tif (el[i].checked) return el[i].value;\n\t\treturn \"\";\n\t},\n\tinput: function(el) {\n\t\tvar type = _attribute(el, \"type\");\n\t\tif (type === \"checkbox\")\n\t\t\treturn el.checked;\t\t\t\n\t\treturn el.value;\n\t},\n\ttextarea: function(el) {\n\t\treturn el.value;\n\t},\n\tselect: function(el) {\n\t\tvar index = el.selectedIndex;\n\t\treturn el.options[index].value;\n\t},\n\tother: function(el) {\n\t\treturn el.innerHTML;\n\t}\n};\n\nfunction _set_html_value(value) {\n\tvar tagname = _tagname(this);\n\tif (_set_value[tagname])\n\t\treturn _set_value[tagname]( this, value);\n\treturn _set_value.other( this, value);\n}\n\nvar _set_value = {\n\tradio:function(el, value){\n\t\tfor (var i = 0; i < el.length; i++)\n\t\t\tel[i].checked = (el[i].value == value);\n\t},\n\tinput: function(el, value) {\n\t\tvar type = _attribute(el, \"type\");\n\t\tif (type === \"checkbox\")\n\t\t\tel.checked = (value) ? true : false;\n\t\telse\n\t\t\tel.value = value;\n\t},\n\ttextarea: function(el, value) {\n\t\tel.value = value;\n\t},\n\tselect: function(el, value) {\n\t\tel.value = value;\n\t\t//incorrect option applied, select first option\n\t\tif(el.selectedIndex === -1) el.value = el.firstElementChild.value;\n\t},\n\tother: function(el, value) {\n\t\tel.innerHTML = value;\n\t}\n};\n\n\nconst api = {\n\tname:\"htmlform\",\n\t$init: function(config) {\n\t\tthis.elements = {};\n\t\tthis._default_values = false;\n\n\t\tif (config.content && (config.container == config.content || !config.container && config.content == document.body))\n\t\t\tthis._copy_inner_content = true;\n\t},\n\tcontent_setter:function(content){\n\t\tcontent = toNode(content);\n\t\tif (this._copy_inner_content){\n\t\t\twhile (content.childNodes.length > 1)\n\t\t\t\tthis._viewobj.childNodes[0].appendChild(content.childNodes[0]);\n\t\t} else {\n\t\t\tthis._viewobj.childNodes[0].appendChild(content);\n\t\t}\n\t\tthis._parse_inputs();\n\t\treturn true;\n\t},\n\trender:function(){\n\t\ttemplate.api.render.apply(this, arguments);\n\t\tthis._parse_inputs();\n\t},\n\t_parse_inputs: function() {\n\t\tvar inputs = this._viewobj.querySelectorAll(\"[name]\");\n\t\tthis.elements = {};\n\n\n\t\tfor (var i=0; i\";\n\t\t},\n\t\tcolor:function(value){\n\t\t\tconst margin = (this.type.height - 20) / 2;\n\t\t\treturn \"
\" + value;\n\t\t}\n\t},\n\ton_edit:{\n\t\tlabel:false\n\t},\n\t_id:/*@attr*/\"webix_f_id\",\n\ton_click:{\n\t\twebix_property_check:function(ev){\n\t\t\tconst id = this.locate(ev);\n\t\t\tconst item = this.getItem(id);\n\t\t\tthis.callEvent(\"onCheck\", [id, item.value = !item.value]);\n\t\t\treturn false;\n\t\t}\n\t},\n\ton_dblclick:{\n\t},\n\tregisterType:function(name, data){\n\t\tif (!isUndefined(data.template))\n\t\t\tthis.on_render[name] = data.template;\n\t\tif (!isUndefined(data.editor))\n\t\t\tthis.on_edit[name] = data.editor;\n\t\tif (!isUndefined(data.click))\n\t\t\tfor (var key in data.click)\n\t\t\t\tthis.on_click[key] = data.click[key];\n\t},\n\telements_setter:function(data){\n\t\tthis._idToLine = {};\n\t\tfor(var i =0; i < data.length; i++){\n\t\t\tvar line = data[i];\n\t\t\tif (line.type == \"multiselect\")\n\t\t\t\tline.optionslist = true;\n\n\t\t\t//line.type \t= \tline.type||\"label\";\n\t\t\tline.id \t=\tline.id||uid();\n\t\t\tline.label \t=\tline.label||\"\";\n\t\t\tline.value \t=\tisUndefined(line.value) ? (line.type == \"checkbox\" ? false : \"\") : line.value;\n\t\t\tthis._idToLine[line.id] = i;\n\t\t\tthis._map_options(data[i]);\n\t\t}\n\t\treturn data;\n\t},\n\tshowItem:function(id){\n\t\tRenderStack.showItem.call(this, id);\n\t},\n\titem_setter:function(value){\n\t\treturn this.type_setter(value);\n\t},\n\ttype_setter:function(value){\n\t\treturn RenderStack.type_setter.call(this, value);\n\t},\n\tlocate:function(){\n\t\treturn locate(arguments[0], this._id);\n\t},\n\tgetItemNode:function(id){\n\t\treturn this._dataobj.childNodes[this._idToLine[id]];\n\t},\n\tgetItem:function(id){\n\t\treturn this._settings.elements[this._idToLine[id]];\n\t},\n\t_get_editor_type:function(id){\n\t\tvar type = this.getItem(id).type;\n\t\tif (type == \"checkbox\") return \"inline-checkbox\";\n\t\tvar alter_type = this.on_edit[type];\n\t\treturn (alter_type === false)?false:(alter_type||type);\n\t},\n\t_get_edit_config:function(id){\n\t\treturn this.getItem(id);\n\t},\n\t_find_cell_next:function(start, check , direction){\n\t\tlet row = this._idToLine[start.id];\n\t\tlet order = this._settings.elements;\n\t\t\n\t\tif (direction){\n\t\t\tfor (let i=row+1; i=0; i--){\n\t\t\t\tif (check.call(this, order[i].id))\n\t\t\t\t\treturn order[i].id;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t},\n\tupdateItem:function(key, data){\n\t\tconst line = this.getItem(key);\n\t\tif (line)\n\t\t\textend(line, data||{}, true);\n\t\tthis.refresh();\n\t},\n\t_cellPosition:function(id){\n\t\tvar html = this.getItemNode(id);\n\t\treturn {\n\t\t\tleft:html.offsetLeft+this._settings.nameWidth,\n\t\t\ttop:html.offsetTop,\n\t\t\theight:html.firstChild.offsetHeight,\n\t\t\twidth:this._data_width,\n\t\t\tparent:this._contentobj\n\t\t};\n\t},\n\t_clear:function(){\n\t\tvar lines = this._settings.elements;\n\t\tfor (var i=0; i isUndefined(this._idToLine[v]));\n\n\t\tif(!update) this._clear();\n\t\tfor(var key in data){\n\t\t\tvar line = this.getItem(key);\n\t\t\tif (line)\n\t\t\t\tline.value = data[key];\n\t\t}\n\n\t\tthis._props_dataset = data;\n\t\tthis.refresh();\n\t},\n\tgetValues:function(){\n\t\tvar data = clone(this._props_dataset||{});\n\t\tfor (var i = 0; i < this._settings.elements.length; i++) {\n\t\t\tvar line = this._settings.elements[i];\n\t\t\tif (line.type != \"label\")\n\t\t\t\tdata[line.id] = line.value;\n\t\t}\n\n\t\tif (this._settings.complexData)\n\t\t\tdata = CodeParser.expandNames(data);\n\n\t\treturn data;\n\t},\n\trefresh:function(){\n\t\tthis.render();\n\t},\n\t$setSize:function(x,y){\n\t\tif (base.api.$setSize.call(this, x, y)){\n\t\t\tthis._data_width = this._content_width - this._settings.nameWidth;\n\t\t\tthis.render();\n\t\t}\n\t},\n\t$getSize:function(dx,dy){\n\t\tif (this._settings.autoheight){\n\t\t\tvar count = this._settings.elements.length;\n\t\t\tthis._settings.height = Math.max(this.type.height*count, this._settings.minHeight||0);\n\t\t}\n\t\treturn base.api.$getSize.call(this, dx, dy);\n\t},\n\t_toHTML:function(){\n\t\tconst html = [];\n\t\tconst els = this._settings.elements;\n\t\tif (els) {\n\t\t\tconst height = `height:${this.type.height}px;line-height:${this.type.height}px;`;\n\t\t\tfor (let i=0; i\";\n\t\t\t\tif (data.type == \"label\")\n\t\t\t\t\thtml[i] = pre+\"
\"+data.label+\"
\";\n\t\t\t\telse {\n\t\t\t\t\tconst render = this.on_render[data.type];\n\t\t\t\t\tconst post = \"
\"+data.label+\"
\";\n\n\t\t\t\t\tlet content;\n\t\t\t\t\tconst value = data.value;\n\t\t\t\t\tconst options = data.collection || data.options;\n\t\t\t\t\tif(options){\n\t\t\t\t\t\tif (data.format) {\n\t\t\t\t\t\t\tconst item = value ? options.getItem(value) : null;\n\t\t\t\t\t\t\tcontent = data.format(item ? item.value : value);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tcontent = data.template(data, this.type, value, data);\n\t\t\t\t\t} else if(data.format){\n\t\t\t\t\t\tcontent = data.format(value);\n\t\t\t\t\t} else\n\t\t\t\t\t\tcontent = value;\n\t\t\t\t\tif (render)\n\t\t\t\t\t\tcontent = render.call(this, value, data);\n\t\t\t\t\thtml[i] = pre+post+content+\"
\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn html.join(\"\");\n\t},\n\ttype:{\n\t\theight:24,\n\t\ttemplateStart:template(\"\"),\n\t\ttemplateEnd:template(\"\")\n\t},\n\t$skin: function(){\n\t\tthis.type.height = $active.propertyItemHeight;\n\t}\n};\n\n\nconst view = protoUI(api, AutoTooltip, EditAbility, MapCollection, MouseEvents, Scrollable, SingleRender, AtomDataLoader, EventSystem, base.view);\nexport default {api, view};","import {index, triggerEvent, preventEvent} from \"../webix/html\";\nimport {protoUI, $$} from \"../ui/core\";\nimport {$active} from \"../webix/skin\";\nimport {extend, copy, toFunctor, isArray} from \"../webix/helpers\";\nimport {_event} from \"../webix/htmlevents\";\nimport template from \"../webix/template\";\n\nimport i18n from \"../webix/i18n\";\nimport MouseEvents from \"../core/mouseevents\";\nimport EventSystem from \"../core/eventsystem\";\nimport base from \"../views/view\";\nimport DateHelper from \"../core/date\";\nimport KeysNavigation from \"../core/keysnavigation\";\n\n\nconst api = {\n\tname:\"calendar\",\n\n\tdefaults:{\n\t\tdate: DateHelper.datePart(new Date()), //selected date, not selected by default\n\t\tnavigation: true,\n\t\tmonthSelect: true,\n\t\tweekHeader: true,\n\t\tmonthHeader: true,\n\t\tweekNumber: false,\n\t\tskipEmptyWeeks: false,\n\t\tcalendarHeader: \"%F %Y\",\n\t\t//calendarTime: \"%H:%i\",\n\t\tevents:DateHelper.isHoliday,\n\t\tminuteStep: 5,\n\t\ttimeIcon:\"wxi-clock\",\n\t\ticons: false,\n\t\ttimepickerHeight: 30,\n\t\theaderHeight: 30,\n\t\tdayTemplate: function(d){\n\t\t\treturn d.getDate();\n\t\t},\n\t\twidth: 260,\n\t\theight: 250,\n\t\tseparator:\", \"\n\t},\n\n\tdayTemplate_setter: template,\n\tcalendarHeader_setter:DateHelper.dateToStr,\n\tcalendarTime_setter:function(format){\n\t\tthis._calendarTime = format;\n\t\treturn DateHelper.dateToStr(format);\n\t},\n\tdate_setter:function(date){\n\t\tdate = DateHelper.copy( this._string_to_date(date) );\n\t\tdate.setDate(1);\n\t\treturn date;\n\t},\n\tmaxDate_setter:function(date){\n\t\treturn DateHelper.datePart( this._string_to_date(date) );\n\t},\n\tminDate_setter:function(date){\n\t\treturn DateHelper.datePart( this._string_to_date(date) );\n\t},\n\tminTime_setter:function(time){\n\t\tif(typeof(time) == \"string\"){\n\t\t\ttime = i18n.parseTimeFormatDate(time);\n\t\t\ttime = [time.getHours(), time.getMinutes()];\n\t\t}\n\t\treturn time;\n\t},\n\tmaxTime_setter:function(time){\n\t\tif(typeof(time) == \"string\"){\n\t\t\ttime = i18n.parseTimeFormatDate(time);\n\t\t\ttime = [time.getHours(), time.getMinutes()];\n\t\t}\n\t\treturn time;\n\t},\n\t_ariaFocus:function(){\n\t\t_event(this.$view, \"mousedown\", () => {\n\t\t\tthis._mouse_time = new Date();\n\t\t});\n\t\t_event(this.$view, \"focus\", e => {\n\t\t\t// in daterange\n\t\t\tif (this._settings.master) return;\n\n\t\t\tconst prev = e.relatedTarget;\n\t\t\tconst css = e.target.className.indexOf(\"webix_cal_day\") !== -1;\n\t\t\tif (prev && (new Date() - this._mouse_time > 100) && css && this.$view.contains(prev)){\n\t\t\t\tconst day = this._locate_day(e.target);\n\t\t\t\tif (!this._selectedDay(day)) this._moveSelection(day);\n\t\t\t}\n\t\t}, { capture: true });\n\t},\n\t$init: function() {\n\t\tthis._viewobj.className += \" webix_calendar\";\n\t\tthis._viewobj.setAttribute(\"role\", \"region\");\n\t\tthis._viewobj.setAttribute(\"aria-label\", i18n.aria.calendar);\n\n\t\t//special dates\n\t\tthis._special_dates = {};\n\t\tthis._selected_days = {};\n\t\tthis._zoom_level = 0;\n\n\t\t//navigation and aria\n\t\tthis._ariaFocus();\n\t\tthis.attachEvent(\"onKeyPress\", this._onKeyPress);\n\t},\n\t_onKeyPress:function(code, e){\n\t\tconst target = e.target, role = target.getAttribute(\"role\");\n\t\tif((code === 13 || code === 32) && (role == \"button\" || role == \"log\") && !this._settings.disabled){\n\t\t\ttriggerEvent(target, \"MouseEvent\", \"click\");\n\t\t\tpreventEvent(e);\n\t\t}\n\t},\n\tminuteStep_setter(value){\n\t\treturn Math.max( Math.min(value, 60), this.defaults.minuteStep );\n\t},\n\ttype_setter: function(value){\n\t\tif(value == \"time\"){\n\t\t\tthis._zoom_in = true;\n\t\t\tthis._zoom_level = -1;\n\t\t}\n\t\telse if(value == \"year\"){\n\t\t\tthis._fixed = true;\n\t\t}\n\t\treturn value;\n\t},\n\t$setSize:function(x,y){\n\n\t\tif(base.api.$setSize.call(this,x,y)){\n\t\t\t//repaint calendar when size changed\n\t\t\tthis.render();\n\t\t}\n\t},\n\t$getSize:function(dx, dy){\n\t\tconst s = this._settings;\n\t\tif (s.cellHeight && !s.type){\n\t\t\tconst state = this._getDateBoundaries(s.date);\n\t\t\ts.height = s.cellHeight * state._rows + s.headerHeight + (s.weekHeader?$active.calendarWeekHeaderHeight:0) +\n\t\t\t\t(s.timepicker||this._icons?s.timepickerHeight:0) + (this._content_padding+$active.borderWidth)*2;\n\t\t}\n\t\treturn base.api.$getSize.call(this, dx,dy);\n\t},\n\tmoveSelection:function(mode, details, focus){\n\t\tif (this.config.master) return; //in daterange\n\t\tvar start = this.getSelectedDate(true);\n\t\tvar date = DateHelper.copy(start || this.getVisibleDate());\n\t\tthis._moveSelection(date, mode, focus);\n\t},\n\t_moveSelection:function(date, mode, focus){\n\t\tconst css = this._zoom_logic[this._zoom_level]._keyshift(date, mode, this);\n\t\tif (focus !== false)\n\t\t\tthis._restore_focus(css);\n\t},\n\t_restore_focus:function(css, ind){\n\t\tlet sel;\n\t\tif (ind) {\n\t\t\tsel = this._viewobj.querySelector(\".webix_cal_body\");\n\t\t\tsel = sel.childNodes[ind.rind].childNodes[ind.cind + (this._settings.weekNumber?1:0)];\n\t\t} else\n\t\t\tsel = this._viewobj.querySelector(\".\"+css+\"[tabindex='0']\");\n\t\tif (sel) sel.focus();\n\t},\n\t_getDateBoundaries: function(date, reset) {\n\t\t// addition information about rendering event:\n\t\t// how many days from the previous month,\n\t\t// next,\n\t\t// number of weeks to display and so on\n\t\t\n\t\tif (!this._set_date_bounds || reset){\n\t\t\tvar month = date.getMonth();\n\t\t\tvar year = date.getFullYear();\n\n\t\t\tvar next = new Date(year, month+1, 1);\n\t\t\tvar start = DateHelper.weekStart(new Date(year, month, 1));\n\n\t\t\tvar days = Math.round((next.valueOf() - start.valueOf())/(60*1000*60*24));\n\t\t\tvar rows = this._settings.skipEmptyWeeks?Math.ceil(days/7):6;\n\n\t\t\tthis._set_date_bounds = { _month: month, _start:start, _next:next, _rows: rows};\n\t\t}\n\n\t\treturn this._set_date_bounds;\n\t},\n\t$skin:function(){\n\t\tif($active.calendar){\n\t\t\tif( $active.calendar.width)\n\t\t\t\tthis.defaults.width = $active.calendar.width;\n\t\t\tif( $active.calendar.height)\n\t\t\t\tthis.defaults.height = $active.calendar.height;\n\t\t\tif( $active.calendar.headerHeight)\n\t\t\t\tthis.defaults.headerHeight = $active.calendar.headerHeight;\n\t\t\tif( $active.calendar.timepickerHeight)\n\t\t\t\tthis.defaults.timepickerHeight = $active.calendar.timepickerHeight;\n\t\t}\n\t\tthis._content_padding = $active.layoutPadding.form;\n\t},\n\t_getColumnConfigSizes: function(date){ \n\t\tvar bounds = this._getDateBoundaries(date);\n\n\t\tvar s = this._settings;\n\t\tvar _columnsHeight = [];\n\t\tvar _columnsWidth = [];\n\n\t\tvar containerWidth = this._content_width - (this._content_padding+$active.borderWidth)*2;\n\n\t\tvar containerHeight = this._content_height - (s.monthHeader?s.headerHeight:0) - (s.weekHeader?$active.calendarWeekHeaderHeight:0) -\n\t\t\t(s.timepicker||this._icons?s.timepickerHeight:0) - (this._content_padding+$active.borderWidth)*2;\n\n\t\tvar columnsNumber = (s.weekNumber)?8:7;\n\t\tfor(var i=0; i\"+i18n.calendar.today+\"\";\n\t\t\t},\n\t\t\ton_click:{\n\t\t\t\t\"webix_cal_icon_today\": function(){\n\t\t\t\t\tvar date = new Date();\n\t\t\t\t\tif(!this._settings.timepicker)\n\t\t\t\t\t\tdate = DateHelper.datePart(date);\n\t\t\t\t\tthis.setValue(date, \"user\");\n\t\t\t\t\tthis.callEvent(\"onTodaySet\",[this.getSelectedDate()]);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\ttemplate: function(){\n\t\t\t\treturn \"\"+i18n.calendar.clear+\"\";\n\t\t\t},\n\t\t\ton_click:{\n\t\t\t\t\"webix_cal_icon_clear\": function(){\n\t\t\t\t\tthis.setValue(\"\", \"user\");\n\t\t\t\t\tthis.callEvent(\"onDateClear\",[this.getSelectedDate()]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t],\n\trefresh:function(){ this.render(); },\n\trender: function() {\n\t\t//reset zoom level\n\t\tthis._zoom_level = 0;\n\t\tthis._zoom_size = false;\n\n\t\tvar s = this._settings;\n\n\t\tif (!this.isVisible(s.id)) return;\n\t\tthis._current_time = DateHelper.datePart(new Date());\n\n\t\tthis.callEvent(\"onBeforeRender\",[]);\n\n\t\tvar date = this.getVisibleDate();\n\n\t\tvar bounds = this._getDateBoundaries(date, true);\n\t\tvar sizes = this._getColumnConfigSizes(date);\n\t\tvar cpad = this._content_padding + \"px\";\n\t\tvar width = sizes[0];\n\t\tvar height = sizes[1];\n\n\t\tvar html = \"\";\n\t\tif (s.monthHeader){\n\t\t\thtml += \"
\"+s.calendarHeader(date)+\"\";\n\t\t\tif (s.navigation)\n\t\t\t\thtml += \"
\";\n\t\t\thtml += \"
\";\n\t\t}\n\n\t\tif(s.weekHeader)\n\t\t\thtml += \"\";\n\t\thtml += \"
\"+this._body_template(width, height, bounds)+\"
\";\n\n\t\tif (s.timepicker || this._icons){\n\t\t\thtml += \"\";\n\t\t}\n\n\t\tthis._contentobj.innerHTML = html;\n\t\tthis._contentobj.firstChild.style.marginTop = cpad;\n\n\t\tif(s.type == \"time\"){\n\t\t\tthis._changeZoomLevel(-1,date);\n\t\t}\n\t\telse if(s.type == \"month\"){\n\t\t\tthis._changeZoomLevel(1,date);\n\t\t}\n\t\telse if(s.type == \"year\"){\n\t\t\tthis._changeZoomLevel(2,date);\n\t\t}\n\n\t\tthis._fix_cover();\n\t\tthis.callEvent(\"onAfterRender\",[]);\n\t},\n\t_icons_template: function(date){\n\t\tvar html =\t\"
\";\n\t\tvar icons = this._icons;\n\n\t\tfor(var i=0; i < icons.length; i++){\n\t\t\tif(icons[i].template){\n\t\t\t\tvar template = (typeof(icons[i].template) == \"function\"?icons[i].template: template(icons[i].template));\n\t\t\t\thtml += template.call(this,date);\n\t\t\t}\n\t\t\tif(icons[i].on_click){\n\t\t\t\textend(this.on_click,icons[i].on_click);\n\t\t\t}\n\t\t}\n\t\thtml += \"
\";\n\t\treturn html;\n\t},\n\t_timepicker_template:function(date){\n\t\tconst sel = this.getSelectedDate(true);\n\t\tif (sel)\n\t\t\tdate.setFullYear(sel.getFullYear(), sel.getMonth(), sel.getDate());\n\t\tconst timeFormat = this._settings.calendarTime||i18n.timeFormatStr;\n\t\tconst clock = this._settings.timeIcon;\n\t\tlet tpl = \"\";\n\n\t\tif(!this._settings.master)\n\t\t\ttpl = \"
\"+timeFormat(date)+\"
\";\n\t\telse{\n\t\t\t//daterange needs two clocks\n\t\t\tconst range_date = copy($$(this._settings.master)._settings.value);\n\t\t\tif(DateHelper.equal(range_date.end, date))\n\t\t\t\trange_date.start = range_date.end;\n\n\t\t\tfor(let i in range_date){\n\t\t\t\ttpl += \"
\"+timeFormat(range_date[i])+\"
\";\n\t\t\t}\n\t\t}\n\t\treturn tpl;\n\t},\n\t_week_template: function(widths){\n\t\tvar s = this._settings;\n\t\tvar week_template = \"\";\n\t\tvar correction = 0;\n\n\t\tif(s.weekNumber) {\n\t\t\tcorrection = 1;\n\t\t\tweek_template += \"
\"+(s.calendarWeekHeader||\"\")+\"
\";\n\t\t}\n\t\t\n\t\tvar k = (DateHelper.startOnMonday)?1:0;\n\t\tfor (var i=0; i<7; i++){ // 7 days total\n\t\t\tvar day_index = (k + i) % 7; // 0 - Sun, 6 - Sat as in Locale.date.day_short\n\t\t\tvar day = i18n.calendar.dayShort[day_index]; // 01, 02 .. 31\n\t\t\tweek_template += \"
\"+day+\"
\";\n\t\t}\n\t\t\n\t\treturn week_template;\n\t},\n\tblockDates_setter:function(value){\n\t\treturn toFunctor(value, this.$scope);\n\t},\n\t_day_css:function(day, bounds){\n\t\tvar css = \"\", isOutside = false;\n\t\tif (DateHelper.equal(day, this._current_time))\n\t\t\tcss += \" webix_cal_today\";\n\t\tif (!this._checkDate(day))\n\t\t\tcss += \" webix_cal_day_disabled\";\n\t\tif (day.getMonth() != bounds._month){\n\t\t\tisOutside = true;\n\t\t\tcss += \" webix_cal_outside\";\n\t\t}\n\t\tif (!isOutside && this._selectedDay(day))\n\t\t\tcss += \" webix_cal_select\";\n\t\tif (this._settings.events)\n\t\t\tcss+=\" \"+(this._settings.events(day, isOutside) || \"\");\n\t\tcss += \" webix_cal_day\";\n\t\treturn css;\n\t},\n\t_body_template: function(widths, heights, bounds){\n\t\tconst s = this._settings;\n\t\tconst start = s.weekNumber ? 1 : 0;\n\t\tlet day = DateHelper.datePart(DateHelper.copy(bounds._start));\n\t\tlet weekNumber = DateHelper.getISOWeek(DateHelper.add(day, 2, \"day\", true));\n\n\t\tlet html = \"\", focusable, sqSize;\n\t\tfor (let y=0; y\";\n\n\t\t\tif (start){\n\t\t\t\t// recalculate week number for the first week of a year\n\t\t\t\tif(!day.getMonth() && day.getDate()<7)\n\t\t\t\t\tweekNumber = DateHelper.getISOWeek(DateHelper.add(day,2,\"day\", true));\n\t\t\t\thtml += \"\";\n\t\t\t}\n\n\t\t\tfor (let x=start; x\";\n\t\t\t\tday = DateHelper.add(day, 1, \"day\");\n\n\t\t\t\tif (day.getHours())\n\t\t\t\t\tday = DateHelper.datePart(day);\n\t\t\t}\n\n\t\t\thtml += \"\";\n\t\t\tweekNumber++;\n\t\t}\n\t\treturn html.replace(\"$webix_tabindex\", (focusable || s.master) ? \"-1\" : \"0\");\n\t},\n\t_changeDate:function(dir, step){\n\t\tif(!step) { step = this._zoom_logic[this._zoom_level]._changeStep; }\n\n\t\tconst now = this._settings.date;\n\t\tconst next = DateHelper.add(now, dir*step, \"month\", true);\n\t\tthis._changeDateInternal(now, next, dir);\n\t},\n\t_changeDateInternal:function(now, next, dir){\n\t\tif(this.callEvent(\"onBeforeMonthChange\", [now, next])){\n\t\t\tif (this._zoom_level){\n\t\t\t\tthis._update_zoom_level(next);\n\t\t\t} else {\n\t\t\t\tthis.showCalendar(next);\n\t\t\t\tif (this._settings.monthHeader && this._settings.navigation){\n\t\t\t\t\tconst css = \"webix_cal_\"+(dir>0?\"next\":\"prev\")+\"_button\";\n\t\t\t\t\tthis._restore_focus(css);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.callEvent(\"onAfterMonthChange\", [next, now]);\n\t\t}\n\t},\n\t_zoom_logic:{\n\t\t\"-2\":{\n\t\t\t_isBlocked: function(i){\n\t\t\t\tvar config = this._settings,\n\t\t\t\t\tdate = this.getSelectedDate(true) || config.date,\n\t\t\t\t\tisBlocked = false;\n\n\t\t\t\tvar minHour = (config.minTime ? config.minTime[0] : 0);\n\t\t\t\tvar maxHour = (config.maxTime ? (config.maxTime[0] + ( config.maxTime[1] ? 1 : 0 )) : 24);\n\n\t\t\t\tvar minMinute = (config.minTime && (date.getHours()==minHour) ? config.minTime[1] : 0);\n\t\t\t\tvar maxMinute = (config.maxTime && config.maxTime[1] && (date.getHours()==(maxHour-1)) ? config.maxTime[1] : 60);\n\n\t\t\t\tif(this._settings.blockTime){\n\t\t\t\t\tvar d = DateHelper.copy(date);\n\t\t\t\t\td.setMinutes(i);\n\t\t\t\t\tisBlocked = this._settings.blockTime(d);\n\t\t\t\t}\n\t\t\t\treturn (i < minMinute || i >= maxMinute || isBlocked);\n\n\t\t\t},\n\t\t\t_setContent:function(next, i){ next.setMinutes(i); },\n\t\t\t_findActive:function(date, mode, calendar){\n\t\t\t\tif(!this._isBlocked.call(calendar, date.getMinutes()))\n\t\t\t\t\treturn date;\n\t\t\t\telse{\n\t\t\t\t\tvar step = calendar._settings.minuteStep;\n\t\t\t\t\tvar newdate = DateHelper.add(date, mode ==\"right\"?step:-step, \"minute\", true);\n\t\t\t\t\tif(date.getHours() === newdate.getHours())\n\t\t\t\t\t\treturn this._findActive(newdate, mode, calendar);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"-1\":{\n\t\t\t_isBlocked: function(i){\n\t\t\t\tvar config = this._settings,\n\t\t\t\t\tdate = this.getSelectedDate(true) || config.date;\n\n\t\t\t\tvar minHour = (config.minTime? config.minTime[0]:0);\n\t\t\t\tvar maxHour = (config.maxTime? config.maxTime[0]+(config.maxTime[1]?1:0):24);\n\n\t\t\t\tif (i < minHour || i >= maxHour) return true;\n\n\t\t\t\tif(config.blockTime){\n\t\t\t\t\tvar d = DateHelper.copy(date);\n\t\t\t\t\td.setHours(i);\n\t\t\t\t\t\n\t\t\t\t\tvar minMinute = (config.minTime && (i==minHour) ? config.minTime[1] : 0);\n\t\t\t\t\tvar maxMinute = (config.maxTime && config.maxTime[1] && (i==(maxHour-1)) ? config.maxTime[1] : 60);\n\n\t\t\t\t\tfor (var j=minMinute; j= (60-step)) inc = step-60;\n\t\t\t\t\tinc -= date.getMinutes()%step;\n\t\t\t\t\tnewdate = calendar._zoom_logic[\"-2\"]._findActive(DateHelper.add(date, inc, \"minute\"), mode, calendar);\n\t\t\t\t}\n\t\t\t\telse if(mode === \"up\" || mode === \"down\"){ //hours\n\t\t\t\t\tinc = mode===\"down\"?1:-1;\n\t\t\t\t\tif(mode === \"down\" && date.getHours() === 23) inc = -23;\n\t\t\t\t\tif(mode === \"up\" && date.getHours() === 0) inc = 23;\n\t\t\t\t\tnewdate = this._findActive(DateHelper.add(date, inc, \"hour\"), mode, calendar);\n\t\t\t\t}\n\t\t\t\telse if(mode === false)\n\t\t\t\t\tnewdate = this._findActive(date, mode, calendar);\n\n\t\t\t\tif(newdate){\n\t\t\t\t\tcalendar._update_zoom_level(newdate);\n\t\t\t\t\tcalendar.selectDate(newdate, false, false, \"user\");\n\t\t\t\t}\n\n\t\t\t\treturn \"webix_cal_block\"+(mode === \"left\" || mode === \"right\"?\"_min\":\"\");\n\t\t\t},\n\t\t\t_findActive:function(date, mode, calendar){\n\t\t\t\tif(!this._isBlocked.call(calendar, date.getHours()))\n\t\t\t\t\treturn date;\n\t\t\t\telse{\n\t\t\t\t\tvar newdate = DateHelper.add(date, mode ==\"down\"?1:-1, \"hour\", true);\n\t\t\t\t\tif(date.getDate() === newdate.getDate())\n\t\t\t\t\t\treturn this._findActive(newdate, mode, calendar);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"0\":{//days\n\t\t\t_changeStep:1,\n\t\t\t_keyshift:function(date, mode, calendar){\n\t\t\t\tvar newdate = date;\n\t\t\t\tif(mode === \"pgup\" || mode === \"pgdown\")\n\t\t\t\t\tnewdate = DateHelper.add(date, (mode===\"pgdown\"?1:-1), \"month\");\n\t\t\t\telse if(mode === \"bottom\")\n\t\t\t\t\tnewdate = new Date(date.getFullYear(), date.getMonth()+1, 0);\n\t\t\t\telse if(mode === \"top\")\n\t\t\t\t\tnewdate = new Date(date.setDate(1));\n\t\t\t\telse if(mode === \"left\" || mode === \"right\")\n\t\t\t\t\tnewdate = DateHelper.add(date, (mode===\"right\"?1:-1), \"day\");\n\t\t\t\telse if(mode === \"up\" || mode === \"down\")\n\t\t\t\t\tnewdate = DateHelper.add(date, (mode===\"down\"?1:-1), \"week\");\n\t\t\t\t\n\t\t\t\tif(!calendar._checkDate(newdate))\n\t\t\t\t\tnewdate = calendar._findActive(date, mode);\n\t\t\t\t\n\t\t\t\tif(newdate)\n\t\t\t\t\tcalendar._selectDate(newdate, false, \"user\");\n\t\t\t\treturn \"webix_cal_day\";\n\t\t\t},\n\t\t\t\n\t\t},\n\t\t\"1\":{\t//months\n\t\t\t_isBlocked: function(i){\n\t\t\t\tconst date = this.getVisibleDate();\n\t\t\t\tdate.setMonth(i);\n\t\t\t\tlet blocked = this._isDateBlocked(date, 1);\n\n\t\t\t\tvar min = this._settings.minDate,\n\t\t\t\t\tmax = this._settings.maxDate,\n\t\t\t\t\tyear = this._settings.date.getFullYear();\n\n\t\t\t\tif (min && !blocked){\n\t\t\t\t\tvar minYear = min.getFullYear();\n\t\t\t\t\tblocked = yeari);\n\t\t\t\t}\n\n\t\t\t\tif (max && !blocked){\n\t\t\t\t\tvar maxYear = max.getFullYear();\n\t\t\t\t\tblocked = year>maxYear || (year==maxYear && max.getMonth() calendar._settings.maxDate){\n\t\t\t\t\tdate = DateHelper.copy(calendar._settings.maxDate);\n\t\t\t\t}\n\t\t\t\tlet blocked = calendar._isDateBlocked(date);\n\t\t\t\tif(blocked){\n\t\t\t\t\tconst d = DateHelper.copy(date);\n\t\t\t\t\twhile(blocked && d.getMonth() == date.getMonth()){\n\t\t\t\t\t\tblocked = calendar._isDateBlocked(d);\n\t\t\t\t\t\tif(blocked)\n\t\t\t\t\t\t\tDateHelper.add(d, 1, \"day\");\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tdate = d;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn date;\n\t\t\t},\n\t\t\t_getTitle:function(date){ return date.getFullYear(); },\n\t\t\t_getContent:function(i){ return i18n.calendar.monthShort[i]; },\n\t\t\t_setContent:function(next, i){ if(i!=next.getMonth()) next.setDate(1);next.setMonth(i); },\n\t\t\t_changeStep:12,\n\t\t\t_keyshift:function(date, mode, calendar){\n\t\t\t\tvar newdate = date;\n\t\t\t\tif(mode === \"pgup\" || mode === \"pgdown\")\n\t\t\t\t\tnewdate = DateHelper.add(date, (mode===\"pgdown\"?1:-1), \"year\");\n\t\t\t\telse if(mode === \"bottom\")\n\t\t\t\t\tnewdate = new Date(date.setMonth(11));\n\t\t\t\telse if(mode === \"top\")\n\t\t\t\t\tnewdate = new Date(date.setMonth(0));\n\t\t\t\telse if(mode === \"left\" || mode === \"right\")\n\t\t\t\t\tnewdate = DateHelper.add(date, (mode===\"right\"?1:-1), \"month\");\n\t\t\t\telse if(mode === \"up\" || mode === \"down\")\n\t\t\t\t\tnewdate = DateHelper.add(date, (mode===\"down\"?4:-4), \"month\");\n\n\t\t\t\tnewdate = calendar._correctDate(newdate);\n\n\t\t\t\tif(!calendar._checkDate(newdate)){\n\t\t\t\t\tnewdate = calendar._findActive(date, mode);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif(newdate){\n\t\t\t\t\tcalendar._update_zoom_level(newdate);\n\t\t\t\t\tcalendar.selectDate(newdate, false, false, \"user\");\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn \"webix_cal_block\";\n\t\t\t}\n\t\t},\n\t\t\"2\":{\t//years\n\t\t\t_isBlocked: function(i){\n\t\t\t\ti += this._zoom_start_date;\n\n\t\t\t\tconst date = this.getVisibleDate();\n\t\t\t\tdate.setFullYear(i);\n\n\t\t\t\tconst blocked = this._isDateBlocked(date, 2);\n\t\t\t\tvar min = this._settings.minDate;\n\t\t\t\tvar max = this._settings.maxDate;\n\n\t\t\t\tif (blocked || (min && min.getFullYear() > i) || (max && max.getFullYear() < i))\n\t\t\t\t\treturn true;\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\t_correctDate: function(date,calendar){\n\t\t\t\tdate = DateHelper.yearStart(date);\n\t\t\t\tif (date < calendar._settings.minDate){\n\t\t\t\t\tdate = DateHelper.copy(calendar._settings.minDate);\n\t\t\t\t}\n\t\t\t\telse if (date > calendar._settings.maxDate){\n\t\t\t\t\tdate = DateHelper.copy(calendar._settings.maxDate);\n\t\t\t\t}\n\t\t\t\tlet blocked = calendar._isDateBlocked(date);\n\t\t\t\tif(blocked){\n\t\t\t\t\tconst d = DateHelper.copy(date);\n\t\t\t\t\twhile(blocked && d.getFullYear() == date.getFullYear()){\n\t\t\t\t\t\tblocked = calendar._isDateBlocked(d);\n\t\t\t\t\t\tif(blocked)\n\t\t\t\t\t\t\tDateHelper.add(d, 1, \"day\");\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tdate = d;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn date;\n\t\t\t},\n\t\t\t_getTitle:function(date, calendar){\n\t\t\t\tvar start = date.getFullYear();\n\t\t\t\tcalendar._zoom_start_date = start = start - start%10 - 1;\n\t\t\t\treturn start+\" - \"+(start+10 + 1);\n\t\t\t},\n\t\t\t_getContent:function(i, calendar){ return calendar._zoom_start_date+i; },\n\t\t\t_setContent:function(next, i, calendar){ next.setFullYear(calendar._zoom_start_date+i); },\n\t\t\t_changeStep:12*10,\n\t\t\t_keyshift:function(date, mode, calendar){\n\t\t\t\tvar newdate = date;\n\t\t\t\tif(mode === \"pgup\" || mode === \"pgdown\")\n\t\t\t\t\tnewdate = DateHelper.add(date, (mode===\"pgdown\"?10:-10), \"year\");\n\t\t\t\telse if(mode === \"bottom\")\n\t\t\t\t\tnewdate = new Date(date.setYear(calendar._zoom_start_date+10));\n\t\t\t\telse if(mode === \"top\")\n\t\t\t\t\tnewdate = new Date(date.setYear(calendar._zoom_start_date));\n\t\t\t\telse if(mode === \"left\" || mode === \"right\")\n\t\t\t\t\tnewdate = DateHelper.add(date, (mode===\"right\"?1:-1), \"year\");\n\t\t\t\telse if(mode === \"up\" || mode === \"down\")\n\t\t\t\t\tnewdate = DateHelper.add(date, (mode===\"down\"?4:-4), \"year\");\n\n\t\t\t\tnewdate = calendar._correctDate(newdate);\n\n\t\t\t\tif(!calendar._checkDate(newdate))\n\t\t\t\t\tnewdate = calendar._findActive(date, mode);\n\t\t\t\t\n\t\t\t\tif(newdate){\n\t\t\t\t\tcalendar._update_zoom_level(newdate);\n\t\t\t\t\tcalendar.selectDate(newdate, false, false, \"user\");\n\t\t\t\t}\n\n\t\t\t\treturn \"webix_cal_block\";\n\t\t\t}\n\t\t}\n\t},\n\t_correctBlockedTime: function(){\n\t\tvar i, isDisabledHour, isDisabledMinutes;\n\t\tisDisabledHour = this._zoom_logic[-1]._isBlocked.call(this,this._settings.date.getHours());\n\t\tif(isDisabledHour){\n\t\t\tfor (i= 0; i< 24; i++){\n\t\t\t\tif(!this._zoom_logic[-1]._isBlocked.call(this,i)){\n\t\t\t\t\tthis._settings.date.setHours(i);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tisDisabledMinutes = this._zoom_logic[-2]._isBlocked.call(this,this._settings.date.getMinutes());\n\t\tif(isDisabledMinutes){\n\t\t\tfor (i=0; i<60; i+=this._settings.minuteStep){\n\t\t\t\tif(!this._zoom_logic[-2]._isBlocked.call(this,i)){\n\t\t\t\t\tthis._settings.date.setMinutes(i);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\t_update_zoom_level:function(date){\n\t\tvar config, css, height, i, index, sections, selected, type, width, zlogic, temp, sqSize;\n\t\tvar html = \"\";\n\t\tvar cpad = this._content_padding + \"px\";\n\n\t\tconfig = this._settings;\n\t\tindex = 2 - (config.weekHeader?0:1) - (config.monthHeader?0:1);\n\t\tzlogic = this._zoom_logic[this._zoom_level];\n\t\tsections = this._contentobj.childNodes;\n\n\t\tif (date)\n\t\t\tthis.define(\"date\", date);\n\t\ttype = config.type;\n\n\t\t//store width and height of draw area\n\t\tif (!this._zoom_size){\n\n\t\t\tthis._reserve_box_height = this._contentobj.offsetHeight - (config.monthHeader||this._zoom_in?config.headerHeight:0) -\n\t\t\t\t(this._content_padding+$active.borderWidth)*2;\n\t\t\tif(type != \"year\" && type != \"month\")\n\t\t\t\tthis._reserve_box_height -= config.timepickerHeight;\n\n\t\t\tthis._reserve_box_width = sections[index].offsetWidth;\n\t\t\tthis._zoom_size = 1;\n\t\t}\n\n\t\t//main section\n\t\tif (this._zoom_in){\n\t\t\t//hours and minutes\n\t\t\theight = this._reserve_box_height/6;\n\t\t\tvar timeColNum = 6;\n\t\t\tvar timeFormat = this._calendarTime||i18n.timeFormat;\n\t\t\tvar enLocale = timeFormat.match(/%([a,A])/);\n\t\t\tif(enLocale)\n\t\t\t\ttimeColNum++;\n\t\t\twidth = parseInt((this._reserve_box_width-3)/timeColNum,10);\n\t\t\tsqSize = Math.min(width,height);\n\n\t\t\thtml += \"
\"+this._timeHeaderTemplate(width,enLocale)+\"
\";\n\t\t\thtml += \"
\";\n\n\t\t\t// check and change blocked selected time\n\t\t\tthis._correctBlockedTime();\n\n\t\t\thtml += \"
\";\n\t\t\tselected = config.date.getHours();\n\t\t\ttemp = DateHelper.copy(config.date);\n\n\t\t\tfor (i= 0; i< 24; i++){\n\t\t\t\tcss=\"\";\n\t\t\t\tif(enLocale){\n\t\t\t\t\tif(i%4===0){\n\t\t\t\t\t\tvar label = (!i ? i18n.am[0] : (i==12?i18n.pm[0]:\"\"));\n\t\t\t\t\t\thtml += \"
\"+label+\"
\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(this._zoom_logic[-1]._isBlocked.call(this,i)){\n\t\t\t\t\tcss += \" webix_cal_day_disabled\";\n\t\t\t\t}\n\t\t\t\telse if(selected == i)\n\t\t\t\t\tcss += \" webix_selected\";\n\n\t\t\t\t\n\t\t\t\ttemp.setHours(i);\n\n\t\t\t\thtml += \"
\"+DateHelper.toFixed(enLocale?(!i||i==12?12:i%12):i)+\"
\";\n\t\t\t}\n\t\t\thtml += \"
\";\n\n\t\t\thtml += \"
\";\n\t\t\tselected = config.date.getMinutes();\n\t\t\ttemp = DateHelper.copy(config.date);\n\n\n\t\t\tfor (i=0; i<60; i+=config.minuteStep){\n\t\t\t\tcss = \"\";\n\t\t\t\tif(this._zoom_logic[-2]._isBlocked.call(this,i)){\n\t\t\t\t\tcss = \" webix_cal_day_disabled\";\n\t\t\t\t}\n\t\t\t\telse if(selected == i)\n\t\t\t\t\tcss = \" webix_selected\";\n\n\t\t\t\ttemp.setMinutes(i);\n\n\t\t\t\thtml += \"
\"+DateHelper.toFixed(i)+\"
\";\n\t\t\t}\n\t\t\thtml += \"
\";\n\n\t\t\thtml += \"
\";\n\t\t\thtml += \"\";\n\t\t\tthis._contentobj.innerHTML = html;\n\t\t\tthis._contentobj.firstChild.style.marginTop = cpad;\n\t\t} else {\n\t\t\t//years and months\n\n\t\t\t//reset header\n\t\t\tif (config.monthHeader){\n\t\t\t\tconst header = sections[0].childNodes;\n\t\t\t\tconst title = zlogic._getTitle(config.date, this);\n\t\t\t\tif (header[0].innerHTML != title) header[0].innerHTML = title;\n\n\t\t\t\tif (config.navigation){\n\t\t\t\t\tconst labels = i18n.aria[\"nav\"+(this._zoom_level==1?\"Year\":\"Decade\")];\n\t\t\t\t\theader[1].setAttribute(\"aria-label\", labels[0]);\n\t\t\t\t\theader[2].setAttribute(\"aria-label\", labels[1]);\n\t\t\t\t}\n\t\t\t} else\t//needed for \"year\" to set start value\n\t\t\t\tzlogic._getTitle(config.date, this);\n\n\t\t\theight = Math.floor(this._reserve_box_height/3);\n\t\t\twidth = Math.floor(this._reserve_box_width/4);\n\t\t\tsqSize = Math.min(height, width);\n\n\t\t\tselected = (this._zoom_level === 1) ? config.date.getMonth() : config.date.getFullYear() - this._zoom_start_date;\n\t\t\tfor (i=0; i<12; i++){\n\t\t\t\tcss = \"\";\n\t\t\t\tif (zlogic._isBlocked.call(this, i)) {\n\t\t\t\t\tcss = \" webix_cal_day_disabled\";\n\t\t\t\t}\n\t\t\t\telse if(selected == i)\n\t\t\t\t\tcss = \" webix_selected\";\n\n\t\t\t\tvar format = i18n.aria[(this._zoom_level==1?\"month\":\"year\")+\"Format\"];\n\t\t\t\thtml+=\"
\"+zlogic._getContent(i, this)+\"
\";\n\t\t\t}\n\t\t\tif (config.weekHeader){\n\t\t\t\tsections[index-1].style.display = \"none\";\n\t\t\t\tif (index === 1) sections[index].style.marginTop = cpad;\n\t\t\t}\n\t\t\tsections[index].innerHTML = \"
\" + html + \"
\";\n\t\t\tif (type != \"year\" && type != \"month\"){\n\t\t\t\tif(!sections[index+1])\n\t\t\t\t\tthis._contentobj.innerHTML += \"\";\n\t\t\t\telse\n\t\t\t\t\tsections[index+1].innerHTML = this._timeButtonsTemplate();\n\t\t\t} else if (sections[index+1]){\n\t\t\t\tsections[index+1].style.display = \"none\";\n\t\t\t}\n\t\t\tsections[index].style.height = this._reserve_box_height+\"px\";\n\t\t}\n\t},\n\t_getCalSizesString: function(width,height){\n\t\treturn \"width:\"+width+\"px; height:\"+height+\"px; line-height:\"+height+\"px;\";\n\t},\n\t_timeButtonsTemplate: function(){\n\t\treturn \"\";\n\t},\n\t_timeHeaderTemplate: function(width,enLocale){\n\t\tvar w1 = width*(enLocale?5:4);\n\t\tvar w2 = width*2;\n\t\treturn \"
\"+i18n.calendar.hours+\"
\"+i18n.calendar.minutes+\"
\";\n\t},\n\t_changeZoomLevel: function(zoom,date){\n\t\tvar oldzoom = this._zoom_level;\n\t\tif(this.callEvent(\"onBeforeZoom\",[zoom, oldzoom])){\n\t\t\tthis._zoom_level = zoom;\n\n\t\t\tif(zoom)\n\t\t\t\tthis._update_zoom_level(date);\n\t\t\telse\n\t\t\t\tthis.showCalendar(date);\n\t\t\tthis.callEvent(\"onAfterZoom\",[zoom, oldzoom]);\n\t\t}\n\t},\n\t_correctDate:function(date){\n\t\tif(this._zoom_logic[this._zoom_level]._correctDate && !this._checkDate(date))\n\t\t\tdate = this._zoom_logic[this._zoom_level]._correctDate(date,this);\n\t\treturn date;\n\t},\n\t_mode_selected:function(target, config){\n\t\tvar next = this._locate_date(target);\n\t\tvar zoom = this._zoom_level-(this._fixed?0:1);\n\n\t\tnext = this._correctDate(next);\n\t\tif(this._checkDate(next)){\n\t\t\tthis._changeZoomLevel(zoom, next);\n\t\t\tvar type = this._settings.type;\n\t\t\tif(type == \"month\" || type == \"year\")\n\t\t\t\tthis._selectDate(next, false, config);\n\t\t}\n\t},\n\t// selects date and redraw calendar\n\t_selectDate: function(date, add, config){\n\t\tif(this.callEvent(\"onBeforeDateSelect\", [date])){\n\t\t\tthis.selectDate(date, true, add, config);\n\t\t\tthis.callEvent(\"onAfterDateSelect\", [date]);\n\t\t}\n\t},\n\t_locate_day:function(target, ind){\n\t\tconst cind = index(target) - (this._settings.weekNumber?1:0);\n\t\tconst rind = index(target.parentNode);\n\t\tif (ind) return { cind, rind };\n\n\t\tconst date = DateHelper.add(this._getDateBoundaries()._start, cind + rind*7, \"day\", true);\n\t\tif (this._settings.timepicker){\n\t\t\tdate.setHours(this._settings.date.getHours());\n\t\t\tdate.setMinutes(this._settings.date.getMinutes());\n\t\t}\n\t\treturn date;\n\t},\n\t_locate_date:function(target){\n\t\tvar value = target.getAttribute(\"data-value\")*1;\n\t\tvar level = (target.className.indexOf(\"webix_cal_block_min\")!=-1?this._zoom_level-1:this._zoom_level);\n\t\tvar next = this.getVisibleDate();\n\n\t\tthis._zoom_logic[level]._setContent(next, value, this);\n\t\treturn next;\n\t},\n\ton_click:{\n\t\twebix_cal_prev_button: function(){\n\t\t\tthis._changeDate(-1);\n\t\t},\n\t\twebix_cal_next_button: function(){\n\t\t\tthis._changeDate(1);\n\t\t},\n\t\twebix_cal_day_disabled: function(){\n\t\t\treturn false;\n\t\t},\n\t\twebix_cal_outside: function(){\n\t\t\tif(!this._settings.navigation)\n\t\t\t\treturn false;\n\t\t},\n\t\twebix_cal_day: function(e, id, target){\n\t\t\tconst date = this._locate_day(target);\n\t\t\tconst ind = this._settings.multiselect ? this._locate_day(target, true) : null;\n\n\t\t\tconst add = this._settings.multiselect === \"touch\" || (e.ctrlKey || e.metaKey);\n\t\t\tthis._selectDate(date, add, \"user\");\n\n\t\t\tthis._restore_focus(\"webix_cal_day\", ind);\n\t\t},\n\t\twebix_cal_time:function(){\n\t\t\tif(this._zoom_logic[this._zoom_level-1]){\n\t\t\t\tthis._zoom_in = true;\n\t\t\t\tvar zoom = this._zoom_level - 1;\n\t\t\t\tthis._changeZoomLevel(zoom);\n\t\t\t}\n\t\t},\n\t\twebix_range_time_start:function(){\n\t\t\t$$(this._settings.master)._time_mode = \"start\";\n\t\t},\n\t\twebix_range_time_end:function(){\n\t\t\t$$(this._settings.master)._time_mode = \"end\";\n\t\t},\n\t\twebix_cal_done:function(){\n\t\t\tlet date = this.getVisibleDate();\n\t\t\tif (this._zoom_in) {\n\t\t\t\tconst start = this.getSelectedDate(true);\n\t\t\t\tif (start) {\n\t\t\t\t\tstart.setHours(date.getHours());\n\t\t\t\t\tstart.setMinutes(date.getMinutes());\n\t\t\t\t\tdate = start;\n\t\t\t\t}\n\t\t\t}\n\t\t\tdate = this._correctDate(date);\n\t\t\tthis._selectDate(date, false, \"user\");\n\t\t},\n\t\twebix_cal_month_name:function(){\n\t\t\tif (!this._settings.navigation) return;\n\n\t\t\tthis._zoom_in = false;\n\t\t\t//maximum zoom reached\n\t\t\tif (this._zoom_level == 2 || !this._settings.monthSelect) return;\n\n\t\t\tvar zoom = Math.max(this._zoom_level, 0) + 1;\n\t\t\tthis._changeZoomLevel(zoom);\n\t\t},\n\t\twebix_cal_block:function(e, id, trg){\n\t\t\tif (this._zoom_in){\n\t\t\t\tif (trg.className.indexOf(\"webix_cal_day_disabled\") !== -1)\n\t\t\t\t\treturn false;\n\n\t\t\t\tconst next = this._locate_date(trg);\n\t\t\t\tthis._update_zoom_level(next);\n\n\t\t\t\tlet css = \"webix_cal_block\";\n\t\t\t\tif (trg.className.indexOf(\"webix_cal_block_min\") !== -1)\n\t\t\t\t\tcss = \"webix_cal_block_min\";\n\t\t\t\tthis._restore_focus(css);\n\t\t\t} else {\n\t\t\t\tif (trg.className.indexOf(\"webix_cal_day_disabled\") == -1)\n\t\t\t\t\tthis._mode_selected(trg, \"user\");\n\t\t\t}\n\t\t}\n\t},\n\t_string_to_date: function(date, format){\n\t\tif (!date)\n\t\t\treturn DateHelper.datePart(new Date());\n\n\t\tif (typeof date == \"string\"){\n\t\t\tif (format)\n\t\t\t\tdate = DateHelper.strToDate(format)(date);\n\t\t\telse\n\t\t\t\tdate = i18n.parseFormatDate(date);\n\t\t}\n\t\treturn date;\n\t},\n\t_checkDate: function(date){\n\t\tconst blockedDate = this._isDateBlocked(date);\n\t\tconst minDate = this._settings.minDate;\n\t\tconst maxDate = this._settings.maxDate;\n\t\tconst outOfRange = (minDate && date < minDate) || (maxDate && date >= DateHelper.add(maxDate, 1, \"day\", true));\n\t\treturn !blockedDate && !outOfRange;\n\t},\n\t_isDateBlocked: function(date, zoom){\n\t\tconst blockDates = this._settings.blockDates;\n\t\tlet blocked = (blockDates && blockDates.call(this, date));\n\t\tif(blocked && zoom){\n\t\t\tconst d = DateHelper.copy(date);\n\t\t\tconst method = zoom == 1? \"getMonth\" : \"getFullYear\";\n\t\t\td.setDate(1);\n\t\t\twhile(blocked && d[method]() == date[method]()){\n\t\t\t\tblocked = blockDates.call(this, d);\n\t\t\t\tDateHelper.add(d, 1, \"day\");\n\t\t\t}\n\t\t}\n\t\treturn blocked;\n\t},\n\t_findActive:function(date, mode){\n\t\tvar dir = (mode === \"top\" || mode === \"left\" || mode === \"pgup\" || mode === \"up\") ? -1 : 1;\n\t\tvar newdate = DateHelper.add(date, dir, \"day\", true);\n\t\tif (this._checkDate(newdate))\n\t\t\treturn newdate;\n\t\telse {\n\t\t\tvar compare;\n\t\t\tif(this._zoom_level === 0) compare = (date.getMonth() === newdate.getMonth());\n\t\t\telse if(this._zoom_level === 1 ) compare = (date.getFullYear() === newdate.getFullYear());\n\t\t\telse if(this._zoom_level === 2) compare = (newdate.getFullYear() > this._zoom_start_date && newdate.getFullYear() < this._zoom_start_date+10);\n\n\t\t\tif(compare)\n\t\t\t\treturn this._findActive(newdate, mode);\n\t\t}\n\t},\n\tshowCalendar: function(date) {\n\t\tthis.define(\"date\", date);\n\t\tthis.render();\n\t\tthis.resize();\n\t},\n\t_selectedDay: function(day){\n\t\treturn day && this._selected_days[day.valueOf()];\n\t},\n\tgetSelectedDate: function(first) {\n\t\tconst result = [];\n\n\t\tconst keys = Object.keys(this._selected_days);\n\t\tconst length = first ? Math.min(1, keys.length) : keys.length;\n\t\tfor (let i=0; i this._formatValue(date, format));\n\t\t\tif(this._settings.stringResult)\n\t\t\t\tdate = date.join(this._settings.separator);\n\t\t}\n\t\telse\n\t\t\tdate = this._formatValue(date, format);\n\n\t\treturn date;\n\t},\n\t_formatValue: function(date, format){\n\t\tif (format)\n\t\t\tdate = DateHelper.dateToStr(format)(date);\n\t\telse if(this._settings.stringResult){\n\t\t\tif(this._settings.type == \"time\")\n\t\t\t\tdate = i18n.parseTimeFormatStr(date);\n\t\t\telse\n\t\t\t\tdate = i18n.parseFormatStr(date);\n\t\t}\n\t\treturn date;\n\t},\n\tselectDate: function(date, show, add, config){\n\t\tif (!date || !add || !this.config.multiselect)\n\t\t\tthis._selected_days = {};\n\n\t\tif (date){\n\t\t\tif(typeof date == \"string\")\n\t\t\t\tdate = date.split(this._settings.separator);\n\t\t\telse if (!isArray(date)) date = [date];\n\t\t\tfor (let i=0; i {\n\t\t\treturn `
`;\n\t\t},\n\t\tpalette:null,\n\t\theight:250,\n\t\twidth:260,\n\t\tcols:11,\n\t\trows:10,\n\t\tminLightness:0.15,\n\t\tmaxLightness:1,\n\t\tnavigation:true,\n\t\tgrayScale:true,\n\t\ttype:\"material\" // \"classic\"\n\t},\n\t$init:function(){\n\t\t_event(this._viewobj, \"click\", bind(function(e){\n\n\t\t\t// prevent selection the main item container\n\t\t\tconst node = e.target.parentNode;\n\t\t\tlet value = locate(node, /*@attr*/\"webix_val\");\n\t\t\t// locate can return null in case of drag\n\t\t\tif (value){\n\t\t\t\tconst oldvalue = this._settings.value;\n\t\t\t\tthis.setValue(value, \"user\");\n\n\t\t\t\t//value can be changed via setValue\n\t\t\t\tvalue = this._settings.value;\n\n\t\t\t\tthis.callEvent(\"onItemClick\", [value, e]);\n\t\t\t\tif (value != oldvalue)\n\t\t\t\t\tthis.callEvent(\"onSelect\", [value]);\n\t\t\t}\n\t\t}, this));\n\n\t\tthis.$view.setAttribute(\"role\", \"grid\");\n\t\tthis._viewobj.setAttribute(\"aria-readonly\", \"true\");\n\t},\n\t_get_clear_palette:function(){\n\t\treturn [\n\t\t\t\"#F34336\",\n\t\t\t\"#FF9700\",\n\t\t\t\"#FFEA3B\",\n\t\t\t\"#4CB050\",\n\t\t\t\"#009788\",\n\t\t\t\"#00BCD4\",\n\t\t\t\"#2196F3\",\n\t\t\t\"#3F51B5\",\n\t\t\t\"#673BB7\",\n\t\t\t\"#9C28B1\",\n\t\t\t\"#EA1E63\",\n\t\t];\n\t},\n\t_set_item_focus:function(){\n\t\tif(!this.getValue())\n\t\t\tthis.moveSelection(\"up\");\n\t},\n\t_findIndex:function(value){\n\t\tconst pal = this._settings.palette;\n\t\tvalue = (value || \"\").toUpperCase();\n\t\tfor(let r= 0, rows= pal.length; r < rows; r++)\n\t\t\tfor(let c= 0, cols = pal[r].length; c < cols; c++){\n\t\t\t\tif(pal[r][c].toUpperCase() == value){\n\t\t\t\t\treturn {row:r, col:c};\n\t\t\t\t}\n\t\t\t}\n\t\treturn null;\n\t},\n\t$setSize:function(x,y){\n\t\tif(base.api.$setSize.call(this,x,y)){\n\t\t\tthis.render();\n\t\t}\n\t},\n\tgetValue:function(){\n\t\treturn this._settings.value;\n\t},\n\t_getBox:function(){\n\t\treturn this._viewobj.firstChild;\n\t},\n\t$prepareValue:function(value){\n\t\tvalue = value ? value.toString(16) : \"\";\n\t\tif (value && value.charAt(0) != \"#\" && /^[0-9a-fA-F]+$/.test(value))\n\t\t\tvalue = \"#\" + value;\n\t\treturn value;\n\t},\n\tvalue_setter:function(value){\n\t\treturn this.$prepareValue(value);\n\t},\n\tsetValue:function(value, config){\n\t\tvalue = this.$prepareValue(value);\n\t\tconst oldvalue = this._settings.value;\n\n\t\tif (oldvalue != value){\n\t\t\tthis._settings.value = value;\n\t\t\tthis.$setValue(value);\n\t\t\tthis.callEvent(\"onChange\", [value, oldvalue, config]);\n\t\t}\n\t},\n\t$setValue:function(value){\n\t\tif(this.isVisible(this._settings.id)){\n\t\t\t// clear previous\n\t\t\tif (this._activeSelection){\n\t\t\t\tconst oldCell = this._getCell(this._activeSelection);\n\t\t\t\tthis._setSelection(oldCell, false);\n\t\t\t}\n\n\t\t\tconst ind = this._activeSelection = this._findIndex(value);\n\t\t\tif (ind){\n\t\t\t\tconst cell = this._getCell(ind);\n\t\t\t\tthis._setSelection(cell, true);\n\t\t\t}\n\t\t}\n\t},\n\t_getCell(ind){\n\t\treturn this._viewobj.lastChild.childNodes[ind.row].childNodes[ind.col];\n\t},\n\t_setSelection(cell, state){\n\t\tif (state){\n\t\t\tcell.setAttribute(\"tabindex\", \"0\");\n\t\t\tcell.setAttribute(\"aria-selected\", \"true\");\n\t\t\taddCss(cell, \"webix_color_selected\");\n\t\t} else {\n\t\t\tcell.setAttribute(\"tabindex\", \"-1\");\n\t\t\tcell.removeAttribute(\"aria-selected\");\n\t\t\tremoveCss(cell, \"webix_color_selected\");\n\t\t}\n\t},\n\t/* handle colors */\n\t_numToHex:function(n){\n\t\treturn color.toHex(n, 2);\n\t},\n\t_rgbToHex:function(r,g,b){\n\t\treturn \"#\"+this._numToHex( Math.floor(r)) +this._numToHex( Math.floor(g)) + this._numToHex(Math.floor(b));\n\t},\n\t_hslToRgb:function(h, s, l){\n\t\tlet r, g, b;\n\t\tif(!s){\n\t\t\tr = g = b = l; // achromatic\n\t\t}else{\n\t\t\tlet q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n\t\t\tlet p = 2 * l - q;\n\t\t\tr = this._hue2rgb(p, q, h + 1/3);\n\t\t\tg = this._hue2rgb(p, q, h);\n\t\t\tb = this._hue2rgb(p, q, h - 1/3);\n\t\t}\n\n\t\treturn {r:r * 255, g:g * 255, b:b * 255};\n\t},\n\t_hue2rgb:function(p, q, t){\n\t\tif(t < 0) t += 1;\n\t\tif(t > 1) t -= 1;\n\t\tif (t < 1/6)\n\t\t\treturn p + (q - p) * 6 * t; \n\t\telse if (t <= 1/2)\n\t\t\treturn q;\n\t\telse if (t < 2/3) \n\t\t\treturn p + (q - p) * (2/3 - t) * 6;\n\t\telse\n\t\t\treturn p;\n\t},\n\t_lightenRgb:function(rgb, lt){\n\t\t/*\tcolor = color * alpha + background * (1 - alpha); */\n\t\tconst r = rgb[0]*lt + 255*(1-lt);\n\t\tconst g = rgb[1]*lt + 255*(1-lt);\n\t\tconst b = rgb[2]*lt + 255*(1-lt);\n\t\treturn {r, g, b};\n\t},\n\t_getGrayScale:function(colCount){\n\t\tconst gray = [];\n\t\tlet\tval = 255,\n\t\t\tstep = val / colCount;\n\n\t\tfor(let i=0; i < colCount; i++){\n\t\t\tval = Math.round(val > 0 ? val : 0);\n\t\t\tgray.push(this._rgbToHex(val, val, val));\n\t\t\tval -= step;\n\t\t}\n\t\tgray[gray.length - 1] = \"#000000\";\n\t\treturn gray;\n\t},\n\t_initPalette:function(config){\n\t\t/* default palette (material and custom) */\n\t\tconst clearColors = this._get_clear_palette();\t\t\n\t\tconfig.cols = clearColors.length; // always use the same set\n\n\t\tconst colors = [];\n\n\t\tlet colorRows = config.rows - 1; // a row is reserved for clear colors\t\t\n\t\tlet lightStep = 1/config.rows;\n\t\tlet colorRange = null;\n\n\t\tif (this._settings.grayScale){\n\t\t\tconst grayColors = this._getGrayScale(config.cols);\n\t\t\tcolors.push(grayColors.reverse()); // inverted order\n\t\t\tlightStep = 1/colorRows;\n\t\t\tcolorRows -= 1;\n\t\t}\n\n\t\tcolors.push(clearColors);\n\n\t\tfor(let step = 0, lt = config.maxLightness; step < colorRows; step++){\n\t\t\tlt-=lightStep;\n\t\t\tcolorRange = [];\n\t\t\tfor(let col = 0; col < config.cols; col++ ){\n\t\t\t\tconst clearRgb = color.toRgb(clearColors[col]);\n\t\t\t\tconst val = this._lightenRgb(clearRgb, lt);\n\t\t\t\tcolorRange.push(this._rgbToHex(val.r, val.g, val.b));\n\t\t\t}\n\t\t\tcolors.push(colorRange);\n\t\t}\n\t\tthis._settings.palette = colors;\n\t},\n\t_initOldPalette:function(config){\n\t\t/* old (classic) palette */\n\t\tconst colors = [];\n\t\tconst colorStep = 1/config.cols;\n\n\t\tlet colorRows = config.rows;\n\t\tlet colorRange = null;\n\n\t\tif (this._settings.grayScale){\n\t\t\tcolors.push(this._getGrayScale(config.cols));\n\t\t\tcolorRows -= 1;\n\t\t}\n\n\t\tlet lightStep = (config.maxLightness - config.minLightness)/colorRows;\n\n\t\tfor(let step = 0, lt = config.minLightness; step < colorRows; step++){\n\t\t\tcolorRange = [];\n\t\t\tfor(let c = 0, col = 0; c < config.cols; c++ ){\n\t\t\t\tconst val = this._hslToRgb(col, 1, lt );\n\t\t\t\tcolorRange.push(this._rgbToHex(val.r, val.g, val.b));\n\t\t\t\tcol += colorStep;\n\t\t\t}\n\t\t\tcolors.push(colorRange);\n\t\t\tlt+=lightStep;\n\t\t}\n\n\t\tthis._settings.palette = colors;\n\t},\n\tmoveSelection:function(mode, details, focus){\n\t\tlet value = this.getValue(), ind, cell;\n\n\t\tif(value) ind = this._findIndex(value);\n\t\tif(!ind) ind = {row:0, col:0};\n\n\t\tif(ind){\n\t\t\tif(mode == \"up\" || mode == \"down\")\n\t\t\t\tind.row = ind.row + (mode == \"up\"?-1:1);\n\t\t\telse if(mode == \"right\" || mode == \"left\")\n\t\t\t\tind.col = ind.col +(mode == \"right\"?1:-1);\n\t\t\telse if(mode == \"top\" )\n\t\t\t\tind.row = ind.col = 0;\n\t\t\telse if(mode == \"bottom\"){\n\t\t\t\tind.row = this._viewobj.lastChild.querySelectorAll(\".webix_color_row\").length-1;\n\t\t\t\tind.col = this._viewobj.lastChild.childNodes[ind.row].childNodes.length-1;\n\t\t\t}\n\t\t\tind.row = Math.max(ind.row, 0);\n\t\t\tif(ind.row>=0){\n\t\t\t\t// check if this is a last row\n\t\t\t\tconst row = this._viewobj.lastChild.childNodes[ind.row];\n\t\t\t\tif (row) cell = row.childNodes[ind.col];\n\t\t\t}\n\t\t\tif(cell){\n\t\t\t\tvalue = cell.getAttribute(/*@attr*/\"webix_val\");\n\t\t\t\tconst config = (details && details.e instanceof KeyboardEvent) ? \"user\" : \"auto\";\n\t\t\t\tthis.setValue(value, config);\n\t\t\t\tthis.callEvent(\"onSelect\", [this._settings.value]);\n\n\t\t\t\tif(focus !== false){\n\t\t\t\t\tconst sel = this._viewobj.querySelector(\"div[tabindex='0']\");\n\t\t\t\t\tif(sel) sel.focus();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\t_renderRow:function(row, widths, height){\n\t\tconst data = {width: 0, height:0, val:0};\n\t\tlet rowHtml = \"
\";\n\n\t\tfor(let cell = 0; cell < row.length; cell++){\n\t\t\tdata.width = widths[cell];\n\t\t\tdata.height = height;\n\t\t\tdata.val = row[cell];\n\t\t\trowHtml += this._renderItem(data);\n\t\t}\n\t\trowHtml += \"
\";\n\t\treturn rowHtml;\n\t},\n\t_renderItem:function(obj){\n\t\tconst colorTemplate = template(this._settings.template||\"\");\n\t\treturn `
${colorTemplate(obj)}
`;\n\t},\n\trender:function(){\n\t\tif(!this.isVisible(this._settings.id))\n\t\t\treturn;\n\n\t\tconst type = this._settings.type;\n\t\tif(!this._settings.palette){\n\t\t\tif (type === \"classic\")\n\t\t\t\tthis._initOldPalette(this._settings);\n\t\t\telse \n\t\t\t\tthis._initPalette(this._settings);\n\t\t}\n\t\tconst palette = this._settings.palette;\n\n\t\tthis.callEvent(\"onBeforeRender\",[]);\n\t\tconst padding = type === \"classic\" ? 0 : $active.colorPadding;\n\t\tconst single = typeof palette[0] == \"object\";\n\t\tconst firstRow = single ? palette[0] : palette;\n\n\t\tconst deltaWidth = padding*2 + padding*(firstRow.length-1);\n\t\tconst deltaHeight = padding*2 + padding*(single ? palette.length-1 : 0);\n\n\t\tlet width = this.$width - deltaWidth,\n\t\t\theight = this.$height - deltaHeight,\n\t\t\twidths = [];\n\n\t\tlet html = `
`;\n\t\t\n\t\tfor(let i=0; i < firstRow.length; i++){\n\t\t\twidths[i] = Math.floor(width/(firstRow.length - i));\n\t\t\twidth -= widths[i];\n\t\t}\n\n\t\tif(typeof palette[0] == \"object\"){\n\t\t\tfor(let r=0; r < palette.length; r++){\n\t\t\t\tconst cellHeight = Math.floor(height/(palette.length - r));\n\t\t\t\theight -= cellHeight;\n\t\t\t\tconst row = palette[r];\n\t\t\t\thtml += this._renderRow(row, widths, cellHeight);\n\t\t\t}\n\t\t} else\n\t\t\thtml += this._renderRow(palette, widths, height);\n\t\thtml += \"
\";\n\n\t\tthis._viewobj.innerHTML = html;\n\n\t\tif(this._settings.value)\n\t\t\tthis.$setValue(this._settings.value);\n\t\telse\n\t\t\tthis._viewobj.lastChild.childNodes[0].childNodes[0].setAttribute(\"tabindex\", \"0\");\n\n\t\tthis._fix_cover();\n\t\tthis.callEvent(\"onAfterRender\",[]);\n\t},\n\trefresh:function(){ this.render(); }\n};\n\nconst view = protoUI(api, KeysNavigation, base.view, EventSystem);\nexport default {api, view};","import {pos as getPos, addCss, removeCss, offset, preventEvent} from \"../webix/html\";\nimport {protoUI} from \"../ui/core\";\nimport {_event, event, eventRemove} from \"../webix/htmlevents\";\nimport {$active} from \"../webix/skin\";\nimport i18n from \"../webix/i18n\";\nimport env from \"../webix/env\";\n\nimport color from \"../webix/color\";\n\nimport EventSystem from \"../core/eventsystem\";\nimport base from \"../views/view\";\n\nconst api = {\n\tname:\"colorselect\",\n\tdefaults:{\n\t\twidth: 260,\n\t\theight: 250,\n\t\tvalue:\"#751FE0\"\n\t},\n\t$init:function(){\n\t\tthis._hValue = this._sValue = this._vValue = 0;\n\n\t\t_event(this.$view, \"keydown\", (e) => this._handle_move_keyboard(e));\n\t\tthis.attachEvent(\"onAfterRender\", function(){\n\t\t\t_event(this._colorBlock, env.mouse.down, (e) => this._handle_dnd(e, \"mouse\"));\n\t\t\t_event(this._colorLine, env.mouse.down, (e) => this._handle_dnd(e, \"mouse\", true));\n\t\t\tif (env.touch) {\n\t\t\t\t_event(this._colorBlock, env.touch.down, (e) => this._handle_dnd(e, \"touch\"));\n\t\t\t\t_event(this._colorLine, env.touch.down, (e) => this._handle_dnd(e, \"touch\", true));\n\t\t\t}\n\t\t\t_event(this._colorOutText, \"change\", () => this.setValue(this._colorOutText.value, \"user\"));\n\t\t\tif (this._settings.button)\n\t\t\t\t_event(this._viewobj.querySelector(\".webix_button\"), \"click\", () => {\n\t\t\t\t\tthis.callEvent(\"onColorSelect\", [this.getValue()]);\n\t\t\t\t});\n\t\t});\n\t\tthis.attachEvent(\"onDestruct\", function(){\n\t\t\tthis._colorCircle = this._colorLineCircle = this._colorBlock = null;\n\t\t\tthis._colorLine = this._colorOutText = this._colorOutBlock = this._offset = null;\n\t\t});\n\t},\n\t$skin:function(){\n\t\tthis._inpHeight = $active.inputHeight - 2*$active.inputPadding;\n\t},\n\t$setSize:function(x,y){\n\t\tif(base.api.$setSize.call(this,x,y)){\n\t\t\tthis.render();\n\t\t}\n\t},\n\tgetValue:function(){\n\t\treturn this._settings.value;\n\t},\n\t$prepareValue:function(value){\n\t\tvalue = value ? value.toString(16) : \"\";\n\t\tif (value && value.charAt(0) != \"#\" && /^[0-9a-fA-F]+$/.test(value))\n\t\t\tvalue = \"#\" + value;\n\t\treturn value;\n\t},\n\tvalue_setter:function(value){\n\t\treturn this.$prepareValue(value);\n\t},\n\tsetValue:function(value, config){\n\t\tvalue = this.$prepareValue(value);\n\t\tconst oldvalue = this._settings.value;\n\n\t\tif (oldvalue != value){\n\t\t\tthis._settings.value = value;\n\t\t\tthis.$setValue(value);\n\t\t\tthis.callEvent(\"onChange\", [value, oldvalue, config]);\n\t\t}\n\t},\n\t$setValue:function(value){\n\t\tif(this.isVisible(this._settings.id)){\n\t\t\tconst rgb = color.toRgb(value);\n\n\t\t\tif(value !==this._current_value){//set by API\n\t\t\t\tconst hsv = color.rgbToHsv(...rgb);\n\t\t\t\tthis._hValue = hsv[0];\n\t\t\t\tthis._sValue = hsv[1];\n\t\t\t\tthis._vValue = hsv[2];\n\t\t\t}\n\n\t\t\tconst left = (this._hValue*this._offset.width)/359;\n\t\t\tthis._colorLineCircle.style.left = left+\"px\";\n\n\t\t\tconst x = this._sValue*(this._offset.width);\n\t\t\tconst y = Math.abs((this._offset.height)*(this._vValue-1));\n\n\t\t\tthis._colorCircle.style.left = Math.max(Math.min(x, this._offset.width), 0)+\"px\";\n\t\t\tthis._colorCircle.style.top = Math.max(Math.min(y, this._offset.height), 0)+\"px\";\n\n\t\t\tthis._colorCircle.setAttribute(\"aria-valuetext\", value);\n\t\t\tthis._colorLineCircle.setAttribute(\"aria-valuetext\", value);\n\n\t\t\tthis._setOutColors(rgb, value);\n\t\t\tthis._setBlockColors();\n\t\t}\n\t},\n\t_setOutColors:function(rgb, hex){\n\t\tif(!rgb) rgb = color.hsvToRgb(this._hValue, this._sValue, this._vValue);\n\t\tif(!hex) hex = \"#\"+color.rgbToHex(rgb);\n\n\t\tconst bgColor = `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;\n\t\tthis._colorCircle.style.backgroundColor = bgColor;\n\t\tthis._colorOutBlock.style.backgroundColor = bgColor;\n\t\tthis._colorOutText.value = hex.toUpperCase();\n\n\t\tthis._current_value = hex;\n\t},\n\t_setBlockColors:function(){\n\t\tconst rgb = color.hsvToRgb(this._hValue, 1, 1);\n\t\tconst rgbStr = `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;\n\t\tthis._colorLineCircle.style.backgroundColor = rgbStr;\n\t\tthis._colorBlock.style.backgroundColor = rgbStr;\n\t},\n\n\t// dragging to set value\n\t_move_block:function(e){\n\t\tconst pos = getPos(e);\n\n\t\tlet x = pos.x - this._offset.x;\n\t\tlet y = pos.y - this._offset.y;\n\n\t\tx = Math.max(Math.min(x, this._offset.width), 0);\n\t\ty = Math.max(Math.min(y, this._offset.height), 0);\n\n\t\tthis._colorCircle.style.left = x+\"px\";\n\t\tthis._colorCircle.style.top = y+\"px\";\n\n\t\tconst pxX = (this._offset.width)/100;\n\t\tconst pxY = (this._offset.height)/100;\n\n\t\tconst s = Math.ceil(x/pxX)/100;\n\t\tconst v = Math.ceil(Math.abs(y/pxY-100))/100;\n\n\t\tthis._sValue = s;\n\t\tthis._vValue = v;\n\n\t\tthis._setOutColors();\n\t},\n\t_move_line:function(e){\n\t\tconst pos = getPos(e);\n\n\t\tlet x = pos.x - this._offset.x;\n\t\tx = Math.max(Math.min(x, this._offset.width), 0);\n\n\t\tthis._colorLineCircle.style.left = x+\"px\";\n\n\t\tconst h = Math.round(x*359/this._offset.width);\n\t\tthis._hValue = Math.max(Math.min(h, 359), 0);\n\n\t\tthis._setOutColors();\n\t\tthis._setBlockColors();\n\t},\n\t_handle_dnd:function(e, pointer, line){\n\t\tthis._offset = offset(this._colorBlock);\n\n\t\tif (line){\n\t\t\taddCss(this._colorLine, \"webix_color_area_active\");\n\t\t\tthis._move_line(e);\n\t\t} else {\n\t\t\taddCss(this._colorBlock, \"webix_color_area_active\");\n\t\t\tthis._move_block(e);\n\t\t}\n\n\t\tconst passive = (pointer === \"touch\") ? { passive:false } : null;\n\t\tthis._handle_drag_events = [\n\t\t\tevent(document.body, env[pointer].move, e => this._handle_move_process(e, pointer, line), passive),\n\t\t\tevent(document, env[pointer].up, () => this._handle_move_stop(line))\n\t\t];\n\t\taddCss(document.body,\"webix_noselect\");\n\t},\n\t_handle_move_process:function(e, pointer, line){\n\t\tif (line) this._move_line(e);\n\t\telse this._move_block(e);\n\n\t\tif (pointer === \"touch\") preventEvent(e);\n\t},\n\t_handle_move_stop:function(line){\n\t\t//detach event handlers\n\t\teventRemove(this._handle_drag_events[0]);\n\t\teventRemove(this._handle_drag_events[1]);\n\t\tthis._handle_drag_events = null;\n\n\t\tthis.setValue(this._current_value, \"user\");\n\n\t\tif (line){\n\t\t\tremoveCss(this._colorLine, \"webix_color_area_active\");\n\t\t\tthis._colorLineCircle.focus();\n\t\t} else {\n\t\t\tremoveCss(this._colorBlock, \"webix_color_area_active\");\n\t\t\tthis._colorCircle.focus();\n\t\t}\n\t\tremoveCss(document.body, \"webix_noselect\");\n\t},\n\t_move_block_value(val, inc){\n\t\treturn Math.min(Math.max(val+inc/100, 0), 1);\n\t},\n\t_move_line_value(val, inc){\n\t\treturn Math.min(Math.max(val+inc, 0), 359);\n\t},\n\t_handle_move_keyboard:function(e){\n\t\tconst code = e.which || e.keyCode;\n\n\t\tif(code>32 && code <41){\n\t\t\tconst match = /webix_color_(\\w*)circle/.exec(e.target.className);\n\t\t\tif(!match) return;\n\t\t\tpreventEvent(e);\n\n\t\t\tif(match[1].length){ //line\n\t\t\t\tif(code === 36) this._hValue = 0;\n\t\t\t\telse if(code === 35) this._hValue = 359;\n\t\t\t\telse{\n\t\t\t\t\tlet inc = (code === 37 || code === 40 || code === 34) ? -1 : 1;\n\t\t\t\t\tthis._hValue = this._move_line_value(this._hValue, inc);\n\t\t\t\t}\n\t\t\t\tthis._setBlockColors();\n\t\t\t} else {\n\t\t\t\tif(code === 36){\n\t\t\t\t\tthis._sValue = 0;\n\t\t\t\t\tthis._vValue = 1;\n\t\t\t\t}\n\t\t\t\telse if(code === 35) \n\t\t\t\t\tthis._sValue = this._vValue = 1;\n\t\t\t\telse if(code === 39 || code === 37){\n\t\t\t\t\tlet inc = code === 39 ? 1: -1;\n\t\t\t\t\tthis._sValue = this._move_block_value(this._sValue, inc);\n\t\t\t\t}\n\t\t\t\telse{\n\t\t\t\t\tlet inc = (code === 33 || code === 38) ? 1 : -1;\n\t\t\t\t\tthis._vValue = this._move_block_value(this._vValue, inc);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._setOutColors();\n\n\t\t\t//paint value, black colors may have a bigger step\n\t\t\tif(this._settings.value == this._current_value)\n\t\t\t\tthis.$setValue(this._current_value);\n\t\t\telse\n\t\t\t\tthis.setValue(this._current_value, \"user\");\n\t\t}\n\t},\n\tmoveSelection:function(mode){\n\t\tif(mode == \"pgup\" || mode == \"pgdown\"){ //line\n\t\t\tlet inc = mode === \"pgup\" ? -1 : 1;\n\t\t\tthis._hValue = this._move_line_value(this._hValue, inc);\n\t\t\tthis._setBlockColors();\n\t\t}\n\t\telse if(mode !=\"top\" && mode !==\"bottom\"){\n\t\t\tlet inc = (mode == \"up\" || mode == \"right\") ? 1 : -1;\n\t\t\tif(mode == \"down\" || mode == \"up\")\n\t\t\t\tthis._vValue = this._move_block_value(this._vValue, inc);\n\t\t\telse\n\t\t\t\tthis._sValue = this._move_block_value(this._sValue, inc);\n\t\t}\n\t\tthis._setOutColors();\n\t\tthis.setValue(this._current_value, \"auto\");\n\t},\n\trender:function(){\n\t\tif(!this.isVisible(this._settings.id))\n\t\t\treturn;\n\n\t\tthis.callEvent(\"onBeforeRender\",[]);\n\n\t\tconst inpWidth = (this.$width - $active.dataPadding*3)/2;\n\t\t//8+14 color line, 3(or 4) data paddings \n\t\tconst bHeight = this.$height - 3*$active.dataPadding - 22 - this._inpHeight - (this._settings.button ? (this._inpHeight+$active.dataPadding) : 0);\n\n\t\tlet html = \"
\";\n\t\thtml += `\n\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\n\t\t\t
\n\t\t`;\n\n\t\tif(this._settings.button)\n\t\t\thtml += `
`;\n\t\thtml += \"
\";\n\n\t\tthis._viewobj.innerHTML = html;\n\n\t\tthis._collect_vars();\n\t\tthis.$setValue(this._settings.value);\n\n\t\tthis._fix_cover();\n\t\tthis.callEvent(\"onAfterRender\",[]);\n\t},\n\t_collect_vars:function(){\n\t\tthis._colorCircle = this._viewobj.querySelector(\".webix_color_circle\");\n\t\tthis._colorLineCircle = this._viewobj.querySelector(\".webix_color_line_circle\");\n\t\tthis._colorBlock = this._viewobj.querySelector(\".webix_color_block\");\n\t\tthis._colorLine = this._viewobj.querySelector(\".webix_color_line\");\n\t\tthis._colorOutText = this._viewobj.querySelector(\".webix_color_out_text\");\n\t\tthis._colorOutBlock = this._viewobj.querySelector(\".webix_color_out_block\");\n\n\t\tthis._offset = offset(this._colorBlock);\n\t},\n\trefresh:function(){ this.render(); }\n};\n\nconst view = protoUI(api, base.view, EventSystem);\nexport default {api, view};","import {triggerEvent, preventEvent, getTextSize, locate} from \"../webix/html\";\nimport {protoUI, ui} from \"../ui/core\";\nimport {$active} from \"../webix/skin\";\nimport {isUndefined, isArray} from \"../webix/helpers\";\nimport {assert} from \"../webix/debug\";\nimport template from \"../webix/template\";\n\nimport baseview from \"../views/baseview\";\nimport base from \"../views/view\";\n\nimport AutoTooltip from \"../core/autotooltip\";\nimport UIManager from \"../core/uimanager\";\nimport EventSystem from \"../core/eventsystem\";\nimport AtomRender from \"../core/atomrender\";\nimport Settings from \"../core/settings\";\n\n\nconst api = {\n\tname:\"button\",\n\ttouchable:true,\n\t$skin:function(){\n\t\tthis.defaults.height = $active.buttonHeight||$active.inputHeight;\n\t},\n\tdefaults:{\n\t\ttemplate:function(obj, common){\n\t\t\tlet text = common.$renderInput(obj, common);\n\t\t\tif (obj.popup)\n\t\t\t\ttext = text.replace(\"