diff --git a/public/libraries/fancytree/LICENSE.txt b/public/libraries/fancytree/LICENSE.txt
deleted file mode 100644
index 980b1b245..000000000
--- a/public/libraries/fancytree/LICENSE.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-Copyright 2008-2017 Martin Wendt,
-http://wwWendt.de/
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/public/libraries/fancytree/jquery.fancytree-all-deps.min.js b/public/libraries/fancytree/jquery.fancytree-all-deps.min.js
deleted file mode 100644
index babaa834d..000000000
--- a/public/libraries/fancytree/jquery.fancytree-all-deps.min.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*! jQuery Fancytree Plugin - 2.23.0 - 2017-05-27T20:09:38Z
- * https://github.com/mar10/fancytree
- * Copyright (c) 2017 Martin Wendt; Licensed MIT */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
- define( [ "jquery" ], factory );
- } else {
- factory( jQuery );
- }
-}(function( $ ) {
-/*! jQuery UI - v1.12.1 - 2017-02-23
-* http://jqueryui.com
-* Includes: widget.js, position.js, keycode.js, scroll-parent.js, unique-id.js, effect.js, effects/effect-blind.js
-* Copyright jQuery Foundation and other contributors; Licensed MIT */
-
-(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){t.ui=t.ui||{},t.ui.version="1.12.1";var e=0,i=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},l=e.split(".")[0];e=e.split(".")[1];var h=l+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][h.toLowerCase()]=function(e){return!!t.data(e,h)},t[l]=t[l]||{},n=t[l][e],o=t[l][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:l,widgetName:e,widgetFullName:h}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var s,n,o=i.call(arguments,1),a=0,r=o.length;r>a;a++)for(s in o[a])n=o[a][s],o[a].hasOwnProperty(s)&&void 0!==n&&(e[s]=t.isPlainObject(n)?t.isPlainObject(e[s])?t.widget.extend({},e[s],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,s){var n=s.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=i.call(arguments,1),l=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(l=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(l=i&&i.jquery?l.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):l=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new s(o,this))})),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",{"class":"ui-fancytree fancytree-container fancytree-plain"}).appendTo(this.$div),this.$container=c,this.rootNode.ul=c[0],null==this.options.debugLevel&&(this.options.debugLevel=w.debugLevel)}if(a.ui&&a.ui.fancytree)return void a.ui.fancytree.warn("Fancytree: ignored duplicate include");var u,v,w=null,x=new RegExp(/\.|\//),y=/[&<>"'\/]/g,z=/[<>"'\/]/g,A="$recursive_request",B={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},C={16:!0,17:!0,18:!0},D={8:"backspace",9:"tab",10:"return",13:"return",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",59:";",61:"=",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scroll",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},E={0:"",1:"left",2:"middle",3:"right"},F="active expanded focus folder lazy radiogroup selected unselectable unselectableIgnore".split(" "),G={},H="checkbox expanded extraClasses folder icon key lazy radiogroup refKey selected statusNodeType title tooltip unselectable unselectableIgnore unselectableStatus".split(" "),I={},J={},K={active:!0,children:!0,data:!0,focus:!0};for(u=0;u=0,"insertBefore must be an existing child"),this.children.splice.apply(this.children,[g,0].concat(k))),h&&!c){for(d=0,f=k.length;d=0;d--)e=this.children[d],"paging"===e.statusNodeType&&this.removeChild(e);return void(this.partload=!1)}return b=a.extend({title:this.tree.options.strings.moreData,statusNodeType:"paging",icon:!1},b),this.partload=!0,this.addNode(b,c)},appendSibling:function(a){return this.addNode(a,"after")},applyPatch:function(b){if(null===b)return this.remove(),k(this);var c,d,e,f={children:!0,expanded:!0,parent:!0};for(c in b)e=b[c],f[c]||a.isFunction(e)||(I[c]?this[c]=e:this.data[c]=e);return b.hasOwnProperty("children")&&(this.removeChildren(),b.children&&this._setChildren(b.children)),this.isVisible()&&(this.renderTitle(),this.renderStatus()),d=b.hasOwnProperty("expanded")?this.setExpanded(b.expanded):k(this)},collapseSiblings:function(){return this.tree._callHook("nodeCollapseSiblings",this)},copyTo:function(a,b,c){return a.addNode(this.toDict(!0,c),b)},countChildren:function(a){var b,c,d,e=this.children;if(!e)return 0;if(d=e.length,a!==!1)for(b=0,c=d;b=2&&(Array.prototype.unshift.call(arguments,this.toString()),f("log",arguments))},discard:function(){return this.warn("FancytreeNode.discard() is deprecated since 2014-02-16. Use .resetLazy() instead."),this.resetLazy()},discardMarkup:function(a){var b=a?"nodeRemoveMarkup":"nodeRemoveChildMarkup";this.tree._callHook(b,this)},findAll:function(b){b=a.isFunction(b)?b:q(b);var c=[];return this.visit(function(a){b(a)&&c.push(a)}),c},findFirst:function(b){b=a.isFunction(b)?b:q(b);var c=null;return this.visit(function(a){if(b(a))return c=a,!1}),c},_changeSelectStatusAttrs:function(a){var b=!1,c=this.tree.options,f=w.evalOption("unselectable",this,this,c,!1),g=w.evalOption("unselectableStatus",this,this,c,d);switch(f&&null!=g&&(a=g),a){case!1:b=this.selected||this.partsel,this.selected=!1,this.partsel=!1;break;case!0:b=!this.selected||!this.partsel,this.selected=!0,this.partsel=!0;break;case d:b=this.selected||!this.partsel,this.selected=!1,this.partsel=!0;break;default:e(!1,"invalid state: "+a)}return b&&this.renderStatus(),b},fixSelection3AfterClick:function(a){var b=this.isSelected();this.visit(function(a){a._changeSelectStatusAttrs(b)}),this.fixSelection3FromEndNodes(a)},fixSelection3FromEndNodes:function(a){function b(a){var e,f,g,h,i,j,k,l,m,n=a.children;if(n&&n.length){for(j=!0,k=!1,e=0,f=n.length;e=1&&(Array.prototype.unshift.call(arguments,this.toString()),f("info",arguments))},isActive:function(){return this.tree.activeNode===this},isChildOf:function(a){return this.parent&&this.parent===a},isDescendantOf:function(a){if(!a||a.tree!==this.tree)return!1;for(var b=this.parent;b;){if(b===a)return!0;b=b.parent}return!1},isExpanded:function(){return!!this.expanded},isFirstSibling:function(){var a=this.parent;return!a||a.children[0]===this},isFolder:function(){return!!this.folder},isLastSibling:function(){var a=this.parent;return!a||a.children[a.children.length-1]===this},isLazy:function(){return!!this.lazy},isLoaded:function(){return!this.lazy||this.hasChildren()!==d},isLoading:function(){return!!this._isLoading},isRoot:function(){return this.isRootNode()},isPartsel:function(){return!this.selected&&!!this.partsel},isPartload:function(){return!!this.partload},isRootNode:function(){return this.tree.rootNode===this},isSelected:function(){return!!this.selected},isStatusNode:function(){return!!this.statusNodeType},isPagingNode:function(){return"paging"===this.statusNodeType},isTopLevel:function(){return this.tree.rootNode===this.parent},isUndefined:function(){return this.hasChildren()===d},isVisible:function(){var a,b,c=this.getParentList(!1,!1);for(a=0,b=c.length;a=0;c--)e.push(g[c].setExpanded(!0,b));return a.when.apply(a,e).done(function(){j?d.scrollIntoView(i).done(function(){f.resolve()}):f.resolve()}),f.promise()},moveTo:function(b,c,f){c===d||"over"===c?c="child":"firstChild"===c&&(b.children&&b.children.length?(c="before",b=b.children[0]):c="child");var g,h=this.parent,i="child"===c?b:b.parent;if(this!==b){if(this.parent?i.isDescendantOf(this)&&a.error("Cannot move a node to its own descendant"):a.error("Cannot move system root"),i!==h&&h.triggerModifyChild("remove",this),1===this.parent.children.length){if(this.parent===i)return;this.parent.children=this.parent.lazy?[]:null,this.parent.expanded=!1}else g=a.inArray(this,this.parent.children),e(g>=0,"invalid source parent"),this.parent.children.splice(g,1);if(this.parent=i,i.hasChildren())switch(c){case"child":i.children.push(this);break;case"before":g=a.inArray(b,i.children),e(g>=0,"invalid target parent"),i.children.splice(g,0,this);break;case"after":g=a.inArray(b,i.children),e(g>=0,"invalid target parent"),i.children.splice(g+1,0,this);break;default:a.error("Invalid mode "+c)}else i.children=[this];f&&b.visit(f,!0),i===h?i.triggerModifyChild("move",this):i.triggerModifyChild("add",this),this.tree!==b.tree&&(this.warn("Cross-tree moveTo is experimantal!"),this.visit(function(a){a.tree=b.tree},!0)),h.isDescendantOf(i)||h.render(),i.isDescendantOf(h)||i===h||i.render()}},navigate:function(b,c){function d(d){if(d){try{d.makeVisible({scrollIntoView:!1})}catch(e){}return a(d.span).is(":visible")?c===!1?d.setFocus():d.setActive():(d.debug("Navigate: skipping hidden node"),void d.navigate(b,c))}}var e,f,g,h=!0,i=a.ui.keyCode,j=null;switch(b){case i.BACKSPACE:this.parent&&this.parent.parent&&(g=d(this.parent));break;case i.HOME:this.tree.visit(function(b){if(a(b.span).is(":visible"))return g=d(b),!1});break;case i.END:this.tree.visit(function(b){a(b.span).is(":visible")&&(g=b)}),g&&(g=d(g));break;case i.LEFT:this.expanded?(this.setExpanded(!1),g=d(this)):this.parent&&this.parent.parent&&(g=d(this.parent));break;case i.RIGHT:this.expanded||!this.children&&!this.lazy?this.children&&this.children.length&&(g=d(this.children[0])):(this.setExpanded(),g=d(this));break;case i.UP:for(j=this.getPrevSibling();j&&!a(j.span).is(":visible");)j=j.getPrevSibling();for(;j&&j.expanded&&j.children&&j.children.length;)j=j.children[j.children.length-1];!j&&this.parent&&this.parent.parent&&(j=this.parent),g=d(j);break;case i.DOWN:if(this.expanded&&this.children&&this.children.length)j=this.children[0];else for(f=this.getParentList(!1,!0),e=f.length-1;e>=0;e--){for(j=f[e].getNextSibling();j&&!a(j.span).is(":visible");)j=j.getNextSibling();if(j)break}g=d(j);break;default:h=!1}return g||k()},remove:function(){return this.parent.removeChild(this)},removeChild:function(a){return this.tree._callHook("nodeRemoveChild",this,a)},removeChildren:function(){return this.tree._callHook("nodeRemoveChildren",this)},removeClass:function(a){return this.toggleClass(a,!1)},render:function(a,b){return this.tree._callHook("nodeRender",this,a,b)},renderTitle:function(){return this.tree._callHook("nodeRenderTitle",this)},renderStatus:function(){return this.tree._callHook("nodeRenderStatus",this)},replaceWith:function(b){var c,d=this.parent,f=a.inArray(this,d.children),g=this;return e(this.isPagingNode(),"replaceWith() currently requires a paging status node"),c=this.tree._callHook("nodeLoadChildren",this,b),c.done(function(a){var b=g.children;for(u=0;uv+u-t&&(z=j+q-u+t,y&&(e(y.isRootNode()||a(y.span).is(":visible"),"topNode must be visible"),id?1:-1},e.sort(a),b)for(c=0,d=e.length;c=0,c=c===d?!f:!!c)f||(l+=e+" ",j=!0);else for(;l.indexOf(" "+e+" ")>-1;)l=l.replace(" "+e+" "," ");return this.extraClasses=a.trim(l),j},toggleExpanded:function(){return this.tree._callHook("nodeToggleExpanded",this)},toggleSelected:function(){return this.tree._callHook("nodeToggleSelected",this)},toString:function(){return""},triggerModifyChild:function(b,c,d){var e,f=this.tree.options.modifyChild;f&&(c&&c.parent!==this&&a.error("childNode "+c+" is not a child of "+this),e={node:this,tree:this.tree,operation:b,childNode:c||null},d&&a.extend(e,d),f({type:"modifyChild"},e))},triggerModify:function(a,b){this.parent.triggerModifyChild(a,this,b)},visit:function(a,b){var c,d,e=!0,f=this.children;if(b===!0&&(e=a(this),e===!1||"skip"===e))return e;if(f)for(c=0,d=f.length;c=2&&(Array.prototype.unshift.call(arguments,this.toString()),f("log",arguments))},enableUpdate:function(a){return a=a!==!1,!!this._enableUpdate==!!a?a:(this._enableUpdate=a,a?(this.debug("enableUpdate(true): redraw "),this.render()):this.debug("enableUpdate(false)..."),!a)},findAll:function(a){return this.rootNode.findAll(a)},findFirst:function(a){return this.rootNode.findFirst(a)},findNextNode:function(b,c,d){var e=null,f=c.parent.children,g=null,h=function(a,b,c){var d,e,f=a.children,g=f.length,i=f[b];if(i&&c(i)===!1)return!1;if(i&&i.children&&i.expanded&&h(i,0,c)===!1)return!1;for(d=b+1;d",{type:"checkbox",name:g,value:b.key,checked:!0}))}d=d||{};var f,g="string"==typeof b?b:"ft_"+this._id+"[]",h="string"==typeof c?c:"ft_"+this._id+"_active",i="fancytree_result_"+this._id,j=a("#"+i),k=3===this.options.selectMode&&d.stopOnParents!==!1;j.length?j.empty():j=a("
",{id:i}).hide().insertAfter(this.$container),c!==!1&&this.activeNode&&j.append(a("",{type:"radio",name:h,value:this.activeNode.key,checked:!0})),d.filter?this.visit(function(a){var b=d.filter(a);return"skip"===b?b:void(b!==!1&&e(a))}):b!==!1&&(f=this.getSelectedNodes(k),a.each(f,function(a,b){e(b)}))},getActiveNode:function(){return this.activeNode},getFirstChild:function(){return this.rootNode.getFirstChild()},getFocusNode:function(){return this.focusNode},getNodeByKey:function(a,b){var d,e;return!b&&(d=c.getElementById(this.options.idPrefix+a))?d.ftnode?d.ftnode:null:(b=b||this.rootNode,e=null,b.visit(function(b){if(b.key===a)return e=b,!1},!0),e)},getRootNode:function(){return this.rootNode},getSelectedNodes:function(a){return this.rootNode.getSelectedNodes(a)},hasFocus:function(){return!!this._hasFocus},info:function(a){this.options.debugLevel>=1&&(Array.prototype.unshift.call(arguments,this.toString()),f("info",arguments))},loadKeyPath:function(b,c,e){function f(a,b,d){c.call(r,b,"loading"),b.load().done(function(){r.loadKeyPath.call(r,l[a],c,b).always(m(d,r))}).fail(function(e){r.warn("loadKeyPath: error loading: "+a+" (parent: "+o+")"),c.call(r,b,"error"),d.reject()})}var g,h,i,j,k,l,n,o,p,q=this.options.keyPathSeparator,r=this;for(c=c||a.noop,a.isArray(b)||(b=[b]),l={},i=0;i"},_triggerNodeEvent:function(a,b,c,e){var f=this._makeHookContext(b,c,e),g=this.widget._trigger(a,c,f);return g!==!1&&f.result!==d?f.result:g},_triggerTreeEvent:function(a,b,c){var e=this._makeHookContext(this,b,c),f=this.widget._trigger(a,b,e);return f!==!1&&e.result!==d?e.result:f},visit:function(a){return this.rootNode.visit(a,!1)},warn:function(a){Array.prototype.unshift.call(arguments,this.toString()),f("warn",arguments)}},a.extend(t.prototype,{nodeClick:function(a){var b,c,d=a.targetType,e=a.node;if("expander"===d){if(e.isLoading())return void e.debug("Got 2nd click while loading: ignored");this._callHook("nodeToggleExpanded",a)}else if("checkbox"===d)this._callHook("nodeToggleSelected",a),a.options.focusOnSelect&&this._callHook("nodeSetFocus",a,!0);else{if(c=!1,b=!0,e.folder)switch(a.options.clickFolderMode){case 2:c=!0,b=!1;break;case 3:b=!0,c=!0}b&&(this.nodeSetFocus(a),this._callHook("nodeSetActive",a,!0)),c&&this._callHook("nodeToggleExpanded",a)}},nodeCollapseSiblings:function(a,b){var c,d,e,f=a.node;if(f.parent)for(c=f.parent.children,d=0,e=c.length;d500&&(i.lastQuicksearchTerm=""),i.lastQuicksearchTime=d,i.lastQuicksearchTerm+=l,c=i.findNextNode(i.lastQuicksearchTerm,i.getActiveNode()),c&&c.setActive(),void g.preventDefault();switch(w.eventToString(g)){case"+":case"=":i.nodeSetExpanded(b,!0);break;case"-":i.nodeSetExpanded(b,!1);break;case"space":h.isPagingNode()?i._triggerNodeEvent("clickPaging",b,g):j.checkbox?i.nodeToggleSelected(b):i.nodeSetActive(b,!0);break;case"return":i.nodeSetActive(b,!0);break;case"home":case"end":case"backspace":case"left":case"right":case"up":case"down":e=h.navigate(g.which,p,!0);break;default:o=!1}o&&g.preventDefault()},nodeLoadChildren:function(b,c){var d,f,g,h=b.tree,i=b.node,j=(new Date).getTime();return a.isFunction(c)&&(c=c.call(h,{type:"source"},b),e(!a.isFunction(c),"source callback must not return another function")),c.url&&(i._requestId&&i.warn("Recursive load request #"+j+" while #"+i._requestId+" is pending."),d=a.extend({},b.options.ajax,c),i._requestId=j,d.debugDelay?(f=d.debugDelay,a.isArray(f)&&(f=f[0]+Math.random()*(f[1]-f[0])),i.warn("nodeLoadChildren waiting debugDelay "+Math.round(f)+" ms ..."),d.debugDelay=!1,g=a.Deferred(function(b){setTimeout(function(){a.ajax(d).done(function(){b.resolveWith(this,arguments)}).fail(function(){b.rejectWith(this,arguments)})},f)})):g=a.ajax(d),c=new a.Deferred,g.done(function(d,e,f){var g,k;if("json"!==this.dataType&&"jsonp"!==this.dataType||"string"!=typeof d||a.error("Ajax request returned a string (did you get the JSON dataType wrong?)."),i._requestId&&i._requestId>j)return void c.rejectWith(this,[A]);if(b.options.postProcess){try{k=h._triggerNodeEvent("postProcess",b,b.originalEvent,{response:d,error:null,dataType:this.dataType})}catch(l){k={error:l,message:""+l,details:"postProcess failed"}}if(k.error)return g=a.isPlainObject(k.error)?k.error:{message:k.error},g=h._makeHookContext(i,null,g),void c.rejectWith(this,[g]);d=a.isArray(k)?k:d}else d&&d.hasOwnProperty("d")&&b.options.enableAspx&&(d="string"==typeof d.d?a.parseJSON(d.d):d.d);c.resolveWith(this,[d])}).fail(function(a,b,d){var e=h._makeHookContext(i,null,{error:a,args:Array.prototype.slice.call(arguments),message:d,details:a.status+": "+d});c.rejectWith(this,[e])})),a.isFunction(c.then)&&a.isFunction(c["catch"])&&(g=c,
-c=new a.Deferred,g.then(function(a){c.resolve(a)},function(a){c.reject(a)})),a.isFunction(c.promise)&&(h.nodeSetStatus(b,"loading"),c.done(function(a){h.nodeSetStatus(b,"ok"),i._requestId=null}).fail(function(a){var c;return a===A?void i.warn("Ignored response for obsolete load request #"+j+" (expected #"+i._requestId+")"):(a.node&&a.error&&a.message?c=a:(c=h._makeHookContext(i,null,{error:a,args:Array.prototype.slice.call(arguments),message:a?a.message||a.toString():""}),"[object Object]"===c.message&&(c.message="")),i.warn("Load children failed ("+c.message+")",c),void(h._triggerNodeEvent("loadError",c,null)!==!1&&h.nodeSetStatus(b,"error",c.message,c.details)))})),a.when(c).done(function(b){var c;a.isPlainObject(b)&&(e(i.isRootNode(),"source may only be an object for root nodes (expecting an array of child objects otherwise)"),e(a.isArray(b.children),"if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')"),c=b,b=b.children,delete c.children,a.extend(h.data,c)),e(a.isArray(b),"expected array of children"),i._setChildren(b),h._triggerNodeEvent("loadChildren",i)})},nodeLoadKeyPath:function(a,b){},nodeRemoveChild:function(b,c){var d,f=b.node,g=a.extend({},b,{node:c}),h=f.children;return 1===h.length?(e(c===h[0],"invalid single child"),this.nodeRemoveChildren(b)):(this.activeNode&&(c===this.activeNode||this.activeNode.isDescendantOf(c))&&this.activeNode.setActive(!1),this.focusNode&&(c===this.focusNode||this.focusNode.isDescendantOf(c))&&(this.focusNode=null),this.nodeRemoveMarkup(g),this.nodeRemoveChildren(g),d=a.inArray(c,h),e(d>=0,"invalid child"),f.triggerModifyChild("remove",c),c.visit(function(a){a.parent=null},!0),this._callHook("treeRegisterNode",this,!1,c),void h.splice(d,1))},nodeRemoveChildMarkup:function(b){var c=b.node;c.ul&&(c.isRootNode()?a(c.ul).empty():(a(c.ul).remove(),c.ul=null),c.visit(function(a){a.li=a.ul=null}))},nodeRemoveChildren:function(b){var c,d=b.tree,e=b.node,f=e.children;f&&(this.activeNode&&this.activeNode.isDescendantOf(e)&&this.activeNode.setActive(!1),this.focusNode&&this.focusNode.isDescendantOf(e)&&(this.focusNode=null),this.nodeRemoveChildMarkup(b),c=a.extend({},b),e.triggerModifyChild("remove",null),e.visit(function(a){a.parent=null,d._callHook("treeRegisterNode",d,!1,a)}),e.lazy?e.children=[]:e.children=null,e.isRootNode()||(e.expanded=!1),this.nodeRenderStatus(b))},nodeRemoveMarkup:function(b){var c=b.node;c.li&&(a(c.li).remove(),c.li=null),this.nodeRemoveChildMarkup(b)},nodeRender:function(b,d,f,g,h){var i,j,k,l,m,n,o,p=b.node,q=b.tree,r=b.options,s=r.aria,t=!1,u=p.parent,v=!u,w=p.children,x=null;if(q._enableUpdate!==!1&&(v||u.ul)){if(e(v||u.ul,"parent UL must exist"),v||(p.li&&(d||p.li.parentNode!==p.parent.ul)&&(p.li.parentNode===p.parent.ul?x=p.li.nextSibling:this.debug("Unlinking "+p+" (must be child of "+p.parent+")"),this.nodeRemoveMarkup(b)),p.li?this.nodeRenderStatus(b):(t=!0,p.li=c.createElement("li"),p.li.ftnode=p,p.key&&r.generateIds&&(p.li.id=r.idPrefix+p.key),p.span=c.createElement("span"),p.span.className="fancytree-node",s&&!p.tr&&a(p.li).attr("role","treeitem"),p.li.appendChild(p.span),this.nodeRenderTitle(b),r.createNode&&r.createNode.call(q,{type:"createNode"},b)),r.renderNode&&r.renderNode.call(q,{type:"renderNode"},b)),w){if(v||p.expanded||f===!0){for(p.ul||(p.ul=c.createElement("ul"),(g!==!0||h)&&p.expanded||(p.ul.style.display="none"),s&&a(p.ul).attr("role","group"),p.li?p.li.appendChild(p.ul):p.tree.$div.append(p.ul)),l=0,m=w.length;l1&&s.push("")):s.push(""),e=w.evalOption("checkbox",l,l,n,!1),e&&!l.isStatusNode()&&(i=q?" role='checkbox'":"",f="fancytree-checkbox",("radio"===e||l.parent&&l.parent.radiogroup)&&(f+=" fancytree-radio"),s.push("")),l.data.iconClass!==d&&(l.icon?a.error("'iconClass' node option is deprecated since v2.14.0: use 'icon' only instead"):(l.warn("'iconClass' node option is deprecated since v2.14.0: use 'icon' instead"),l.icon=l.data.iconClass)),g=w.evalOption("icon",l,l,n,!0),"boolean"!=typeof g&&(g=""+g),g!==!1&&(i=q?" role='presentation'":"","string"==typeof g?x.test(g)?(g="/"===g.charAt(0)?g:(n.imagePath||"")+g,s.push("")):s.push(""):s.push("")),h="",n.renderTitle&&(h=n.renderTitle.call(m,{type:"renderTitle"},b)||""),h||(k=w.evalOption("tooltip",l,l,n,null),k===!0&&(k=l.title),k=k?" title='"+p(k)+"'":"",j=n.titlesTabbable?" tabindex='0'":"",h=""+(n.escapeTitles?o(l.title):l.title)+""),s.push(h),l.span.innerHTML=s.join(""),this.nodeRenderStatus(b),n.enhanceTitle&&(b.$title=a(">span.fancytree-title",l.span),h=n.enhanceTitle.call(m,{type:"enhanceTitle"},b)||""))},nodeRenderStatus:function(b){var c,d=b.node,e=b.tree,f=b.options,g=d.hasChildren(),h=d.isLastSibling(),i=f.aria,j=f._classNames,k=[],l=d[e.statusClassPropName];l&&e._enableUpdate!==!1&&(i&&(c=a(d.tr||d.li)),k.push(j.node),e.activeNode===d&&k.push(j.active),e.focusNode===d&&k.push(j.focused),d.expanded&&k.push(j.expanded),i&&(g!==!1?c.attr("aria-expanded",Boolean(d.expanded)):c.removeAttr("aria-expanded")),d.folder&&k.push(j.folder),g!==!1&&k.push(j.hasChildren),h&&k.push(j.lastsib),d.lazy&&null==d.children&&k.push(j.lazy),d.partload&&k.push(j.partload),d.partsel&&k.push(j.partsel),w.evalOption("unselectable",d,d,f,!1)&&k.push(j.unselectable),d._isLoading&&k.push(j.loading),d._error&&k.push(j.error),d.statusNodeType&&k.push(j.statusNodePrefix+d.statusNodeType),d.selected?(k.push(j.selected),i&&c.attr("aria-selected",!0)):i&&c.attr("aria-selected",!1),d.extraClasses&&k.push(d.extraClasses),g===!1?k.push(j.combinedExpanderPrefix+"n"+(h?"l":"")):k.push(j.combinedExpanderPrefix+(d.expanded?"e":"c")+(d.lazy&&null==d.children?"d":"")+(h?"l":"")),k.push(j.combinedIconPrefix+(d.expanded?"e":"c")+(d.folder?"f":"")),l.className=k.join(" "),d.li&&a(d.li).toggleClass(j.lastsib,h))},nodeSetActive:function(b,c,d){d=d||{};var f,g=b.node,h=b.tree,i=b.options,j=d.noEvents===!0,m=d.noFocus===!0,n=g===h.activeNode;return c=c!==!1,n===c?k(g):c&&!j&&this._triggerNodeEvent("beforeActivate",g,b.originalEvent)===!1?l(g,["rejected"]):(c?(h.activeNode&&(e(h.activeNode!==g,"node was active (inconsistency)"),f=a.extend({},b,{node:h.activeNode}),h.nodeSetActive(f,!1),e(null===h.activeNode,"deactivate was out of sync?")),i.activeVisible&&g.makeVisible({scrollIntoView:m&&null==h.focusNode}),h.activeNode=g,h.nodeRenderStatus(b),m||h.nodeSetFocus(b),j||h._triggerNodeEvent("activate",g,b.originalEvent)):(e(h.activeNode===g,"node was not active (inconsistency)"),h.activeNode=null,this.nodeRenderStatus(b),j||b.tree._triggerNodeEvent("deactivate",g,b.originalEvent)),k(g))},nodeSetExpanded:function(b,c,e){e=e||{};var f,g,h,i,j,m,n=b.node,o=b.tree,p=b.options,q=e.noAnimation===!0,r=e.noEvents===!0;if(c=c!==!1,n.expanded&&c||!n.expanded&&!c)return k(n);if(c&&!n.lazy&&!n.hasChildren())return k(n);if(!c&&n.getLevel()ul.fancytree-container").empty(),b.rootNode.children=null},treeCreate:function(a){},treeDestroy:function(a){this.$div.find(">ul.fancytree-container").remove(),this.$source&&this.$source.removeClass("ui-helper-hidden")},treeInit:function(a){var b=a.tree,c=b.options;b.$container.attr("tabindex",c.tabindex),c.rtl?b.$container.attr("DIR","RTL").addClass("fancytree-rtl"):b.$container.removeAttr("DIR").removeClass("fancytree-rtl"),c.aria&&(b.$container.attr("role","tree"),1!==c.selectMode&&b.$container.attr("aria-multiselectable",!0)),this.treeLoad(a)},treeLoad:function(b,c){var d,f,g,h,i=b.tree,j=b.widget.element,k=a.extend({},b,{node:this.rootNode});if(i.rootNode.children&&this.treeClear(b),c=c||this.options.source)"string"==typeof c&&a.error("Not implemented");else switch(f=j.data("type")||"html"){case"html":g=j.find(">ul:first"),g.addClass("ui-fancytree-source ui-helper-hidden"),c=a.ui.fancytree.parseHtml(g),this.data=a.extend(this.data,n(g));break;case"json":c=a.parseJSON(j.text()),j.contents().filter(function(){return 3===this.nodeType}).remove(),a.isPlainObject(c)&&(e(a.isArray(c.children),"if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')"),d=c,c=c.children,delete d.children,a.extend(i.data,d));break;default:a.error("Invalid data-type: "+f)}return h=this.nodeLoadChildren(k,c).done(function(){i.render(),3===b.options.selectMode&&i.rootNode.fixSelection3FromEndNodes(),i.activeNode&&i.options.activeVisible&&i.activeNode.makeVisible(),i._triggerTreeEvent("init",null,{status:!0})}).fail(function(){i.render(),i._triggerTreeEvent("init",null,{status:!1})})},treeRegisterNode:function(a,b,c){},treeSetFocus:function(b,c,d){function e(a){!a.activeNode&&a.getFirstChild()&&a.getFirstChild().setFocus()}if(c=c!==!1,c!==this.hasFocus()&&(this._hasFocus=c,!c&&this.focusNode?this.focusNode.setFocus(!1):!c||d&&d.calledByNode||a(this.$container).focus(),this.$container.toggleClass("fancytree-treefocus",c),this._triggerTreeEvent(c?"focusTree":"blurTree"),c)){var f=this;setTimeout(function(){e(f)},0)}},treeSetOption:function(b,c,d){var e=b.tree,f=!0,g=!1;switch(c){case"aria":case"checkbox":case"icon":case"minExpandLevel":case"tabindex":e._callHook("treeCreate",e),g=!0;break;case"escapeTitles":case"tooltip":g=!0;break;case"rtl":d===!1?e.$container.removeAttr("DIR").removeClass("fancytree-rtl"):e.$container.attr("DIR","RTL").addClass("fancytree-rtl"),g=!0;break;case"source":f=!1,e._callHook("treeLoad",e,d),g=!0}e.debug("set option "+c+"="+d+" <"+typeof d+">"),f&&(this.widget._super?this.widget._super.call(this.widget,c,d):a.Widget.prototype._setOption.call(this.widget,c,d)),g&&e.render(!0,!1)}}),a.widget("ui.fancytree",{options:{activeVisible:!0,ajax:{type:"GET",cache:!1,dataType:"json"},aria:!0,autoActivate:!0,autoCollapse:!1,autoScroll:!1,checkbox:!1,clickFolderMode:4,debugLevel:null,disabled:!1,enableAspx:!0,escapeTitles:!1,extensions:[],toggleEffect:{effect:"blind",options:{direction:"vertical",scale:"box"},duration:200},generateIds:!1,icon:!0,idPrefix:"ft_",focusOnSelect:!1,keyboard:!0,keyPathSeparator:"/",minExpandLevel:1,quicksearch:!1,rtl:!1,scrollOfs:{top:0,bottom:0},scrollParent:null,selectMode:2,strings:{loading:"Loading...",loadError:"Load error!",moreData:"More...",noData:"No data."},tabindex:"0",titlesTabbable:!1,tooltip:!1,_classNames:{node:"fancytree-node",folder:"fancytree-folder",animating:"fancytree-animating",combinedExpanderPrefix:"fancytree-exp-",combinedIconPrefix:"fancytree-ico-",hasChildren:"fancytree-has-children",active:"fancytree-active",selected:"fancytree-selected",expanded:"fancytree-expanded",lazy:"fancytree-lazy",focused:"fancytree-focused",partload:"fancytree-partload",partsel:"fancytree-partsel",radio:"fancytree-radio",unselectable:"fancytree-unselectable",lastsib:"fancytree-lastsib",loading:"fancytree-loading",error:"fancytree-error",statusNodePrefix:"fancytree-statusnode-"},lazyLoad:null,postProcess:null},_create:function(){this.tree=new t(this),this.$source=this.source||"json"===this.element.data("type")?this.element:this.element.find(">ul:first");var b,c,f,g=this.options,h=g.extensions,i=this.tree;for(f=0;f=2&&f("log",arguments)},error:function(a){f("error",arguments)},escapeHtml:o,fixPositionOptions:function(b){if((b.offset||(""+b.my+b.at).indexOf("%")>=0)&&a.error("expected new position syntax (but '%' is not supported)"),!a.ui.fancytree.jquerySupports.positionMyOfs){var c=/(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec(b.my),d=/(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec(b.at),e=(c[2]?+c[2]:0)+(d[2]?+d[2]:0),f=(c[4]?+c[4]:0)+(d[4]?+d[4]:0);b=a.extend({},b,{my:c[1]+" "+c[3],at:d[1]+" "+d[3]}),(e||f)&&(b.offset=""+e+" "+f)}return b},getEventTargetType:function(a){return this.getEventTarget(a).type},getEventTarget:function(b){var c=b&&b.target?b.target.className:"",e={node:this.getNode(b.target),type:d};return/\bfancytree-title\b/.test(c)?e.type="title":/\bfancytree-expander\b/.test(c)?e.type=e.node.hasChildren()===!1?"prefix":"expander":/\bfancytree-checkbox\b/.test(c)?e.type="checkbox":/\bfancytree-icon\b/.test(c)?e.type="icon":/\bfancytree-node\b/.test(c)?e.type="title":b&&b.target&&a(b.target).closest(".fancytree-title").length&&(e.type="title"),e},getNode:function(a){if(a instanceof s)return a;for(a instanceof jQuery?a=a[0]:a.originalEvent!==d&&(a=a.target);a;){if(a.ftnode)return a.ftnode;a=a.parentNode}return null},getTree:function(b){var c;return b instanceof t?b:(b===d&&(b=0),"number"==typeof b?b=a(".fancytree-container").eq(b):"string"==typeof b?b=a(b).eq(0):b.selector!==d?b=b.eq(0):b.originalEvent!==d&&(b=a(b.target)),b=b.closest(":ui-fancytree"),c=b.data("ui-fancytree")||b.data("fancytree"),c?c.tree:null)},evalOption:function(b,c,d,e,f){var g,h,i=c.tree,j=e[b],k=d[b];return a.isFunction(j)?(g={node:c,tree:i,widget:i.widget,options:i.widget.options},h=j.call(i,{type:b},g),null==h&&(h=k)):h=null!=k?k:j,null==h&&(h=f),h},eventToString:function(a){var b=a.which,c=a.type,d=[];return a.altKey&&d.push("alt"),a.ctrlKey&&d.push("ctrl"),a.metaKey&&d.push("meta"),a.shiftKey&&d.push("shift"),"click"===c||"dblclick"===c?d.push(E[a.button]+c):C[b]||d.push(D[b]||String.fromCharCode(b).toLowerCase()),d.join("+")},info:function(b){a.ui.fancytree.debugLevel>=1&&f("info",arguments)},keyEventToString:function(a){return this.warn("keyEventToString() is deprecated: use eventToString()"),this.eventToString(a)},overrideMethod:function(b,c,d){var e,f=b[c]||a.noop;b[c]=function(){try{return e=this._super,this._super=f,d.apply(this,arguments)}finally{this._super=e}}},parseHtml:function(b){var c,e,f,g,h,i,j,k,l=b.find(">li"),m=[];return l.each(function(){var l,o,p=a(this),q=p.find(">span:first",this),r=q.length?null:p.find(">a:first"),s={tooltip:null,data:{}};for(q.length?s.title=q.html():r&&r.length?(s.title=r.html(),s.data.href=r.attr("href"),s.data.target=r.attr("target"),s.tooltip=r.attr("title")):(s.title=p.html(),h=s.title.search(/
=0&&(s.title=s.title.substring(0,h))),s.title=a.trim(s.title),g=0,i=F.length;gul:first"),b.length?s.children=a.ui.fancytree.parseHtml(b):s.children=s.lazy?d:null,m.push(s)}),m},registerExtension:function(b){e(null!=b.name,"extensions must have a `name` property."),e(null!=b.version,"extensions must have a `version` property."),a.ui.fancytree._extensions[b.name]=b},unescapeHtml:function(a){var b=c.createElement("div");return b.innerHTML=a,0===b.childNodes.length?"":b.childNodes[0].nodeValue},warn:function(a){f("warn",arguments)}})}(jQuery,window,document);
-
-/*! Extension 'jquery.fancytree.childcounter.min.js' */
-!function(a,b){"use strict";a.ui.fancytree._FancytreeClass.prototype.countSelected=function(a){var b=this;b.options;return b.getSelectedNodes(a).length},a.ui.fancytree._FancytreeNodeClass.prototype.updateCounters=function(){var b=this,c=a("span.fancytree-childcounter",b.span),d=b.tree.options.childcounter,e=b.countChildren(d.deep);b.data.childCounter=e,!e&&d.hideZeros||b.isExpanded()&&d.hideExpanded?c.remove():(c.length||(c=a("").appendTo(a("span.fancytree-icon",b.span))),c.text(e)),!d.deep||b.isTopLevel()||b.isRoot()||b.parent.updateCounters()},a.ui.fancytree.prototype.widgetMethod1=function(a){this.tree;return a},a.ui.fancytree.registerExtension({name:"childcounter",version:"2.23.0",options:{deep:!0,hideZeros:!0,hideExpanded:!1},foo:42,_appendCounter:function(a){},treeInit:function(a){a.options,a.options.childcounter;this._superApply(arguments),this.$container.addClass("fancytree-ext-childcounter")},treeDestroy:function(a){this._superApply(arguments)},nodeRenderTitle:function(b,c){var d=b.node,e=b.options.childcounter,f=null==d.data.childCounter?d.countChildren(e.deep):+d.data.childCounter;this._super(b,c),!f&&e.hideZeros||d.isExpanded()&&e.hideExpanded||a("span.fancytree-icon",d.span).append(a("").text(f))},nodeSetExpanded:function(a,b,c){var d=a.tree;a.node;return this._superApply(arguments).always(function(){d.nodeRenderTitle(a)})}})}(jQuery);
-
-/*! Extension 'jquery.fancytree.clones.min.js' */
-!function(a,b,c,d){"use strict";function e(b,c){b||(c=c?": "+c:"",a.error("Assertion failed"+c))}function f(a,b){var c;for(c=a.length-1;c>=0;c--)if(a[c]===b)return a.splice(c,1),!0;return!1}function g(a,b,c){for(var d,e,f=3&a.length,g=a.length-f,h=c,i=3432918353,j=461845907,k=0;k>>16)*i&65535)<<16)&4294967295,e=e<<15|e>>>17,e=(65535&e)*j+(((e>>>16)*j&65535)<<16)&4294967295,h^=e,h=h<<13|h>>>19,d=5*(65535&h)+((5*(h>>>16)&65535)<<16)&4294967295,h=(65535&d)+27492+(((d>>>16)+58964&65535)<<16);switch(e=0,f){case 3:e^=(255&a.charCodeAt(k+2))<<16;case 2:e^=(255&a.charCodeAt(k+1))<<8;case 1:e^=255&a.charCodeAt(k),e=(65535&e)*i+(((e>>>16)*i&65535)<<16)&4294967295,e=e<<15|e>>>17,e=(65535&e)*j+(((e>>>16)*j&65535)<<16)&4294967295,h^=e}return h^=a.length,h^=h>>>16,h=2246822507*(65535&h)+((2246822507*(h>>>16)&65535)<<16)&4294967295,h^=h>>>13,h=3266489909*(65535&h)+((3266489909*(h>>>16)&65535)<<16)&4294967295,h^=h>>>16,b?("0000000"+(h>>>0).toString(16)).substr(-8):h>>>0}function h(b){var c,d=a.map(b.getParentList(!1,!0),function(a){return a.refKey||a.key});return d=d.join("/"),c="id_"+g(d,!0)}a.ui.fancytree._FancytreeNodeClass.prototype.getCloneList=function(b){var c,d=this.tree,e=d.refMap[this.refKey]||null,f=d.keyMap;return e&&(c=this.key,b?e=a.map(e,function(a){return f[a]}):(e=a.map(e,function(a){return a===c?null:f[a]}),e.length<1&&(e=null))),e},a.ui.fancytree._FancytreeNodeClass.prototype.isClone=function(){var a=this.refKey||null,b=a&&this.tree.refMap[a]||null;return!!(b&&b.length>1)},a.ui.fancytree._FancytreeNodeClass.prototype.reRegister=function(b,c){b=null==b?null:""+b,c=null==c?null:""+c;var d=this.tree,e=this.key,f=this.refKey,g=d.keyMap,h=d.refMap,i=h[f]||null,j=!1;return null!=b&&b!==this.key&&(g[b]&&a.error("[ext-clones] reRegister("+b+"): already exists: "+this),delete g[e],g[b]=this,i&&(h[f]=a.map(i,function(a){return a===e?b:a})),this.key=b,j=!0),null!=c&&c!==this.refKey&&(i&&(1===i.length?delete h[f]:h[f]=a.map(i,function(a){return a===e?null:a})),h[c]?h[c].append(b):h[c]=[this.key],this.refKey=c,j=!0),j},a.ui.fancytree._FancytreeNodeClass.prototype.setRefKey=function(a){return this.reRegister(null,a)},a.ui.fancytree._FancytreeClass.prototype.getNodesByRef=function(b,c){var d=this.keyMap,e=this.refMap[b]||null;return e&&(e=c?a.map(e,function(a){var b=d[a];return b.isDescendantOf(c)?b:null}):a.map(e,function(a){return d[a]}),e.length<1&&(e=null)),e},a.ui.fancytree._FancytreeClass.prototype.changeRefKey=function(a,b){var c,d,e=this.keyMap,f=this.refMap[a]||null;if(f){for(c=0;c0?"+"+a:""+a}function f(b){var c;return!!b&&(c=a.isPlainObject(b)?{over:!!b.over,before:!!b.before,after:!!b.after}:a.isArray(b)?{over:a.inArray("over",b)>=0,before:a.inArray("before",b)>=0,after:a.inArray("after",b)>=0}:{over:b===!0||"over"===b,before:b===!0||"before"===b,after:b===!0||"after"===b},0!==Object.keys(c).length&&c)}function g(d,e){var f,g,h,i=d.options.dnd5,j=d.$scrollParent[0],k=i.scrollSensitivity,l=i.scrollSpeed,m=0;return j!==c&&"HTML"!==j.tagName?(f=d.$scrollParent.offset(),g=j.scrollTop,f.top+j.offsetHeight-e.pageY0&&(j.scrollTop=m=g+l)):g>0&&e.pageY-f.top0&&e.pageY-g.75?i="after":!t.over&&t.after&&h>.5?i="after":t.before&&h<=.25?i="before":!t.over&&t.before&&h<=.5?i="before":t.over&&(i="over"),s.preventVoidMoves&&(v===w?(v.debug("drop over source node prevented"),i=null):"before"===i&&w&&v===w.getNextSibling()?(v.debug("drop after source node prevented"),i=null):"after"===i&&w&&v===w.getPrevSibling()?(v.debug("drop before source node prevented"),i=null):"over"===i&&w&&w.parent===v&&w.isLastSibling()&&(v.debug("drop last child over own parent prevented"),i=null))),c.hitMode=i,i&&s.dragOver&&(s.dragOver(v,c),i=c.hitMode),u=i,"after"===i||"before"===i||"over"===i){switch(d=s.dropMarkerOffsetX||0,i){case"before":x="top",d+=s.dropMarkerInsertOffsetX||0;break;case"after":x="bottom",d+=s.dropMarkerInsertOffsetX||0}r.toggleClass(l,"after"===i).toggleClass(n,"over"===i).toggleClass(m,"before"===i).show().position(a.ui.fancytree.fixPositionOptions({my:"left"+e(d)+" center",at:"left "+x,of:z}))}else r.hide();return a(v.span).toggleClass(p,"after"===i||"before"===i||"over"===i).toggleClass(l,"after"===i).toggleClass(m,"before"===i).toggleClass(k,"over"===i).toggleClass(o,i===!1),i}var i="fancytree-drag-source",j="fancytree-drag-remove",k="fancytree-drop-accept",l="fancytree-drop-after",m="fancytree-drop-before",n="fancytree-drop-over",o="fancytree-drop-reject",p="fancytree-drop-target",q="application/x-fancytree-node",r=null,s=null,t=null,u=null;a.ui.fancytree.registerExtension({name:"dnd5",version:"2.23.0",options:{autoExpandMS:1500,setTextTypeJson:!1,preventForeignNodes:!1,preventNonNodes:!1,preventRecursiveMoves:!0,preventVoidMoves:!0,scroll:!0,scrollSensitivity:20,scrollSpeed:5,dropMarkerOffsetX:-24,dropMarkerInsertOffsetX:-16,dragStart:null,dragDrag:a.noop,dragEnd:a.noop,dragEnter:null,dragOver:a.noop,dragExpand:a.noop,dragDrop:a.noop,dragLeave:a.noop},treeInit:function(b){var c=b.tree,e=b.options,g=e.dnd5,l=a.ui.fancytree.getNode;a.inArray("dnd",e.extensions)>=0&&a.error("Extensions 'dnd' and 'dnd5' are mutually exclusive."),g.dragStop&&a.error("dragStop is not used by ext-dnd5. Use dragEnd instead."),g.dragStart&&a.ui.fancytree.overrideMethod(b.options,"createNode",function(a,b){this._super.apply(this,arguments),b.node.span.draggable=!0}),this._superApply(arguments),this.$container.addClass("fancytree-ext-dnd5"),this.$scrollParent=this.$container.children(":first").scrollParent(),r=a("#fancytree-drop-marker"),r.length||(r=a("").hide().css({"z-index":1e3,"pointer-events":"none"}).prependTo("body")),g.dragStart&&c.$container.on("dragstart drag dragend",function(b){var e,f=l(b),h=b.dataTransfer||b.originalEvent.dataTransfer,k="move"===h.dropEffect,m=f?a(f.span):null,n={node:f,tree:c,options:c.options,originalEvent:b,dataTransfer:h,isCancelled:d};switch(b.type){case"dragstart":a(f.span).addClass(i),s=f,e=JSON.stringify(f.toDict());try{h.setData(q,e),h.setData("text/html",a(f.span).html()),h.setData("text/plain",f.title)}catch(o){c.warn("Could not set data (IE only accepts 'text') - "+o)}return g.setTextTypeJson?h.setData("text",e):h.setData("text",f.title),h.effectAllowed="all",h.setDragImage&&h.setDragImage(a(f.span).find(".fancytree-title")[0],-10,-10),g.dragStart(f,n)!==!1;case"drag":m.toggleClass(j,k),g.dragDrag(f,n);break;case"dragend":a(f.span).removeClass(i+" "+j),s=null,t=null,n.isCancelled="none"===h.dropEffect,r.hide(),g.dragEnd(f,n)}}),g.dragEnter&&c.$container.on("dragenter dragover dragleave drop",function(b){var e,i,j,m,p=null,v=l(b),w=b.dataTransfer||b.originalEvent.dataTransfer,x={node:v,tree:c,options:c.options,hitMode:t,originalEvent:b,dataTransfer:w,otherNode:s||null,otherNodeData:null,dropEffect:d,isCancelled:d};switch(b.type){case"dragenter":if(!v){c.debug("Ignore non-node "+b.type+": "+b.target.tagName+"."+b.target.className),t=!1;break}if(a(v.span).addClass(n).removeClass(k+" "+o),g.preventNonNodes&&!i){v.debug("Reject dropping a non-node"),t=!1;break}if(g.preventForeignNodes&&(!s||s.tree!==v.tree)){v.debug("Reject dropping a foreign node"),t=!1;break}setTimeout(function(){!g.autoExpandMS||v.hasChildren()===!1||v.expanded||g.dragExpand&&g.dragExpand(v,x)===!1||v.scheduleAction("expand",g.autoExpandMS)},0),r.show(),g.preventRecursiveMoves&&v.isDescendantOf(x.otherNode)?m=!1:(j=g.dragEnter(v,x),m=f(j)),t=m,p=m&&(m.over||m.before||m.after);break;case"dragover":u=h(b,x),p=!!u;break;case"dragleave":if(!v){c.debug("Ignore non-node "+b.type+": "+b.target.tagName+"."+b.target.className);break}if(!a(v.span).hasClass(n)){v.debug("Ignore dragleave (multi)");break}a(v.span).removeClass(n+" "+k+" "+o),v.scheduleAction("cancel"),g.dragLeave(v,x),r.hide();break;case"drop":if(a.inArray(q,w.types)>=0&&(i=w.getData(q),c.info(b.type+": getData('application/x-fancytree-node'): '"+i+"'")),i||(i=w.getData("text"),c.info(b.type+": getData('text'): '"+i+"'")),i)try{e=JSON.parse(i),e.title!==d&&(x.otherNodeData=e)}catch(y){}c.debug(b.type+": nodeData: '"+i+"', otherNodeData: ",x.otherNodeData),a(v.span).removeClass(n+" "+k+" "+o),r.hide(),x.hitMode=u,x.dropEffect=w.dropEffect,x.isCancelled="none"===x.dropEffect,g.dragDrop(v,x),b.preventDefault()}if(p)return b.preventDefault(),!1})}})}(jQuery,window,document);
-
-/*! Extension 'jquery.fancytree.edit.min.js' */
-!function(a,b,c,d){"use strict";var e=/Mac/.test(navigator.platform),f=a.ui.fancytree.escapeHtml,g=a.ui.fancytree.unescapeHtml;a.ui.fancytree._FancytreeNodeClass.prototype.editStart=function(){var b,d=this,e=this.tree,f=e.ext.edit,h=e.options.edit,i=a(".fancytree-title",d.span),j={node:d,tree:e,options:e.options,isNew:a(d[e.statusClassPropName]).hasClass("fancytree-edit-new"),orgTitle:d.title,input:null,dirty:!1};return h.beforeEdit.call(d,{type:"beforeEdit"},j)!==!1&&(a.ui.fancytree.assert(!f.currentNode,"recursive edit"),f.currentNode=this,f.eventData=j,e.widget._unbind(),a(c).on("mousedown.fancytree-edit",function(b){a(b.target).hasClass("fancytree-edit-input")||d.editEnd(!0,b)}),b=a("",{"class":"fancytree-edit-input",type:"text",value:e.options.escapeTitles?j.orgTitle:g(j.orgTitle)}),f.eventData.input=b,null!=h.adjustWidthOfs&&b.width(i.width()+h.adjustWidthOfs),null!=h.inputCss&&b.css(h.inputCss),i.html(b),b.focus().change(function(a){b.addClass("fancytree-edit-dirty")}).keydown(function(b){switch(b.which){case a.ui.keyCode.ESCAPE:d.editEnd(!1,b);break;case a.ui.keyCode.ENTER:return d.editEnd(!0,b),!1}b.stopPropagation()}).blur(function(a){return d.editEnd(!0,a)}),void h.edit.call(d,{type:"edit"},j))},a.ui.fancytree._FancytreeNodeClass.prototype.editEnd=function(b,d){var e,g=this,h=this.tree,i=h.ext.edit,j=i.eventData,k=h.options.edit,l=a(".fancytree-title",g.span),m=l.find("input.fancytree-edit-input");return k.trim&&m.val(a.trim(m.val())),e=m.val(),j.dirty=e!==g.title,j.originalEvent=d,b===!1?j.save=!1:j.isNew?j.save=""!==e:j.save=j.dirty&&""!==e,k.beforeClose.call(g,{type:"beforeClose"},j)!==!1&&((!j.save||k.save.call(g,{type:"save"},j)!==!1)&&(m.removeClass("fancytree-edit-dirty").off(),a(c).off(".fancytree-edit"),j.save?(g.setTitle(h.options.escapeTitles?e:f(e)),g.setFocus()):j.isNew?(g.remove(),g=j.node=null,i.relatedNode.setFocus()):(g.renderTitle(),g.setFocus()),i.eventData=null,i.currentNode=null,i.relatedNode=null,h.widget._bind(),a(h.$container).focus(),j.input=null,k.close.call(g,{type:"close"},j),!0))},a.ui.fancytree._FancytreeNodeClass.prototype.editCreateNode=function(b,c){var d,e=this.tree,f=this;return b=b||"child",null==c?c={title:""}:"string"==typeof c?c={title:c}:a.ui.fancytree.assert(a.isPlainObject(c)),"child"!==b||this.isExpanded()||this.hasChildren()===!1?(d=this.addNode(c,b),d.match=!0,a(d[e.statusClassPropName]).removeClass("fancytree-hide").addClass("fancytree-match"),void d.makeVisible().done(function(){a(d[e.statusClassPropName]).addClass("fancytree-edit-new"),f.tree.ext.edit.relatedNode=f,d.editStart()})):void this.setExpanded().done(function(){f.editCreateNode(b,c)})},a.ui.fancytree._FancytreeClass.prototype.isEditing=function(){return this.ext.edit?this.ext.edit.currentNode:null},a.ui.fancytree._FancytreeNodeClass.prototype.isEditing=function(){return!!this.tree.ext.edit&&this.tree.ext.edit.currentNode===this},a.ui.fancytree.registerExtension({name:"edit",version:"2.23.0",options:{adjustWidthOfs:4,allowEmpty:!1,inputCss:{minWidth:"3em"},triggerStart:["f2","shift+click","mac+enter"],trim:!0,beforeClose:a.noop,beforeEdit:a.noop,close:a.noop,edit:a.noop,save:a.noop},currentNode:null,treeInit:function(a){this._superApply(arguments),this.$container.addClass("fancytree-ext-edit")},nodeClick:function(b){return a.inArray("shift+click",b.options.edit.triggerStart)>=0&&b.originalEvent.shiftKey?(b.node.editStart(),!1):this._superApply(arguments)},nodeDblclick:function(b){return a.inArray("dblclick",b.options.edit.triggerStart)>=0?(b.node.editStart(),!1):this._superApply(arguments)},nodeKeydown:function(b){switch(b.originalEvent.which){case 113:if(a.inArray("f2",b.options.edit.triggerStart)>=0)return b.node.editStart(),!1;break;case a.ui.keyCode.ENTER:if(a.inArray("mac+enter",b.options.edit.triggerStart)>=0&&e)return b.node.editStart(),!1}return this._superApply(arguments)}})}(jQuery,window,document);
-
-/*! Extension 'jquery.fancytree.filter.min.js' */
-!function(a,b,c,d){"use strict";function e(a){return(a+"").replace(/([.?*+\^\$\[\]\\(){}|-])/g,"\\$1")}function f(b){return b.indexOf(">")>=0?a("").html(b).text():b}var g="__not_found__",h=a.ui.fancytree.escapeHtml;a.ui.fancytree._FancytreeClass.prototype._applyFilterImpl=function(b,c,d){var i,j,k,l,m=0,n=this.options,o=n.escapeTitles,p=n.autoCollapse,q=a.extend({},n.filter,d),r="hide"===q.mode,s=!!q.leavesOnly&&!c;return"string"==typeof b&&(i=q.fuzzy?b.split("").reduce(function(a,b){return a+"[^"+b+"]*"+b}):e(b),k=new RegExp(".*"+i+".*","i"),l=new RegExp(e(b),"gi"),b=function(a){var b,c=o?a.title:f(a.title),d=!!k.test(c);return d&&q.highlight&&(b=o?h(a.title):c,a.titleWithHighlight=b.replace(l,function(a){return""+a+""})),d}),this.enableFilter=!0,this.lastFilterArgs=arguments,this.$div.addClass("fancytree-ext-filter"),r?this.$div.addClass("fancytree-ext-filter-hide"):this.$div.addClass("fancytree-ext-filter-dimm"),this.$div.toggleClass("fancytree-ext-filter-hide-expanders",!!q.hideExpanders),this.visit(function(a){delete a.match,delete a.titleWithHighlight,a.subMatchCount=0}),j=this.getRootNode()._findDirectChild(g),j&&j.remove(),n.autoCollapse=!1,this.visit(function(a){if(!s||null==a.children){var d=b(a),e=!1;if("skip"===d)return a.visit(function(a){a.match=!1},!0),"skip";d||!c&&"branch"!==d||!a.parent.match||(d=!0,e=!0),d&&(m++,a.match=!0,a.visitParents(function(a){a.subMatchCount+=1,!q.autoExpand||e||a.expanded||(a.setExpanded(!0,{noAnimation:!0,noEvents:!0,scrollIntoView:!1}),a._filterAutoExpanded=!0)}))}}),n.autoCollapse=p,0===m&&q.nodata&&r&&(j=q.nodata,a.isFunction(j)&&(j=j()),j===!0?j={}:"string"==typeof j&&(j={title:j}),j=a.extend({statusNodeType:"nodata",key:g,title:this.options.strings.noData},j),this.getRootNode().addNode(j).match=!0),this.render(),m},a.ui.fancytree._FancytreeClass.prototype.filterNodes=function(a,b){return"boolean"==typeof b&&(b={leavesOnly:b},this.warn("Fancytree.filterNodes() leavesOnly option is deprecated since 2.9.0 / 2015-04-19. Use opts.leavesOnly instead.")),this._applyFilterImpl(a,!1,b)},a.ui.fancytree._FancytreeClass.prototype.applyFilter=function(a){return this.warn("Fancytree.applyFilter() is deprecated since 2.1.0 / 2014-05-29. Use .filterNodes() instead."),this.filterNodes.apply(this,arguments)},a.ui.fancytree._FancytreeClass.prototype.filterBranches=function(a,b){return this._applyFilterImpl(a,!0,b)},a.ui.fancytree._FancytreeClass.prototype.clearFilter=function(){var b,c=this.getRootNode()._findDirectChild(g),d=this.options.escapeTitles,e=this.options.enhanceTitle;c&&c.remove(),this.visit(function(c){c.match&&c.span&&(b=a(c.span).find(">span.fancytree-title"),d?b.text(c.title):b.html(c.title),e&&e({type:"enhanceTitle"},{node:c,$title:b})),delete c.match,delete c.subMatchCount,delete c.titleWithHighlight,c.$subMatchBadge&&(c.$subMatchBadge.remove(),delete c.$subMatchBadge),c._filterAutoExpanded&&c.expanded&&c.setExpanded(!1,{noAnimation:!0,noEvents:!0,scrollIntoView:!1}),delete c._filterAutoExpanded}),this.enableFilter=!1,this.lastFilterArgs=null,this.$div.removeClass("fancytree-ext-filter fancytree-ext-filter-dimm fancytree-ext-filter-hide"),this.render()},a.ui.fancytree._FancytreeClass.prototype.isFilterActive=function(){return!!this.enableFilter},a.ui.fancytree._FancytreeNodeClass.prototype.isMatched=function(){return!(this.tree.enableFilter&&!this.match)},a.ui.fancytree.registerExtension({name:"filter",version:"2.23.0",options:{autoApply:!0,autoExpand:!1,counter:!0,fuzzy:!1,hideExpandedCounter:!0,hideExpanders:!1,highlight:!0,leavesOnly:!1,nodata:!0,mode:"dimm"},nodeLoadChildren:function(a,b){return this._superApply(arguments).done(function(){a.tree.enableFilter&&a.tree.lastFilterArgs&&a.options.filter.autoApply&&a.tree._applyFilterImpl.apply(a.tree,a.tree.lastFilterArgs)})},nodeSetExpanded:function(a,b,c){return delete a.node._filterAutoExpanded,!b&&a.options.filter.hideExpandedCounter&&a.node.$subMatchBadge&&a.node.$subMatchBadge.show(),this._superApply(arguments)},nodeRenderStatus:function(b){var c,d=b.node,e=b.tree,f=b.options.filter,g=a(d.span).find("span.fancytree-title"),h=a(d[e.statusClassPropName]),i=b.options.enhanceTitle,j=b.options.escapeTitles;return c=this._super(b),h.length&&e.enableFilter?(h.toggleClass("fancytree-match",!!d.match).toggleClass("fancytree-submatch",!!d.subMatchCount).toggleClass("fancytree-hide",!(d.match||d.subMatchCount)),!f.counter||!d.subMatchCount||d.isExpanded()&&f.hideExpandedCounter?d.$subMatchBadge&&d.$subMatchBadge.hide():(d.$subMatchBadge||(d.$subMatchBadge=a(""),a("span.fancytree-icon, span.fancytree-custom-icon",d.span).append(d.$subMatchBadge)),d.$subMatchBadge.show().text(d.subMatchCount)),!d.span||d.isEditing&&d.isEditing.call(d)||(d.titleWithHighlight?g.html(d.titleWithHighlight):j?g.text(d.title):g.html(d.title),i&&i({type:"enhanceTitle"},{node:d,$title:g})),c):c}})}(jQuery,window,document);
-
-/*! Extension 'jquery.fancytree.glyph.min.js' */
-!function(a,b,c,d){"use strict";function e(a,b){return a.map[b]}a.ui.fancytree.registerExtension({name:"glyph",version:"2.23.0",options:{map:{checkbox:"icon-check-empty",checkboxSelected:"icon-check",checkboxUnknown:"icon-check icon-muted",error:"icon-exclamation-sign",expanderClosed:"icon-caret-right",expanderLazy:"icon-angle-right",expanderOpen:"icon-caret-down",nodata:"icon-meh",noExpander:"",dragHelper:"icon-caret-right",dropMarker:"icon-caret-right",doc:"icon-file-alt",docOpen:"icon-file-alt",loading:"icon-refresh icon-spin",folder:"icon-folder-close-alt",folderOpen:"icon-folder-open-alt"}},treeInit:function(a){var b=a.tree;this._superApply(arguments),b.$container.addClass("fancytree-ext-glyph")},nodeRenderStatus:function(b){var c,d,f,g=b.node,h=a(g.span),i=b.options.glyph,j=i.map;return d=this._super(b),g.isRoot()?d:(f=h.children("span.fancytree-expander").get(0),f&&(c=g.expanded&&g.hasChildren()?"expanderOpen":g.isUndefined()?"expanderLazy":g.hasChildren()?"expanderClosed":"noExpander",f.className="fancytree-expander "+j[c]),f=g.tr?a("td",g.tr).find("span.fancytree-checkbox").get(0):h.children("span.fancytree-checkbox").get(0),f&&(c=g.selected?"checkboxSelected":g.partsel?"checkboxUnknown":"checkbox",f.className="fancytree-checkbox "+j[c]),f=h.children("span.fancytree-icon").get(0),f&&(c=g.statusNodeType?e(i,g.statusNodeType):g.folder?g.expanded&&g.hasChildren()?e(i,"folderOpen"):e(i,"folder"):g.expanded?e(i,"docOpen"):e(i,"doc"),f.className="fancytree-icon "+c),d)},nodeSetStatus:function(b,c,d,f){var g,h,i=b.options.glyph,j=b.node;return g=this._superApply(arguments),"error"!==c&&"loading"!==c&&"nodata"!==c||(j.parent?(h=a("span.fancytree-expander",j.span).get(0),h&&(h.className="fancytree-expander "+e(i,c))):(h=a(".fancytree-statusnode-"+c,j[this.nodeContainerAttrName]).find("span.fancytree-icon").get(0),h&&(h.className="fancytree-icon "+e(i,c)))),g}})}(jQuery,window,document);
-
-/*! Extension 'jquery.fancytree.gridnav.min.js' */
-!function(a,b,c,d){"use strict";function e(b,c){var d,e=c.get(0),f=0;return b.children().each(function(){return this!==e&&(d=a(this).prop("colspan"),void(f+=d?d:1))}),f}function f(b,c){var d,e=null,f=0;return b.children().each(function(){return f>=c?(e=a(this),!1):(d=a(this).prop("colspan"),void(f+=d?d:1))}),e}function g(a,b){var c,d,g=a.closest("td"),i=null;switch(b){case h.LEFT:i=g.prev();break;case h.RIGHT:i=g.next();break;case h.UP:case h.DOWN:for(c=g.parent(),d=e(c,g);;){if(c=b===h.UP?c.prev():c.next(),!c.length)break;if(!c.is(":hidden")&&(i=f(c,d),i&&i.find(":input,a").length))break}}return i}var h=a.ui.keyCode,i={text:[h.UP,h.DOWN],checkbox:[h.UP,h.DOWN,h.LEFT,h.RIGHT],link:[h.UP,h.DOWN,h.LEFT,h.RIGHT],radiobutton:[h.UP,h.DOWN,h.LEFT,h.RIGHT],"select-one":[h.LEFT,h.RIGHT],"select-multiple":[h.LEFT,h.RIGHT]};a.ui.fancytree.registerExtension({name:"gridnav",version:"2.23.0",options:{autofocusInput:!1,handleCursorKeys:!0},treeInit:function(b){this._requireExtension("table",!0,!0),this._superApply(arguments),this.$container.addClass("fancytree-ext-gridnav"),this.$container.on("focusin",function(c){var d,e=a.ui.fancytree.getNode(c.target);e&&!e.isActive()&&(d=b.tree._makeHookContext(e,c),b.tree._callHook("nodeSetActive",d,!0))})},nodeSetActive:function(b,c,d){var e,f=b.options.gridnav,g=b.node,h=b.originalEvent||{},i=a(h.target).is(":input");c=c!==!1,this._superApply(arguments),c&&(b.options.titlesTabbable?(i||(a(g.span).find("span.fancytree-title").focus(),g.setFocus()),b.tree.$container.attr("tabindex","-1")):f.autofocusInput&&!i&&(e=a(g.tr||g.span),e.find(":input:enabled:first").focus()))},nodeKeydown:function(b){var c,d,e,f=b.options.gridnav,h=b.originalEvent,j=a(h.target);return j.is(":input:enabled")?c=j.prop("type"):j.is("a")&&(c="link"),c&&f.handleCursorKeys?(d=i[c],!(d&&a.inArray(h.which,d)>=0&&(e=g(j,h.which),e&&e.length))||(e.find(":input:enabled,a").focus(),!1)):this._superApply(arguments)}})}(jQuery,window,document);
-
-/*! Extension 'jquery.fancytree.persist.min.js' */
-!function(a,b,c,d){"use strict";function e(b,c,d,f,g){var h,i,j,l,m=!1,n=b.options.persist.expandOpts,o=[],p=[];for(d=d||[],g=g||a.Deferred(),h=0,j=d.length;h0)e(b,c,p,f,g);else{if(p.length)for(b.warn("_loadLazyNodes: could not load those keys: ",p),h=0,j=p.length;h=0&&b._data(c+j,null),a.indexOf(k)>=0&&b._data(c+k,null),a.indexOf(l)>=0&&b._data(c+l,null),a.indexOf(m)>=0&&b._data(c+m,null)},a.ui.fancytree._FancytreeClass.prototype.getPersistData=function(){var a=this.ext.persist,b=a.cookiePrefix,c=a.cookieDelimiter,d={};return d[j]=a._data(b+j),d[k]=(a._data(b+k)||"").split(c),d[m]=(a._data(b+m)||"").split(c),d[l]=a._data(b+l),d},a.ui.fancytree.registerExtension({name:"persist",version:"2.23.0",options:{cookieDelimiter:"~",cookiePrefix:d,cookie:{raw:!1,expires:"",path:"",domain:"",secure:!1},expandLazy:!1,expandOpts:d,fireActivate:!0,overrideSource:!0,store:"auto",types:"active expanded focus selected"},_data:function(a,b){var c=this._local.localStorage;return b===d?c?c.getItem(a):f(a):void(null===b?c?c.removeItem(a):g(a):c?c.setItem(a,b):h(a,b,this.options.persist.cookie))},_appendKey:function(b,c,d){c=""+c;var e=this._local,f=this.options.persist,g=f.cookieDelimiter,h=e.cookiePrefix+b,i=e._data(h),j=i?i.split(g):[],k=a.inArray(c,j);k>=0&&j.splice(k,1),d&&j.push(c),e._data(h,j.join(g))},treeInit:function(c){var g=c.tree,h=c.options,n=this._local,o=this.options.persist;return i("auto"!==o.store&&"cookie"!==o.store||f,"Missing required plugin for 'persist' extension: js.cookie.js or jquery.cookie.js"),n.cookiePrefix=o.cookiePrefix||"fancytree-"+g._id+"-",n.storeActive=o.types.indexOf(j)>=0,n.storeExpanded=o.types.indexOf(k)>=0,n.storeSelected=o.types.indexOf(m)>=0,n.storeFocus=o.types.indexOf(l)>=0,"cookie"!==o.store&&b.localStorage?n.localStorage="local"===o.store?b.localStorage:b.sessionStorage:n.localStorage=null,g.$div.bind("fancytreeinit",function(b){if(g._triggerTreeEvent("beforeRestore",null,{})!==!1){var c,f,i,p,q,r=n._data(n.cookiePrefix+l),s=o.fireActivate===!1;c=n._data(n.cookiePrefix+k),p=c&&c.split(o.cookieDelimiter),f=n.storeExpanded?e(g,n,p,!!o.expandLazy&&"expand",null):(new a.Deferred).resolve(),f.done(function(){if(n.storeSelected){if(c=n._data(n.cookiePrefix+m))for(p=c.split(o.cookieDelimiter),i=0;i1&&h[0]!==b)for(c=a.inArray(b,h),f=h[c-1],e(f.tr);f.children&&f.children.length&&(d=f.children[f.children.length-1],d.tr);)f=d;else f=g;return f}a.ui.fancytree.registerExtension({name:"table",version:"2.23.0",options:{checkboxColumnIdx:null,indentation:16,nodeColumnIdx:0},treeInit:function(b){var d,f,g,h,i,j=b.tree,k=b.options,l=k.table,m=j.widget.element;if(null!=l.customStatus&&(null!=k.renderStatusColumns?a.error("The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' only instead."):(j.warn("The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' instead."),k.renderStatusColumns=l.customStatus)),k.renderStatusColumns&&k.renderStatusColumns===!0&&(k.renderStatusColumns=k.renderColumns),m.addClass("fancytree-container fancytree-ext-table"),j.tbody=m.find(">tbody")[0],i=a(j.tbody),f=a("thead >tr:last >th",m).length,h=i.children("tr:first"),h.length)g=h.children("td").length,f&&g!==f&&(j.warn("Column count mismatch between thead ("+f+") and tbody ("+g+"): using tbody."),f=g),h=h.clone();else for(e(f>=1,"Need either or with
elements to determine column count."),h=a("
"),d=0;d");h.find(">td").eq(l.nodeColumnIdx).html(""),k.aria&&(h.attr("role","row"),h.find("td").attr("role","gridcell")),j.rowFragment=c.createDocumentFragment(),j.rowFragment.appendChild(h.get(0)),i.empty(),j.statusClassPropName="tr",j.ariaPropName="tr",this.nodeContainerAttrName="tr",j.$container=m,this._superApply(arguments),a(j.rootNode.ul).remove(),j.rootNode.ul=null,this.$container.attr("tabindex",k.tabindex),k.aria&&j.$container.attr("role","treegrid").attr("aria-readonly",!0)},nodeRemoveChildMarkup:function(b){var c=b.node;c.visit(function(b){b.tr&&(a(b.tr).remove(),b.tr=null)})},nodeRemoveMarkup:function(b){var c=b.node;c.tr&&(a(c.tr).remove(),c.tr=null),this.nodeRemoveChildMarkup(b)},nodeRender:function(b,c,d,j,k){var l,m,n,o,p,q,r,s,t=b.tree,u=b.node,v=b.options,w=!u.parent;if(t._enableUpdate!==!1){if(k||(b.hasCollapsedParents=u.parent&&!u.parent.expanded),!w)if(u.tr&&c&&this.nodeRemoveMarkup(b),u.tr)c?this.nodeRenderTitle(b):this.nodeRenderStatus(b);else{if(b.hasCollapsedParents&&!d)return;p=t.rowFragment.firstChild.cloneNode(!0),q=i(u),e(q),j===!0&&k?p.style.display="none":d&&b.hasCollapsedParents&&(p.style.display="none"),q.tr?g(q.tr,p):(e(!q.parent,"prev. row must have a tr, or be system root"),f(t.tbody,p)),u.tr=p,u.key&&v.generateIds&&(u.tr.id=v.idPrefix+u.key),u.tr.ftnode=u,u.span=a("span.fancytree-node",u.tr).get(0),this.nodeRenderTitle(b),v.createNode&&v.createNode.call(t,{type:"createNode"},b)}if(v.renderNode&&v.renderNode.call(t,{type:"renderNode"},b),l=u.children,l&&(w||d||u.expanded))for(n=0,o=l.length;n").attr("id",b).addClass("fancytree-style").prop("type","text/css").appendTo("head"));try{d.html(c)}catch(e){d[0].styleSheet.cssText=c}return d}function f(a,b,c,d,e,f){var g,h="#"+a+" span.fancytree-level-",i=[];for(g=0;g
").appendTo(b.tree.$container),n=m.find(".fancytree-icon"),o=m.find("ul"),p=l.iconSpacing||n.css("margin-left"),q=l.iconWidth||n.css("width"),r=l.labelSpacing||"3px",s=l.levelOfs||o.css("padding-left");m.remove(),h=p.match(g)[2],p=parseFloat(p,10),i=r.match(g)[2],r=parseFloat(r,10),j=q.match(g)[2],q=parseFloat(q,10),k=s.match(g)[2],h===j&&k===j&&i===j||a.error("iconWidth, iconSpacing, and levelOfs must have the same css measure unit"),this._local.measureUnit=j,this._local.levelOfs=parseFloat(s),this._local.lineOfs=(1+(b.options.checkbox?1:0)+(b.options.icon===!1?0:1))*(q+p)+p,this._local.labelOfs=r,this._local.maxDepth=10,c=this.$container.uniqueId().attr("id"),d=f(c,this._local.maxDepth,this._local.levelOfs,this._local.lineOfs,this._local.labelOfs,this._local.measureUnit),e(c,d)},treeDestroy:function(a){return e(this.$container.attr("id"),null),this._superApply(arguments)},nodeRenderStatus:function(b){var c,d,g,h=b.node,i=h.getLevel();return g=this._super(b),i>this._local.maxDepth&&(c=this.$container.attr("id"),this._local.maxDepth*=2,h.debug("Define global ext-wide css up to level "+this._local.maxDepth),d=f(c,this._local.maxDepth,this._local.levelOfs,this._local.lineOfs,this._local.labelSpacing,this._local.measureUnit),e(c,d)),a(h.span).addClass("fancytree-level-"+i),g}})}(jQuery,window,document);
-}));
diff --git a/public/libraries/fancytree/jquery.fancytree-all.js b/public/libraries/fancytree/jquery.fancytree-all.js
deleted file mode 100644
index 6172fbb6d..000000000
--- a/public/libraries/fancytree/jquery.fancytree-all.js
+++ /dev/null
@@ -1,9226 +0,0 @@
-/*!
- * jquery.fancytree.js
- * Tree view control with support for lazy loading and much more.
- * https://github.com/mar10/fancytree/
- *
- * Copyright (c) 2008-2017, Martin Wendt (http://wwWendt.de)
- * Released under the MIT license
- * https://github.com/mar10/fancytree/wiki/LicenseInfo
- *
- * @version 2.23.0
- * @date 2017-05-27T20:09:38Z
- */
-
-/** Core Fancytree module.
- */
-
-
-// Start of local namespace
-;(function($, window, document, undefined) {
-"use strict";
-
-// prevent duplicate loading
-if ( $.ui && $.ui.fancytree ) {
- $.ui.fancytree.warn("Fancytree: ignored duplicate include");
- return;
-}
-
-
-/* *****************************************************************************
- * Private functions and variables
- */
-
-var i, attr,
- FT = null, // initialized below
- TEST_IMG = new RegExp(/\.|\//), // strings are considered image urls if they contain '.' or '/'
- REX_HTML = /[&<>"'\/]/g,
- REX_TOOLTIP = /[<>"'\/]/g,
- RECURSIVE_REQUEST_ERROR = "$recursive_request",
- ENTITY_MAP = {"&": "&", "<": "<", ">": ">", "\"": """, "'": "'", "/": "/"},
- IGNORE_KEYCODES = { 16: true, 17: true, 18: true },
- SPECIAL_KEYCODES = {
- 8: "backspace", 9: "tab", 10: "return", 13: "return",
- // 16: null, 17: null, 18: null, // ignore shift, ctrl, alt
- 19: "pause", 20: "capslock", 27: "esc", 32: "space", 33: "pageup",
- 34: "pagedown", 35: "end", 36: "home", 37: "left", 38: "up",
- 39: "right", 40: "down", 45: "insert", 46: "del", 59: ";", 61: "=",
- 96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6",
- 103: "7", 104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".",
- 111: "/", 112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5",
- 117: "f6", 118: "f7", 119: "f8", 120: "f9", 121: "f10", 122: "f11",
- 123: "f12", 144: "numlock", 145: "scroll", 173: "-", 186: ";", 187: "=",
- 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
- 221: "]", 222: "'"},
- MOUSE_BUTTONS = { 0: "", 1: "left", 2: "middle", 3: "right" },
- // Boolean attributes that can be set with equivalent class names in the LI tags
- // Note: v2.23: checkbox and hideCheckbox are *not* in this list
- CLASS_ATTRS = "active expanded focus folder lazy radiogroup selected unselectable unselectableIgnore".split(" "),
- CLASS_ATTR_MAP = {},
- // Top-level Fancytree node attributes, that can be set by dict
- NODE_ATTRS = "checkbox expanded extraClasses folder icon key lazy radiogroup refKey selected statusNodeType title tooltip unselectable unselectableIgnore unselectableStatus".split(" "),
- NODE_ATTR_MAP = {},
- // Mapping of lowercase -> real name (because HTML5 data-... attribute only supports lowercase)
- NODE_ATTR_LOWERCASE_MAP = {},
- // Attribute names that should NOT be added to node.data
- NONE_NODE_DATA_MAP = {"active": true, "children": true, "data": true, "focus": true};
-
-for(i=0; i t );
- }
- }
- return true;
-}
-
-/** Return a wrapper that calls sub.methodName() and exposes
- * this : tree
- * this._local : tree.ext.EXTNAME
- * this._super : base.methodName.call()
- * this._superApply : base.methodName.apply()
- */
-function _makeVirtualFunction(methodName, tree, base, extension, extName){
- // $.ui.fancytree.debug("_makeVirtualFunction", methodName, tree, base, extension, extName);
- // if(rexTestSuper && !rexTestSuper.test(func)){
- // // extension.methodName() doesn't call _super(), so no wrapper required
- // return func;
- // }
- // Use an immediate function as closure
- var proxy = (function(){
- var prevFunc = tree[methodName], // org. tree method or prev. proxy
- baseFunc = extension[methodName], //
- _local = tree.ext[extName],
- _super = function(){
- return prevFunc.apply(tree, arguments);
- },
- _superApply = function(args){
- return prevFunc.apply(tree, args);
- };
-
- // Return the wrapper function
- return function(){
- var prevLocal = tree._local,
- prevSuper = tree._super,
- prevSuperApply = tree._superApply;
-
- try{
- tree._local = _local;
- tree._super = _super;
- tree._superApply = _superApply;
- return baseFunc.apply(tree, arguments);
- }finally{
- tree._local = prevLocal;
- tree._super = prevSuper;
- tree._superApply = prevSuperApply;
- }
- };
- })(); // end of Immediate Function
- return proxy;
-}
-
-/**
- * Subclass `base` by creating proxy functions
- */
-function _subclassObject(tree, base, extension, extName){
- // $.ui.fancytree.debug("_subclassObject", tree, base, extension, extName);
- for(var attrName in extension){
- if(typeof extension[attrName] === "function"){
- if(typeof tree[attrName] === "function"){
- // override existing method
- tree[attrName] = _makeVirtualFunction(attrName, tree, base, extension, extName);
- }else if(attrName.charAt(0) === "_"){
- // Create private methods in tree.ext.EXTENSION namespace
- tree.ext[extName][attrName] = _makeVirtualFunction(attrName, tree, base, extension, extName);
- }else{
- $.error("Could not override tree." + attrName + ". Use prefix '_' to create tree." + extName + "._" + attrName);
- }
- }else{
- // Create member variables in tree.ext.EXTENSION namespace
- if(attrName !== "options"){
- tree.ext[extName][attrName] = extension[attrName];
- }
- }
- }
-}
-
-
-function _getResolvedPromise(context, argArray){
- if(context === undefined){
- return $.Deferred(function(){this.resolve();}).promise();
- }else{
- return $.Deferred(function(){this.resolveWith(context, argArray);}).promise();
- }
-}
-
-
-function _getRejectedPromise(context, argArray){
- if(context === undefined){
- return $.Deferred(function(){this.reject();}).promise();
- }else{
- return $.Deferred(function(){this.rejectWith(context, argArray);}).promise();
- }
-}
-
-
-function _makeResolveFunc(deferred, context){
- return function(){
- deferred.resolveWith(context);
- };
-}
-
-
-function _getElementDataAsDict($el){
- // Evaluate 'data-NAME' attributes with special treatment for 'data-json'.
- var d = $.extend({}, $el.data()),
- json = d.json;
-
- delete d.fancytree; // added to container by widget factory (old jQuery UI)
- delete d.uiFancytree; // added to container by widget factory
-
- if( json ) {
- delete d.json;
- //
is already returned as object (http://api.jquery.com/data/#data-html5)
- d = $.extend(d, json);
- }
- return d;
-}
-
-
-function _escapeHtml(s){
- return ("" + s).replace(REX_HTML, function(s) {
- return ENTITY_MAP[s];
- });
-}
-
-
-function _escapeTooltip(s){
- return ("" + s).replace(REX_TOOLTIP, function(s) {
- return ENTITY_MAP[s];
- });
-}
-
-
-// TODO: use currying
-function _makeNodeTitleMatcher(s){
- s = s.toLowerCase();
- return function(node){
- return node.title.toLowerCase().indexOf(s) >= 0;
- };
-}
-
-
-function _makeNodeTitleStartMatcher(s){
- var reMatch = new RegExp("^" + s, "i");
- return function(node){
- return reMatch.test(node.title);
- };
-}
-
-
-/* *****************************************************************************
- * FancytreeNode
- */
-
-
-/**
- * Creates a new FancytreeNode
- *
- * @class FancytreeNode
- * @classdesc A FancytreeNode represents the hierarchical data model and operations.
- *
- * @param {FancytreeNode} parent
- * @param {NodeData} obj
- *
- * @property {Fancytree} tree The tree instance
- * @property {FancytreeNode} parent The parent node
- * @property {string} key Node id (must be unique inside the tree)
- * @property {string} title Display name (may contain HTML)
- * @property {object} data Contains all extra data that was passed on node creation
- * @property {FancytreeNode[] | null | undefined} children Array of child nodes.
- * For lazy nodes, null or undefined means 'not yet loaded'. Use an empty array
- * to define a node that has no children.
- * @property {boolean} expanded Use isExpanded(), setExpanded() to access this property.
- * @property {string} extraClasses Additional CSS classes, added to the node's `<span>`.
- * Note: use `node.add/remove/toggleClass()` to modify.
- * @property {boolean} folder Folder nodes have different default icons and click behavior.
- * Note: Also non-folders may have children.
- * @property {string} statusNodeType null for standard nodes. Otherwise type of special system node: 'error', 'loading', 'nodata', or 'paging'.
- * @property {boolean} lazy True if this node is loaded on demand, i.e. on first expansion.
- * @property {boolean} selected Use isSelected(), setSelected() to access this property.
- * @property {string} tooltip Alternative description used as hover popup
- */
-function FancytreeNode(parent, obj){
- var i, l, name, cl;
-
- this.parent = parent;
- this.tree = parent.tree;
- this.ul = null;
- this.li = null; //
tag
- this.statusNodeType = null; // if this is a temp. node to display the status of its parent
- this._isLoading = false; // if this node itself is loading
- this._error = null; // {message: '...'} if a load error occurred
- this.data = {};
-
- // TODO: merge this code with node.toDict()
- // copy attributes from obj object
- for(i=0, l=NODE_ATTRS.length; i= 0, "insertBefore must be an existing child");
- // insert nodeList after children[pos]
- this.children.splice.apply(this.children, [pos, 0].concat(nodeList));
- }
- if ( origFirstChild && !insertBefore ) {
- // #708: Fast path -- don't render every child of root, just the new ones!
- // #723, #729: but only if it's appended to an existing child list
- for(i=0, l=nodeList.length; i= 0; i--) {
- n = this.children[i];
- if( n.statusNodeType === "paging" ) {
- this.removeChild(n);
- }
- }
- this.partload = false;
- return;
- }
- node = $.extend({
- title: this.tree.options.strings.moreData,
- statusNodeType: "paging",
- icon: false
- }, node);
- this.partload = true;
- return this.addNode(node, mode);
- },
- /**
- * Append new node after this.
- *
- * This a convenience function that calls addNode(node, 'after')
- *
- * @param {NodeData} node node definition
- * @returns {FancytreeNode} new node
- */
- appendSibling: function(node){
- return this.addNode(node, "after");
- },
- /**
- * Modify existing child nodes.
- *
- * @param {NodePatch} patch
- * @returns {$.Promise}
- * @see FancytreeNode#addChildren
- */
- applyPatch: function(patch) {
- // patch [key, null] means 'remove'
- if(patch === null){
- this.remove();
- return _getResolvedPromise(this);
- }
- // TODO: make sure that root node is not collapsed or modified
- // copy (most) attributes to node.ATTR or node.data.ATTR
- var name, promise, v,
- IGNORE_MAP = { children: true, expanded: true, parent: true }; // TODO: should be global
-
- for(name in patch){
- v = patch[name];
- if( !IGNORE_MAP[name] && !$.isFunction(v)){
- if(NODE_ATTR_MAP[name]){
- this[name] = v;
- }else{
- this.data[name] = v;
- }
- }
- }
- // Remove and/or create children
- if(patch.hasOwnProperty("children")){
- this.removeChildren();
- if(patch.children){ // only if not null and not empty list
- // TODO: addChildren instead?
- this._setChildren(patch.children);
- }
- // TODO: how can we APPEND or INSERT child nodes?
- }
- if(this.isVisible()){
- this.renderTitle();
- this.renderStatus();
- }
- // Expand collapse (final step, since this may be async)
- if(patch.hasOwnProperty("expanded")){
- promise = this.setExpanded(patch.expanded);
- }else{
- promise = _getResolvedPromise(this);
- }
- return promise;
- },
- /** Collapse all sibling nodes.
- * @returns {$.Promise}
- */
- collapseSiblings: function() {
- return this.tree._callHook("nodeCollapseSiblings", this);
- },
- /** Copy this node as sibling or child of `node`.
- *
- * @param {FancytreeNode} node source node
- * @param {string} [mode=child] 'before' | 'after' | 'child'
- * @param {Function} [map] callback function(NodeData) that could modify the new node
- * @returns {FancytreeNode} new
- */
- copyTo: function(node, mode, map) {
- return node.addNode(this.toDict(true, map), mode);
- },
- /** Count direct and indirect children.
- *
- * @param {boolean} [deep=true] pass 'false' to only count direct children
- * @returns {int} number of child nodes
- */
- countChildren: function(deep) {
- var cl = this.children, i, l, n;
- if( !cl ){
- return 0;
- }
- n = cl.length;
- if(deep !== false){
- for(i=0, l=n; i= 2 (prepending node info)
- *
- * @param {*} msg string or object or array of such
- */
- debug: function(msg){
- if( this.tree.options.debugLevel >= 2 ) {
- Array.prototype.unshift.call(arguments, this.toString());
- consoleApply("log", arguments);
- }
- },
- /** Deprecated.
- * @deprecated since 2014-02-16. Use resetLazy() instead.
- */
- discard: function(){
- this.warn("FancytreeNode.discard() is deprecated since 2014-02-16. Use .resetLazy() instead.");
- return this.resetLazy();
- },
- /** Remove DOM elements for all descendents. May be called on .collapse event
- * to keep the DOM small.
- * @param {boolean} [includeSelf=false]
- */
- discardMarkup: function(includeSelf){
- var fn = includeSelf ? "nodeRemoveMarkup" : "nodeRemoveChildMarkup";
- this.tree._callHook(fn, this);
- },
- /**Find all nodes that match condition (excluding self).
- *
- * @param {string | function(node)} match title string to search for, or a
- * callback function that returns `true` if a node is matched.
- * @returns {FancytreeNode[]} array of nodes (may be empty)
- */
- findAll: function(match) {
- match = $.isFunction(match) ? match : _makeNodeTitleMatcher(match);
- var res = [];
- this.visit(function(n){
- if(match(n)){
- res.push(n);
- }
- });
- return res;
- },
- /**Find first node that matches condition (excluding self).
- *
- * @param {string | function(node)} match title string to search for, or a
- * callback function that returns `true` if a node is matched.
- * @returns {FancytreeNode} matching node or null
- * @see FancytreeNode#findAll
- */
- findFirst: function(match) {
- match = $.isFunction(match) ? match : _makeNodeTitleMatcher(match);
- var res = null;
- this.visit(function(n){
- if(match(n)){
- res = n;
- return false;
- }
- });
- return res;
- },
- /* Apply selection state (internal use only) */
- _changeSelectStatusAttrs: function(state) {
- var changed = false,
- opts = this.tree.options,
- unselectable = FT.evalOption("unselectable", this, this, opts, false),
- unselectableStatus = FT.evalOption("unselectableStatus", this, this, opts, undefined);
-
- if( unselectable && unselectableStatus != null ) {
- state = unselectableStatus;
- }
- switch(state){
- case false:
- changed = ( this.selected || this.partsel );
- this.selected = false;
- this.partsel = false;
- break;
- case true:
- changed = ( !this.selected || !this.partsel );
- this.selected = true;
- this.partsel = true;
- break;
- case undefined:
- changed = ( this.selected || !this.partsel );
- this.selected = false;
- this.partsel = true;
- break;
- default:
- _assert(false, "invalid state: " + state);
- }
- // this.debug("fixSelection3AfterLoad() _changeSelectStatusAttrs()", state, changed);
- if( changed ){
- this.renderStatus();
- }
- return changed;
- },
- /**
- * Fix selection status, after this node was (de)selected in multi-hier mode.
- * This includes (de)selecting all children.
- */
- fixSelection3AfterClick: function(callOpts) {
- var flag = this.isSelected();
-
-// this.debug("fixSelection3AfterClick()");
-
- this.visit(function(node){
- node._changeSelectStatusAttrs(flag);
- });
- this.fixSelection3FromEndNodes(callOpts);
- },
- /**
- * Fix selection status for multi-hier mode.
- * Only end-nodes are considered to update the descendants branch and parents.
- * Should be called after this node has loaded new children or after
- * children have been modified using the API.
- */
- fixSelection3FromEndNodes: function(callOpts) {
- var opts = this.tree.options;
-
-// this.debug("fixSelection3FromEndNodes()");
- _assert(opts.selectMode === 3, "expected selectMode 3");
-
- // Visit all end nodes and adjust their parent's `selected` and `partsel`
- // attributes. Return selection state true, false, or undefined.
- function _walk(node){
- var i, l, child, s, state, allSelected, someSelected, unselIgnore, unselState,
- children = node.children;
-
- if( children && children.length ){
- // check all children recursively
- allSelected = true;
- someSelected = false;
-
- for( i=0, l=children.length; i= 1 (prepending node info)
- *
- * @param {*} msg string or object or array of such
- */
- info: function(msg){
- if( this.tree.options.debugLevel >= 1 ) {
- Array.prototype.unshift.call(arguments, this.toString());
- consoleApply("info", arguments);
- }
- },
- /** Return true if node is active (see also FancytreeNode#isSelected).
- * @returns {boolean}
- */
- isActive: function() {
- return (this.tree.activeNode === this);
- },
- /** Return true if node is a direct child of otherNode.
- * @param {FancytreeNode} otherNode
- * @returns {boolean}
- */
- isChildOf: function(otherNode) {
- return (this.parent && this.parent === otherNode);
- },
- /** Return true, if node is a direct or indirect sub node of otherNode.
- * @param {FancytreeNode} otherNode
- * @returns {boolean}
- */
- isDescendantOf: function(otherNode) {
- if(!otherNode || otherNode.tree !== this.tree){
- return false;
- }
- var p = this.parent;
- while( p ) {
- if( p === otherNode ){
- return true;
- }
- p = p.parent;
- }
- return false;
- },
- /** Return true if node is expanded.
- * @returns {boolean}
- */
- isExpanded: function() {
- return !!this.expanded;
- },
- /** Return true if node is the first node of its parent's children.
- * @returns {boolean}
- */
- isFirstSibling: function() {
- var p = this.parent;
- return !p || p.children[0] === this;
- },
- /** Return true if node is a folder, i.e. has the node.folder attribute set.
- * @returns {boolean}
- */
- isFolder: function() {
- return !!this.folder;
- },
- /** Return true if node is the last node of its parent's children.
- * @returns {boolean}
- */
- isLastSibling: function() {
- var p = this.parent;
- return !p || p.children[p.children.length-1] === this;
- },
- /** Return true if node is lazy (even if data was already loaded)
- * @returns {boolean}
- */
- isLazy: function() {
- return !!this.lazy;
- },
- /** Return true if node is lazy and loaded. For non-lazy nodes always return true.
- * @returns {boolean}
- */
- isLoaded: function() {
- return !this.lazy || this.hasChildren() !== undefined; // Also checks if the only child is a status node
- },
- /** Return true if children are currently beeing loaded, i.e. a Ajax request is pending.
- * @returns {boolean}
- */
- isLoading: function() {
- return !!this._isLoading;
- },
- /*
- * @deprecated since v2.4.0: Use isRootNode() instead
- */
- isRoot: function() {
- return this.isRootNode();
- },
- /** Return true if node is partially selected (tri-state).
- * @returns {boolean}
- * @since 2.23
- */
- isPartsel: function() {
- return !this.selected && !!this.partsel;
- },
- /** (experimental) Return true if this is partially loaded.
- * @returns {boolean}
- * @since 2.15
- */
- isPartload: function() {
- return !!this.partload;
- },
- /** Return true if this is the (invisible) system root node.
- * @returns {boolean}
- * @since 2.4
- */
- isRootNode: function() {
- return (this.tree.rootNode === this);
- },
- /** Return true if node is selected, i.e. has a checkmark set (see also FancytreeNode#isActive).
- * @returns {boolean}
- */
- isSelected: function() {
- return !!this.selected;
- },
- /** Return true if this node is a temporarily generated system node like
- * 'loading', 'paging', or 'error' (node.statusNodeType contains the type).
- * @returns {boolean}
- */
- isStatusNode: function() {
- return !!this.statusNodeType;
- },
- /** Return true if this node is a status node of type 'paging'.
- * @returns {boolean}
- * @since 2.15
- */
- isPagingNode: function() {
- return this.statusNodeType === "paging";
- },
- /** Return true if this a top level node, i.e. a direct child of the (invisible) system root node.
- * @returns {boolean}
- * @since 2.4
- */
- isTopLevel: function() {
- return (this.tree.rootNode === this.parent);
- },
- /** Return true if node is lazy and not yet loaded. For non-lazy nodes always return false.
- * @returns {boolean}
- */
- isUndefined: function() {
- return this.hasChildren() === undefined; // also checks if the only child is a status node
- },
- /** Return true if all parent nodes are expanded. Note: this does not check
- * whether the node is scrolled into the visible part of the screen.
- * @returns {boolean}
- */
- isVisible: function() {
- var i, l,
- parents = this.getParentList(false, false);
-
- for(i=0, l=parents.length; iexpanded state is maintained.
- * @param {boolean} [forceReload=false] Pass true to discard any existing nodes before. Otherwise this method does nothing if the node was already loaded.
- * @returns {$.Promise}
- */
- load: function(forceReload) {
- var res, source,
- that = this,
- wasExpanded = this.isExpanded();
-
- _assert( this.isLazy(), "load() requires a lazy node" );
- // _assert( forceReload || this.isUndefined(), "Pass forceReload=true to re-load a lazy node" );
- if( !forceReload && !this.isUndefined() ) {
- return _getResolvedPromise(this);
- }
- if( this.isLoaded() ){
- this.resetLazy(); // also collapses
- }
- // This method is also called by setExpanded() and loadKeyPath(), so we
- // have to avoid recursion.
- source = this.tree._triggerNodeEvent("lazyLoad", this);
- if( source === false ) { // #69
- return _getResolvedPromise(this);
- }
- _assert(typeof source !== "boolean", "lazyLoad event must return source in data.result");
- res = this.tree._callHook("nodeLoadChildren", this, source);
- if( wasExpanded ) {
- this.expanded = true;
- res.always(function(){
- that.render();
- });
- } else {
- res.always(function(){
- that.renderStatus(); // fix expander icon to 'loaded'
- });
- }
- return res;
- },
- /** Expand all parents and optionally scroll into visible area as neccessary.
- * Promise is resolved, when lazy loading and animations are done.
- * @param {object} [opts] passed to `setExpanded()`.
- * Defaults to {noAnimation: false, noEvents: false, scrollIntoView: true}
- * @returns {$.Promise}
- */
- makeVisible: function(opts) {
- var i,
- that = this,
- deferreds = [],
- dfd = new $.Deferred(),
- parents = this.getParentList(false, false),
- len = parents.length,
- effects = !(opts && opts.noAnimation === true),
- scroll = !(opts && opts.scrollIntoView === false);
-
- // Expand bottom-up, so only the top node is animated
- for(i = len - 1; i >= 0; i--){
- // that.debug("pushexpand" + parents[i]);
- deferreds.push(parents[i].setExpanded(true, opts));
- }
- $.when.apply($, deferreds).done(function(){
- // All expands have finished
- // that.debug("expand DONE", scroll);
- if( scroll ){
- that.scrollIntoView(effects).done(function(){
- // that.debug("scroll DONE");
- dfd.resolve();
- });
- } else {
- dfd.resolve();
- }
- });
- return dfd.promise();
- },
- /** Move this node to targetNode.
- * @param {FancytreeNode} targetNode
- * @param {string} mode
- * 'child': append this node as last child of targetNode.
- * This is the default. To be compatble with the D'n'd
- * hitMode, we also accept 'over'.
- * 'firstChild': add this node as first child of targetNode.
- * 'before': add this node as sibling before targetNode.
- * 'after': add this node as sibling after targetNode.
tag yet:
-// if( !targetParent.ul ) {
-// // This is the parent's first child: create UL tag
-// // (Hidden, because it will be
-// targetParent.ul = document.createElement("ul");
-// targetParent.ul.style.display = "none";
-// targetParent.li.appendChild(targetParent.ul);
-// }
-// // Issue 319: Add to target DOM parent (only if node was already rendered(expanded))
-// if(this.li){
-// targetParent.ul.appendChild(this.li);
-// }^
-
- // Let caller modify the nodes
- if( map ){
- targetNode.visit(map, true);
- }
- if( targetParent === prevParent ) {
- targetParent.triggerModifyChild("move", this);
- } else {
- // prevParent.triggerModifyChild("remove", this);
- targetParent.triggerModifyChild("add", this);
- }
- // Handle cross-tree moves
- if( this.tree !== targetNode.tree ) {
- // Fix node.tree for all source nodes
-// _assert(false, "Cross-tree move is not yet implemented.");
- this.warn("Cross-tree moveTo is experimantal!");
- this.visit(function(n){
- // TODO: fix selection state and activation, ...
- n.tree = targetNode.tree;
- }, true);
- }
-
- // A collaposed node won't re-render children, so we have to remove it manually
- // if( !targetParent.expanded ){
- // prevParent.ul.removeChild(this.li);
- // }
-
- // Update HTML markup
- if( !prevParent.isDescendantOf(targetParent)) {
- prevParent.render();
- }
- if( !targetParent.isDescendantOf(prevParent) && targetParent !== prevParent) {
- targetParent.render();
- }
- // TODO: fix selection state
- // TODO: fix active state
-
-/*
- var tree = this.tree;
- var opts = tree.options;
- var pers = tree.persistence;
-
-
- // Always expand, if it's below minExpandLevel
-// tree.logDebug ("%s._addChildNode(%o), l=%o", this, ftnode, ftnode.getLevel());
- if ( opts.minExpandLevel >= ftnode.getLevel() ) {
-// tree.logDebug ("Force expand for %o", ftnode);
- this.bExpanded = true;
- }
-
- // In multi-hier mode, update the parents selection state
- // DT issue #82: only if not initializing, because the children may not exist yet
-// if( !ftnode.data.isStatusNode() && opts.selectMode==3 && !isInitializing )
-// ftnode._fixSelectionState();
-
- // In multi-hier mode, update the parents selection state
- if( ftnode.bSelected && opts.selectMode==3 ) {
- var p = this;
- while( p ) {
- if( !p.hasSubSel )
- p._setSubSel(true);
- p = p.parent;
- }
- }
- // render this node and the new child
- if ( tree.bEnableUpdate )
- this.render();
-
- return ftnode;
-
-*/
- },
- /** Set focus relative to this node and optionally activate.
- *
- * @param {number} where The keyCode that would normally trigger this move,
- * e.g. `$.ui.keyCode.LEFT` would collapse the node if it
- * is expanded or move to the parent oterwise.
- * @param {boolean} [activate=true]
- * @returns {$.Promise}
- */
- navigate: function(where, activate) {
- var i, parents, res,
- handled = true,
- KC = $.ui.keyCode,
- sib = null;
-
- // Navigate to node
- function _goto(n){
- if( n ){
- // setFocus/setActive will scroll later (if autoScroll is specified)
- try { n.makeVisible({scrollIntoView: false}); } catch(e) {} // #272
- // Node may still be hidden by a filter
- if( ! $(n.span).is(":visible") ) {
- n.debug("Navigate: skipping hidden node");
- n.navigate(where, activate);
- return;
- }
- return activate === false ? n.setFocus() : n.setActive();
- }
- }
-
- switch( where ) {
- case KC.BACKSPACE:
- if( this.parent && this.parent.parent ) {
- res = _goto(this.parent);
- }
- break;
- case KC.HOME:
- this.tree.visit(function(n){ // goto first visible node
- if( $(n.span).is(":visible") ) {
- res = _goto(n);
- return false;
- }
- });
- break;
- case KC.END:
- this.tree.visit(function(n){ // goto last visible node
- if( $(n.span).is(":visible") ) {
- res = n;
- }
- });
- if( res ) {
- res = _goto(res);
- }
- break;
- case KC.LEFT:
- if( this.expanded ) {
- this.setExpanded(false);
- res = _goto(this);
- } else if( this.parent && this.parent.parent ) {
- res = _goto(this.parent);
- }
- break;
- case KC.RIGHT:
- if( !this.expanded && (this.children || this.lazy) ) {
- this.setExpanded();
- res = _goto(this);
- } else if( this.children && this.children.length ) {
- res = _goto(this.children[0]);
- }
- break;
- case KC.UP:
- sib = this.getPrevSibling();
- // #359: skip hidden sibling nodes, preventing a _goto() recursion
- while( sib && !$(sib.span).is(":visible") ) {
- sib = sib.getPrevSibling();
- }
- while( sib && sib.expanded && sib.children && sib.children.length ) {
- sib = sib.children[sib.children.length - 1];
- }
- if( !sib && this.parent && this.parent.parent ){
- sib = this.parent;
- }
- res = _goto(sib);
- break;
- case KC.DOWN:
- if( this.expanded && this.children && this.children.length ) {
- sib = this.children[0];
- } else {
- parents = this.getParentList(false, true);
- for(i=parents.length-1; i>=0; i--) {
- sib = parents[i].getNextSibling();
- // #359: skip hidden sibling nodes, preventing a _goto() recursion
- while( sib && !$(sib.span).is(":visible") ) {
- sib = sib.getNextSibling();
- }
- if( sib ){ break; }
- }
- }
- res = _goto(sib);
- break;
- default:
- handled = false;
- }
- return res || _getResolvedPromise();
- },
- /**
- * Remove this node (not allowed for system root).
- */
- remove: function() {
- return this.parent.removeChild(this);
- },
- /**
- * Remove childNode from list of direct children.
- * @param {FancytreeNode} childNode
- */
- removeChild: function(childNode) {
- return this.tree._callHook("nodeRemoveChild", this, childNode);
- },
- /**
- * Remove all child nodes and descendents. This converts the node into a leaf.
- * If this was a lazy node, it is still considered 'loaded'; call node.resetLazy()
- * in order to trigger lazyLoad on next expand.
- */
- removeChildren: function() {
- return this.tree._callHook("nodeRemoveChildren", this);
- },
- /**
- * Remove class from node's span tag and .extraClasses.
- *
- * @param {string} className class name
- *
- * @since 2.17
- */
- removeClass: function(className){
- return this.toggleClass(className, false);
- },
- /**
- * This method renders and updates all HTML markup that is required
- * to display this node in its current state.
- * Note:
- *
- *
It should only be neccessary to call this method after the node object
- * was modified by direct access to its properties, because the common
- * API methods (node.setTitle(), moveTo(), addChildren(), remove(), ...)
- * already handle this.
- *
{@link FancytreeNode#renderTitle} and {@link FancytreeNode#renderStatus}
- * are implied. If changes are more local, calling only renderTitle() or
- * renderStatus() may be sufficient and faster.
- *
- *
- * @param {boolean} [force=false] re-render, even if html markup was already created
- * @param {boolean} [deep=false] also render all descendants, even if parent is collapsed
- */
- render: function(force, deep) {
- return this.tree._callHook("nodeRender", this, force, deep);
- },
- /** Create HTML markup for the node's outer <span> (expander, checkbox, icon, and title).
- * Implies {@link FancytreeNode#renderStatus}.
- * @see Fancytree_Hooks#nodeRenderTitle
- */
- renderTitle: function() {
- return this.tree._callHook("nodeRenderTitle", this);
- },
- /** Update element's CSS classes according to node state.
- * @see Fancytree_Hooks#nodeRenderStatus
- */
- renderStatus: function() {
- return this.tree._callHook("nodeRenderStatus", this);
- },
- /**
- * (experimental) Replace this node with `source`.
- * (Currently only available for paging nodes.)
- * @param {NodeData[]} source List of child node definitions
- * @since 2.15
- */
- replaceWith: function(source) {
- var res,
- parent = this.parent,
- pos = $.inArray(this, parent.children),
- that = this;
-
- _assert( this.isPagingNode(), "replaceWith() currently requires a paging status node" );
-
- res = this.tree._callHook("nodeLoadChildren", this, source);
- res.done(function(data){
- // New nodes are currently children of `this`.
- var children = that.children;
- // Prepend newly loaded child nodes to `this`
- // Move new children after self
- for( i=0; i y ? 1 : -1;
- };
- cl.sort(cmp);
- if( deep ){
- for(i=0, l=cl.length; i= 0;
- flag = (flag === undefined) ? (!hasClass) : !!flag;
- if ( flag ) {
- if( !hasClass ) {
- curClasses += className + " ";
- wasAdded = true;
- }
- } else {
- while ( curClasses.indexOf( " " + className + " " ) > -1 ) {
- curClasses = curClasses.replace( " " + className + " ", " " );
- }
- }
- }
- this.extraClasses = $.trim(curClasses);
- // this.info("-> toggleClass('" + value + "', " + flag + "): '" + this.extraClasses + "'");
- return wasAdded;
- },
- /** Flip expanded status. */
- toggleExpanded: function(){
- return this.tree._callHook("nodeToggleExpanded", this);
- },
- /** Flip selection status. */
- toggleSelected: function(){
- return this.tree._callHook("nodeToggleSelected", this);
- },
- toString: function() {
- return "";
- },
- /**
- * Trigger `modifyChild` event on a parent to signal that a child was modified.
- * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ...
- * @param {FancytreeNode} [childNode]
- * @param {object} [extra]
- */
- triggerModifyChild: function(operation, childNode, extra){
- var data,
- modifyChild = this.tree.options.modifyChild;
-
- if ( modifyChild ){
- if( childNode && childNode.parent !== this ) {
- $.error("childNode " + childNode + " is not a child of " + this);
- }
- data = {
- node: this,
- tree: this.tree,
- operation: operation,
- childNode: childNode || null
- };
- if( extra ) {
- $.extend(data, extra);
- }
- modifyChild({type: "modifyChild"}, data);
- }
- },
- /**
- * Trigger `modifyChild` event on node.parent(!).
- * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ...
- * @param {object} [extra]
- */
- triggerModify: function(operation, extra){
- this.parent.triggerModifyChild(operation, this, extra);
- },
- /** Call fn(node) for all child nodes.
- * Stop iteration, if fn() returns false. Skip current branch, if fn() returns "skip".
- * Return false if iteration was stopped.
- *
- * @param {function} fn the callback function.
- * Return false to stop iteration, return "skip" to skip this node and
- * its children only.
- * @param {boolean} [includeSelf=false]
- * @returns {boolean}
- */
- visit: function(fn, includeSelf) {
- var i, l,
- res = true,
- children = this.children;
-
- if( includeSelf === true ) {
- res = fn(this);
- if( res === false || res === "skip" ){
- return res;
- }
- }
- if(children){
- for(i=0, l=children.length; i
- * Note: If you need this method, you probably should consider to review
- * your architecture! Recursivley loading nodes is a perfect way for lazy
- * programmers to flood the server with requests ;-)
- *
- * @param {function} [fn] optional callback function.
- * Return false to stop iteration, return "skip" to skip this node and
- * its children only.
- * @param {boolean} [includeSelf=false]
- * @returns {$.Promise}
- * @since 2.4
- */
- visitAndLoad: function(fn, includeSelf, _recursion) {
- var dfd, res, loaders,
- node = this;
-
- // node.debug("visitAndLoad");
- if( fn && includeSelf === true ) {
- res = fn(node);
- if( res === false || res === "skip" ) {
- return _recursion ? res : _getResolvedPromise();
- }
- }
- if( !node.children && !node.lazy ) {
- return _getResolvedPromise();
- }
- dfd = new $.Deferred();
- loaders = [];
- // node.debug("load()...");
- node.load().done(function(){
- // node.debug("load()... done.");
- for(var i=0, l=node.children.length; i
- * Stop iteration, if fn() returns false.
- * Return false if iteration was stopped.
- *
- * @param {function} fn the callback function.
- * Return false to stop iteration, return "skip" to skip this node and children only.
- * @param {boolean} [includeSelf=false]
- * @returns {boolean}
- */
- visitParents: function(fn, includeSelf) {
- // Visit parent nodes (bottom up)
- if(includeSelf && fn(this) === false){
- return false;
- }
- var p = this.parent;
- while( p ) {
- if(fn(p) === false){
- return false;
- }
- p = p.parent;
- }
- return true;
- },
- /** Call fn(node) for all sibling nodes.
- * Stop iteration, if fn() returns false.
- * Return false if iteration was stopped.
- *
- * @param {function} fn the callback function.
- * Return false to stop iteration.
- * @param {boolean} [includeSelf=false]
- * @returns {boolean}
- */
- visitSiblings: function(fn, includeSelf) {
- var i, l, n,
- ac = this.parent.children;
-
- for (i=0, l=ac.length; i element (or <table> element for ext-table).
- * @property {jQueryObject} $div A jQuery object containing the element used to instantiate the tree widget (`widget.element`)
- * @property {object} data Metadata, i.e. properties that may be passed to `source` in addition to a children array.
- * @property {object} ext Hash of all active plugin instances.
- * @property {FancytreeNode} focusNode Currently focused node or null.
- * @property {FancytreeNode} lastSelectedNode Used to implement selectMode 1 (single select)
- * @property {string} nodeContainerAttrName Property name of FancytreeNode that contains the outer element of single nodes.
- * Typically "li", but "tr" for table extension.
- * @property {FancytreeOptions} options Current options, i.e. default options + options passed to constructor.
- * @property {FancytreeNode} rootNode Invisible system root node.
- * @property {string} statusClassPropName Property name of FancytreeNode that contains the element which will receive the status classes.
- * Typically "span", but "tr" for table extension.
- * @property {object} widget Base widget instance.
- */
-function Fancytree(widget) {
- this.widget = widget;
- this.$div = widget.element;
- this.options = widget.options;
- if( this.options ) {
- if( $.isFunction(this.options.lazyload ) && !$.isFunction(this.options.lazyLoad) ) {
- this.options.lazyLoad = function() {
- FT.warn("The 'lazyload' event is deprecated since 2014-02-25. Use 'lazyLoad' (with uppercase L) instead.");
- return widget.options.lazyload.apply(this, arguments);
- };
- }
- if( $.isFunction(this.options.loaderror) ) {
- $.error("The 'loaderror' event was renamed since 2014-07-03. Use 'loadError' (with uppercase E) instead.");
- }
- if( this.options.fx !== undefined ) {
- FT.warn("The 'fx' option was replaced by 'toggleEffect' since 2014-11-30.");
- }
- if( this.options.removeNode !== undefined ) {
- $.error("The 'removeNode' event was replaced by 'modifyChild' since 2.20 (2016-09-10).");
- }
- }
- this.ext = {}; // Active extension instances
- // allow to init tree.data.foo from
";
- }
- opts = sourceNode.tree.options.dnd;
- $nodeTag = $(sourceNode.span);
- // Only event and node argument is available
- $helper = $("
")
- .css({zIndex: 3, position: "relative"}) // so it appears above ext-wide selection bar
- .append($nodeTag.find("span.fancytree-title").clone());
-
- // Attach node reference to helper object
- $helper.data("ftSourceNode", sourceNode);
-
- // Support glyph symbols instead of icons
- if( glyph ) {
- $helper.find(".fancytree-drag-helper-img")
- .addClass(glyph.map.dragHelper);
- }
- // Allow to modify the helper, e.g. to add multi-node-drag feedback
- if( opts.initHelper ) {
- opts.initHelper.call(sourceNode.tree, sourceNode, {
- node: sourceNode,
- tree: sourceNode.tree,
- originalEvent: event,
- ui: { helper: $helper }
- });
- }
- // We return an unconnected element, so `draggable` will add this
- // to the parent specified as `appendTo` option
- return $helper;
- },
- start: function(event, ui) {
- var sourceNode = ui.helper.data("ftSourceNode");
- return !!sourceNode; // Abort dragging if no node could be found
- }
- }, tree.options.dnd.draggable));
- }
- // Attach ui.droppable to this Fancytree instance
- if(dnd && dnd.dragDrop) {
- tree.widget.element.droppable($.extend({
- addClasses: false,
- tolerance: "intersect",
- greedy: false
-/*
- activate: function(event, ui) {
- tree.debug("droppable - activate", event, ui, this);
- },
- create: function(event, ui) {
- tree.debug("droppable - create", event, ui);
- },
- deactivate: function(event, ui) {
- tree.debug("droppable - deactivate", event, ui);
- },
- drop: function(event, ui) {
- tree.debug("droppable - drop", event, ui);
- },
- out: function(event, ui) {
- tree.debug("droppable - out", event, ui);
- },
- over: function(event, ui) {
- tree.debug("droppable - over", event, ui);
- }
-*/
- }, tree.options.dnd.droppable));
- }
-}
-
-
-/* *****************************************************************************
- *
- */
-
-$.ui.fancytree.registerExtension({
- name: "dnd",
- version: "2.23.0",
- // Default options for this extension.
- options: {
- // Make tree nodes accept draggables
- autoExpandMS: 1000, // Expand nodes after n milliseconds of hovering.
- draggable: null, // Additional options passed to jQuery draggable
- droppable: null, // Additional options passed to jQuery droppable
- focusOnClick: false, // Focus, although draggable cancels mousedown event (#270)
- preventVoidMoves: true, // Prevent dropping nodes 'before self', etc.
- preventRecursiveMoves: true,// Prevent dropping nodes on own descendants
- smartRevert: true, // set draggable.revert = true if drop was rejected
- dropMarkerOffsetX: -24, // absolute position offset for .fancytree-drop-marker relatively to ..fancytree-title (icon/img near a node accepting drop)
- dropMarkerInsertOffsetX: -16, // additional offset for drop-marker with hitMode = "before"/"after"
- // Events (drag support)
- dragStart: null, // Callback(sourceNode, data), return true, to enable dnd
- dragStop: null, // Callback(sourceNode, data)
- initHelper: null, // Callback(sourceNode, data)
- updateHelper: null, // Callback(sourceNode, data)
- // Events (drop support)
- dragEnter: null, // Callback(targetNode, data)
- dragOver: null, // Callback(targetNode, data)
- dragExpand: null, // Callback(targetNode, data), return false to prevent autoExpand
- dragDrop: null, // Callback(targetNode, data)
- dragLeave: null // Callback(targetNode, data)
- },
-
- treeInit: function(ctx){
- var tree = ctx.tree;
- this._superApply(arguments);
- // issue #270: draggable eats mousedown events
- if( tree.options.dnd.dragStart ){
- tree.$container.on("mousedown", function(event){
-// if( !tree.hasFocus() && ctx.options.dnd.focusOnClick ) {
- if( ctx.options.dnd.focusOnClick ) { // #270
- var node = $.ui.fancytree.getNode(event);
- if (node){
- node.debug("Re-enable focus that was prevented by jQuery UI draggable.");
- // node.setFocus();
- // $(node.span).closest(":tabbable").focus();
- // $(event.target).trigger("focus");
- // $(event.target).closest(":tabbable").trigger("focus");
- }
- setTimeout(function() { // #300
- $(event.target).closest(":tabbable").focus();
- }, 10);
- }
- });
- }
- _initDragAndDrop(tree);
- },
- /* Display drop marker according to hitMode ('after', 'before', 'over'). */
- _setDndStatus: function(sourceNode, targetNode, helper, hitMode, accept) {
- var markerOffsetX,
- markerAt = "center",
- instData = this._local,
- dndOpt = this.options.dnd ,
- glyphOpt = this.options.glyph,
- $source = sourceNode ? $(sourceNode.span) : null,
- $target = $(targetNode.span),
- $targetTitle = $target.find("span.fancytree-title");
-
- if( !instData.$dropMarker ) {
- instData.$dropMarker = $("")
- .hide()
- .css({"z-index": 1000})
- .prependTo($(this.$div).parent());
-// .prependTo("body");
-
- if( glyphOpt ) {
- // instData.$dropMarker.addClass(glyph.map.dragHelper);
- instData.$dropMarker
- .addClass(glyphOpt.map.dropMarker);
- }
- }
- if( hitMode === "after" || hitMode === "before" || hitMode === "over" ){
- markerOffsetX = dndOpt.dropMarkerOffsetX || 0;
- switch(hitMode){
- case "before":
- markerAt = "top";
- markerOffsetX += (dndOpt.dropMarkerInsertOffsetX || 0);
- break;
- case "after":
- markerAt = "bottom";
- markerOffsetX += (dndOpt.dropMarkerInsertOffsetX || 0);
- break;
- }
-
- instData.$dropMarker
- .toggleClass(classDropAfter, hitMode === "after")
- .toggleClass(classDropOver, hitMode === "over")
- .toggleClass(classDropBefore, hitMode === "before")
- .show()
- .position($.ui.fancytree.fixPositionOptions({
- my: "left" + offsetString(markerOffsetX) + " center",
- at: "left " + markerAt,
- of: $targetTitle
- }));
- } else {
- instData.$dropMarker.hide();
- }
- if( $source ){
- $source
- .toggleClass(classDropAccept, accept === true)
- .toggleClass(classDropReject, accept === false);
- }
- $target
- .toggleClass(classDropTarget, hitMode === "after" || hitMode === "before" || hitMode === "over")
- .toggleClass(classDropAfter, hitMode === "after")
- .toggleClass(classDropBefore, hitMode === "before")
- .toggleClass(classDropAccept, accept === true)
- .toggleClass(classDropReject, accept === false);
-
- helper
- .toggleClass(classDropAccept, accept === true)
- .toggleClass(classDropReject, accept === false);
- },
-
- /*
- * Handles drag'n'drop functionality.
- *
- * A standard jQuery drag-and-drop process may generate these calls:
- *
- * start:
- * _onDragEvent("start", sourceNode, null, event, ui, draggable);
- * drag:
- * _onDragEvent("leave", prevTargetNode, sourceNode, event, ui, draggable);
- * _onDragEvent("over", targetNode, sourceNode, event, ui, draggable);
- * _onDragEvent("enter", targetNode, sourceNode, event, ui, draggable);
- * stop:
- * _onDragEvent("drop", targetNode, sourceNode, event, ui, draggable);
- * _onDragEvent("leave", targetNode, sourceNode, event, ui, draggable);
- * _onDragEvent("stop", sourceNode, null, event, ui, draggable);
- */
- _onDragEvent: function(eventName, node, otherNode, event, ui, draggable) {
- // if(eventName !== "over"){
- // this.debug("tree.ext.dnd._onDragEvent(%s, %o, %o) - %o", eventName, node, otherNode, this);
- // }
- var accept, nodeOfs, parentRect, rect, relPos, relPos2,
- enterResponse, hitMode, r,
- opts = this.options,
- dnd = opts.dnd,
- ctx = this._makeHookContext(node, event, {otherNode: otherNode, ui: ui, draggable: draggable}),
- res = null,
- that = this,
- $nodeTag = $(node.span);
-
- if( dnd.smartRevert ) {
- draggable.options.revert = "invalid";
- }
-
- switch (eventName) {
-
- case "start":
- if( node.isStatusNode() ) {
- res = false;
- } else if(dnd.dragStart) {
- res = dnd.dragStart(node, ctx);
- }
- if(res === false) {
- this.debug("tree.dragStart() cancelled");
- //draggable._clear();
- // NOTE: the return value seems to be ignored (drag is not cancelled, when false is returned)
- // TODO: call this._cancelDrag()?
- ui.helper.trigger("mouseup")
- .hide();
- } else {
- if( dnd.smartRevert ) {
- // #567, #593: fix revert position
- // rect = node.li.getBoundingClientRect();
- rect = node[ctx.tree.nodeContainerAttrName].getBoundingClientRect();
- parentRect = $(draggable.options.appendTo)[0].getBoundingClientRect();
- draggable.originalPosition.left = Math.max(0, rect.left - parentRect.left);
- draggable.originalPosition.top = Math.max(0, rect.top - parentRect.top);
- }
- $nodeTag.addClass("fancytree-drag-source");
- // Register global handlers to allow cancel
- $(document)
- .on("keydown.fancytree-dnd,mousedown.fancytree-dnd", function(event){
- // node.tree.debug("dnd global event", event.type, event.which);
- if( event.type === "keydown" && event.which === $.ui.keyCode.ESCAPE ) {
- that.ext.dnd._cancelDrag();
- } else if( event.type === "mousedown" ) {
- that.ext.dnd._cancelDrag();
- }
- });
- }
- break;
-
- case "enter":
- if(dnd.preventRecursiveMoves && node.isDescendantOf(otherNode)){
- r = false;
- }else{
- r = dnd.dragEnter ? dnd.dragEnter(node, ctx) : null;
- }
- if(!r){
- // convert null, undefined, false to false
- res = false;
- }else if ( $.isArray(r) ) {
- // TODO: also accept passing an object of this format directly
- res = {
- over: ($.inArray("over", r) >= 0),
- before: ($.inArray("before", r) >= 0),
- after: ($.inArray("after", r) >= 0)
- };
- }else{
- res = {
- over: ((r === true) || (r === "over")),
- before: ((r === true) || (r === "before")),
- after: ((r === true) || (r === "after"))
- };
- }
- ui.helper.data("enterResponse", res);
- // this.debug("helper.enterResponse: %o", res);
- break;
-
- case "over":
- enterResponse = ui.helper.data("enterResponse");
- hitMode = null;
- if(enterResponse === false){
- // Don't call dragOver if onEnter returned false.
-// break;
- } else if(typeof enterResponse === "string") {
- // Use hitMode from onEnter if provided.
- hitMode = enterResponse;
- } else {
- // Calculate hitMode from relative cursor position.
- nodeOfs = $nodeTag.offset();
- relPos = { x: event.pageX - nodeOfs.left,
- y: event.pageY - nodeOfs.top };
- relPos2 = { x: relPos.x / $nodeTag.width(),
- y: relPos.y / $nodeTag.height() };
-
- if( enterResponse.after && relPos2.y > 0.75 ){
- hitMode = "after";
- } else if(!enterResponse.over && enterResponse.after && relPos2.y > 0.5 ){
- hitMode = "after";
- } else if(enterResponse.before && relPos2.y <= 0.25) {
- hitMode = "before";
- } else if(!enterResponse.over && enterResponse.before && relPos2.y <= 0.5) {
- hitMode = "before";
- } else if(enterResponse.over) {
- hitMode = "over";
- }
- // Prevent no-ops like 'before source node'
- // TODO: these are no-ops when moving nodes, but not in copy mode
- if( dnd.preventVoidMoves ){
- if(node === otherNode){
- this.debug(" drop over source node prevented");
- hitMode = null;
- }else if(hitMode === "before" && otherNode && node === otherNode.getNextSibling()){
- this.debug(" drop after source node prevented");
- hitMode = null;
- }else if(hitMode === "after" && otherNode && node === otherNode.getPrevSibling()){
- this.debug(" drop before source node prevented");
- hitMode = null;
- }else if(hitMode === "over" && otherNode && otherNode.parent === node && otherNode.isLastSibling() ){
- this.debug(" drop last child over own parent prevented");
- hitMode = null;
- }
- }
-// this.debug("hitMode: %s - %s - %s", hitMode, (node.parent === otherNode), node.isLastSibling());
- ui.helper.data("hitMode", hitMode);
- }
- // Auto-expand node (only when 'over' the node, not 'before', or 'after')
- if(hitMode !== "before" && hitMode !== "after" && dnd.autoExpandMS &&
- node.hasChildren() !== false && !node.expanded &&
- (!dnd.dragExpand || dnd.dragExpand(node, ctx) !== false)
- ) {
- node.scheduleAction("expand", dnd.autoExpandMS);
- }
- if(hitMode && dnd.dragOver){
- // TODO: http://code.google.com/p/dynatree/source/detail?r=625
- ctx.hitMode = hitMode;
- res = dnd.dragOver(node, ctx);
- }
- accept = (res !== false && hitMode !== null);
- if( dnd.smartRevert ) {
- draggable.options.revert = !accept;
- }
- this._local._setDndStatus(otherNode, node, ui.helper, hitMode, accept);
- break;
-
- case "drop":
- hitMode = ui.helper.data("hitMode");
- if(hitMode && dnd.dragDrop){
- ctx.hitMode = hitMode;
- dnd.dragDrop(node, ctx);
- }
- break;
-
- case "leave":
- // Cancel pending expand request
- node.scheduleAction("cancel");
- ui.helper.data("enterResponse", null);
- ui.helper.data("hitMode", null);
- this._local._setDndStatus(otherNode, node, ui.helper, "out", undefined);
- if(dnd.dragLeave){
- dnd.dragLeave(node, ctx);
- }
- break;
-
- case "stop":
- $nodeTag.removeClass("fancytree-drag-source");
- $(document).off(".fancytree-dnd");
- if(dnd.dragStop){
- dnd.dragStop(node, ctx);
- }
- break;
-
- default:
- $.error("Unsupported drag event: " + eventName);
- }
- return res;
- },
-
- _cancelDrag: function() {
- var dd = $.ui.ddmanager.current;
- if(dd){
- dd.cancel();
- }
- }
-});
-}(jQuery, window, document));
-
-/*!
- * jquery.fancytree.dnd5.js
- *
- * Drag-and-drop support (native HTML5).
- * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
- *
- * Copyright (c) 2008-2017, Martin Wendt (http://wwWendt.de)
- *
- * Released under the MIT license
- * https://github.com/mar10/fancytree/wiki/LicenseInfo
- *
- * @version 2.23.0
- * @date 2017-05-27T20:09:38Z
- */
-
-
- /*
- #TODO
- - glyph
-
- Compatiblity when dragging between *separate* windows:
-
- Drag from Chrome Edge FF IE11 Safari
- To Chrome ok ok ok NO ?
- Edge ok ok ok NO ?
- FF ok ok ok NO ?
- IE 11 ok ok ok ok ?
- Safari ? ? ? ? ok
-
- */
-
-;(function($, window, document, undefined) {
-
-"use strict";
-
-/* *****************************************************************************
- * Private functions and variables
- */
-var
- classDragSource = "fancytree-drag-source",
- classDragRemove = "fancytree-drag-remove",
- classDropAccept = "fancytree-drop-accept",
- classDropAfter = "fancytree-drop-after",
- classDropBefore = "fancytree-drop-before",
- classDropOver = "fancytree-drop-over",
- classDropReject = "fancytree-drop-reject",
- classDropTarget = "fancytree-drop-target",
- nodeMimeType = "application/x-fancytree-node",
- $dropMarker = null,
- SOURCE_NODE = null,
- DRAG_ENTER_RESPONSE = null,
- LAST_HIT_MODE = null;
-
-/* Convert number to string and prepend +/-; return empty string for 0.*/
-function offsetString(n){
- return n === 0 ? "" : (( n > 0 ) ? ("+" + n) : ("" + n));
-}
-
-/* Convert a dragEnter() or dragOver() response to a canonical form.
- * Return false or plain object
- * @param {string|object|boolean} r
- * @return {object|false}
- */
-function normalizeDragEnterResponse(r) {
- var res;
-
- if( !r ){
- return false;
- }
- if ( $.isPlainObject(r) ) {
- res = {
- over: !!r.over,
- before: !!r.before,
- after: !!r.after
- };
- }else if ( $.isArray(r) ) {
- res = {
- over: ($.inArray("over", r) >= 0),
- before: ($.inArray("before", r) >= 0),
- after: ($.inArray("after", r) >= 0)
- };
- }else{
- res = {
- over: ((r === true) || (r === "over")),
- before: ((r === true) || (r === "before")),
- after: ((r === true) || (r === "after"))
- };
- }
- if( Object.keys(res).length === 0 ) {
- return false;
- }
- // if( Object.keys(res).length === 1 ) {
- // res.unique = res[0];
- // }
- return res;
-}
-
-/* Implement auto scrolling when drag cursor is in top/bottom area of scroll parent. */
-function autoScroll(tree, event) {
- var spOfs, scrollTop, delta,
- dndOpts = tree.options.dnd5,
- sp = tree.$scrollParent[0],
- sensitivity = dndOpts.scrollSensitivity,
- speed = dndOpts.scrollSpeed,
- scrolled = 0;
-
- if ( sp !== document && sp.tagName !== "HTML" ) {
- spOfs = tree.$scrollParent.offset();
- scrollTop = sp.scrollTop;
- if ( spOfs.top + sp.offsetHeight - event.pageY < sensitivity ) {
- delta = (sp.scrollHeight - tree.$scrollParent.innerHeight() - scrollTop);
- // console.log ("sp.offsetHeight: " + sp.offsetHeight
- // + ", spOfs.top: " + spOfs.top
- // + ", scrollTop: " + scrollTop
- // + ", innerHeight: " + tree.$scrollParent.innerHeight()
- // + ", scrollHeight: " + sp.scrollHeight
- // + ", delta: " + delta
- // );
- if( delta > 0 ) {
- sp.scrollTop = scrolled = scrollTop + speed;
- }
- } else if ( scrollTop > 0 && event.pageY - spOfs.top < sensitivity ) {
- sp.scrollTop = scrolled = scrollTop - speed;
- }
- } else {
- scrollTop = $(document).scrollTop();
- if (scrollTop > 0 && event.pageY - scrollTop < sensitivity) {
- scrolled = scrollTop - speed;
- $(document).scrollTop(scrolled);
- } else if ($(window).height() - (event.pageY - scrollTop) < sensitivity) {
- scrolled = scrollTop + speed;
- $(document).scrollTop(scrolled);
- }
- }
- if( scrolled ) {
- tree.debug("autoScroll: " + scrolled + "px");
- }
- return scrolled;
-}
-
-/* Handle dragover event (fired every x ms) and return hitMode. */
-function handleDragOver(event, data) {
- // Implement auto-scrolling
- if ( data.options.dnd5.scroll ) {
- autoScroll(data.tree, event);
- }
- // Bail out with previous response if we get an invalid dragover
- if( !data.node ) {
- data.tree.warn("Ignore dragover for non-node"); //, event, data);
- return LAST_HIT_MODE;
- }
-
- var markerOffsetX, nodeOfs, relPosY, //res,
- // eventHash = getEventHash(event),
- hitMode = null,
- tree = data.tree,
- options = tree.options,
- dndOpts = options.dnd5,
- targetNode = data.node,
- sourceNode = data.otherNode,
- markerAt = "center",
- // glyph = options.glyph || null,
- // $source = sourceNode ? $(sourceNode.span) : null,
- $target = $(targetNode.span),
- $targetTitle = $target.find("span.fancytree-title");
-
- if(DRAG_ENTER_RESPONSE === false){
- tree.warn("Ignore dragover, since dragenter returned false"); //, event, data);
- // $.error("assert failed: dragenter returned false");
- return false;
- } else if(typeof DRAG_ENTER_RESPONSE === "string") {
- $.error("assert failed: dragenter returned string");
- // Use hitMode from onEnter if provided.
- // hitMode = DRAG_ENTER_RESPONSE;
- } else {
- // Calculate hitMode from relative cursor position.
- nodeOfs = $target.offset();
- relPosY = (event.pageY - nodeOfs.top) / $target.height();
-
- if( DRAG_ENTER_RESPONSE.after && relPosY > 0.75 ){
- hitMode = "after";
- } else if(!DRAG_ENTER_RESPONSE.over && DRAG_ENTER_RESPONSE.after && relPosY > 0.5 ){
- hitMode = "after";
- } else if(DRAG_ENTER_RESPONSE.before && relPosY <= 0.25) {
- hitMode = "before";
- } else if(!DRAG_ENTER_RESPONSE.over && DRAG_ENTER_RESPONSE.before && relPosY <= 0.5) {
- hitMode = "before";
- } else if(DRAG_ENTER_RESPONSE.over) {
- hitMode = "over";
- }
- // Prevent no-ops like 'before source node'
- // TODO: these are no-ops when moving nodes, but not in copy mode
- if( dndOpts.preventVoidMoves ){
- if(targetNode === sourceNode){
- targetNode.debug("drop over source node prevented");
- hitMode = null;
- }else if(hitMode === "before" && sourceNode && targetNode === sourceNode.getNextSibling()){
- targetNode.debug("drop after source node prevented");
- hitMode = null;
- }else if(hitMode === "after" && sourceNode && targetNode === sourceNode.getPrevSibling()){
- targetNode.debug("drop before source node prevented");
- hitMode = null;
- }else if(hitMode === "over" && sourceNode && sourceNode.parent === targetNode && sourceNode.isLastSibling() ){
- targetNode.debug("drop last child over own parent prevented");
- hitMode = null;
- }
- }
- }
- // Let callback modify the calculated hitMode
- data.hitMode = hitMode;
- if(hitMode && dndOpts.dragOver){
- // TODO: http://code.google.com/p/dynatree/source/detail?r=625
- dndOpts.dragOver(targetNode, data);
- hitMode = data.hitMode;
- }
- // LAST_DROP_EFFECT = data.dataTransfer.dropEffect;
- // LAST_EFFECT_ALLOWED = data.dataTransfer.effectAllowed;
- LAST_HIT_MODE = hitMode;
- //
- if( hitMode === "after" || hitMode === "before" || hitMode === "over" ){
- markerOffsetX = dndOpts.dropMarkerOffsetX || 0;
- switch(hitMode){
- case "before":
- markerAt = "top";
- markerOffsetX += (dndOpts.dropMarkerInsertOffsetX || 0);
- break;
- case "after":
- markerAt = "bottom";
- markerOffsetX += (dndOpts.dropMarkerInsertOffsetX || 0);
- break;
- }
-
- $dropMarker
- .toggleClass(classDropAfter, hitMode === "after")
- .toggleClass(classDropOver, hitMode === "over")
- .toggleClass(classDropBefore, hitMode === "before")
- .show()
- .position($.ui.fancytree.fixPositionOptions({
- my: "left" + offsetString(markerOffsetX) + " center",
- at: "left " + markerAt,
- of: $targetTitle
- }));
- } else {
- $dropMarker.hide();
- // console.log("hide dropmarker")
- }
- // if( $source ){
- // $source.toggleClass(classDragRemove, isMove);
- // }
- $(targetNode.span)
- .toggleClass(classDropTarget, hitMode === "after" || hitMode === "before" || hitMode === "over")
- .toggleClass(classDropAfter, hitMode === "after")
- .toggleClass(classDropBefore, hitMode === "before")
- .toggleClass(classDropAccept, hitMode === "over")
- .toggleClass(classDropReject, hitMode === false);
-
- return hitMode;
-}
-
-/* *****************************************************************************
- *
- */
-
-$.ui.fancytree.registerExtension({
- name: "dnd5",
- version: "2.23.0",
- // Default options for this extension.
- options: {
- autoExpandMS: 1500, // Expand nodes after n milliseconds of hovering
- setTextTypeJson: false, // Allow dragging of nodes to different IE windows
- preventForeignNodes: false, // Prevent dropping nodes from different Fancytrees
- preventNonNodes: false, // Prevent dropping items other than Fancytree nodes
- preventRecursiveMoves: true, // Prevent dropping nodes on own descendants
- preventVoidMoves: true, // Prevent dropping nodes 'before self', etc.
- scroll: true, // Enable auto-scrolling while dragging
- scrollSensitivity: 20, // Active top/bottom margin in pixel
- scrollSpeed: 5, // Pixel per event
- dropMarkerOffsetX: -24, // absolute position offset for .fancytree-drop-marker relatively to ..fancytree-title (icon/img near a node accepting drop)
- dropMarkerInsertOffsetX: -16,// additional offset for drop-marker with hitMode = "before"/"after"
- // Events (drag support)
- dragStart: null, // Callback(sourceNode, data), return true, to enable dnd drag
- dragDrag: $.noop, // Callback(sourceNode, data)
- dragEnd: $.noop, // Callback(sourceNode, data)
- // Events (drop support)
- dragEnter: null, // Callback(targetNode, data), return true, to enable dnd drop
- dragOver: $.noop, // Callback(targetNode, data)
- dragExpand: $.noop, // Callback(targetNode, data), return false to prevent autoExpand
- dragDrop: $.noop, // Callback(targetNode, data)
- dragLeave: $.noop // Callback(targetNode, data)
- },
-
- treeInit: function(ctx){
- var tree = ctx.tree,
- opts = ctx.options,
- dndOpts = opts.dnd5,
- getNode = $.ui.fancytree.getNode;
-
- if( $.inArray("dnd", opts.extensions) >= 0 ) {
- $.error("Extensions 'dnd' and 'dnd5' are mutually exclusive.");
- }
- if( dndOpts.dragStop ) {
- $.error("dragStop is not used by ext-dnd5. Use dragEnd instead.");
- }
-
- // Implement `opts.createNode` event to add the 'draggable' attribute
- // #680: this must happen before calling super.treeInit()
- if( dndOpts.dragStart ) {
- $.ui.fancytree.overrideMethod(ctx.options, "createNode", function(event, data) {
- // Default processing if any
- this._super.apply(this, arguments);
-
- data.node.span.draggable = true;
- });
- }
- this._superApply(arguments);
-
- this.$container.addClass("fancytree-ext-dnd5");
-
- // Store the current scroll parent, which may be the tree
- // container, any enclosing div, or the document
- this.$scrollParent = this.$container.children(":first").scrollParent();
-
- $dropMarker = $("#fancytree-drop-marker");
- if( !$dropMarker.length ) {
- $dropMarker = $("")
- .hide()
- .css({
- "z-index": 1000,
- // Drop marker should not steal dragenter/dragover events:
- "pointer-events": "none"
- }).prependTo("body");
- // if( glyph ) {
- // instData.$dropMarker
- // .addClass(glyph.map.dropMarker);
- // }
- }
- // Enable drag support if dragStart() is specified:
- if( dndOpts.dragStart ) {
- // Bind drag event handlers
- tree.$container.on("dragstart drag dragend", function(event){
- var json,
- node = getNode(event),
- dataTransfer = event.dataTransfer || event.originalEvent.dataTransfer,
- isMove = dataTransfer.dropEffect === "move",
- $source = node ? $(node.span) : null,
- data = {
- node: node,
- tree: tree,
- options: tree.options,
- originalEvent: event,
- dataTransfer: dataTransfer,
-// dropEffect: undefined, // set by dragend
- isCancelled: undefined // set by dragend
- };
-
- switch( event.type ) {
-
- case "dragstart":
- $(node.span).addClass(classDragSource);
-
- // Store current source node in different formats
- SOURCE_NODE = node;
-
- // Set payload
- // Note:
- // Transfer data is only accessible on dragstart and drop!
- // For all other events the formats and kinds in the drag
- // data store list of items representing dragged data can be
- // enumerated, but the data itself is unavailable and no new
- // data can be added.
- json = JSON.stringify(node.toDict());
- try {
- dataTransfer.setData(nodeMimeType, json);
- dataTransfer.setData("text/html", $(node.span).html());
- dataTransfer.setData("text/plain", node.title);
- } catch(ex) {
- // IE only accepts 'text' type
- tree.warn("Could not set data (IE only accepts 'text') - " + ex);
- }
- // We always need to set the 'text' type if we want to drag
- // Because IE 11 only accepts this single type.
- // If we pass JSON here, IE can can access all node properties,
- // even when the source lives in another window. (D'n'd inside
- // the same window will always work.)
- // The drawback is, that in this case ALL browsers will see
- // the JSON representation as 'text', so dragging
- // to a text field will insert the JSON string instead of
- // the node title.
- if( dndOpts.setTextTypeJson ) {
- dataTransfer.setData("text", json);
- } else {
- dataTransfer.setData("text", node.title);
- }
-
- // Set the allowed and current drag mode (move, copy, or link)
- dataTransfer.effectAllowed = "all"; // "copyMove"
- // dataTransfer.dropEffect = "move";
-
- // Set the title as drag image (otherwise it would contain the expander)
- if( dataTransfer.setDragImage ) {
- // IE 11 does not support this
- dataTransfer.setDragImage($(node.span).find(".fancytree-title")[0], -10, -10);
- // dataTransfer.setDragImage($(node.span)[0], -10, -10);
- }
- // Let user modify above settings
- return dndOpts.dragStart(node, data) !== false;
-
- case "drag":
- // Called every few miliseconds
- $source.toggleClass(classDragRemove, isMove);
- dndOpts.dragDrag(node, data);
- break;
-
- case "dragend":
- $(node.span).removeClass(classDragSource + " " + classDragRemove);
- SOURCE_NODE = null;
- DRAG_ENTER_RESPONSE = null;
-// data.dropEffect = dataTransfer.dropEffect;
- data.isCancelled = (dataTransfer.dropEffect === "none");
- $dropMarker.hide();
- dndOpts.dragEnd(node, data);
- break;
- }
- });
- }
- // Enable drop support if dragEnter() is specified:
- if( dndOpts.dragEnter ) {
- // Bind drop event handlers
- tree.$container.on("dragenter dragover dragleave drop", function(event){
- var json, nodeData, r, res,
- allowDrop = null,
- node = getNode(event),
- dataTransfer = event.dataTransfer || event.originalEvent.dataTransfer,
- // glyph = opts.glyph || null,
- data = {
- node: node,
- tree: tree,
- options: tree.options,
- hitMode: DRAG_ENTER_RESPONSE,
- originalEvent: event,
- dataTransfer: dataTransfer,
- otherNode: SOURCE_NODE || null,
- otherNodeData: null, // set by drop event
- dropEffect: undefined, // set by drop event
- isCancelled: undefined // set by drop event
- };
-
- switch( event.type ) {
-
- case "dragenter":
- // The dragenter event is fired when a dragged element or
- // text selection enters a valid drop target.
-
- if( !node ) {
- // Sometimes we get dragenter for the container element
- tree.debug("Ignore non-node " + event.type + ": " + event.target.tagName + "." + event.target.className);
- DRAG_ENTER_RESPONSE = false;
- break;
- }
-
- $(node.span)
- .addClass(classDropOver)
- .removeClass(classDropAccept + " " + classDropReject);
-
- if( dndOpts.preventNonNodes && !nodeData ) {
- node.debug("Reject dropping a non-node");
- DRAG_ENTER_RESPONSE = false;
- break;
- } else if( dndOpts.preventForeignNodes && (!SOURCE_NODE || SOURCE_NODE.tree !== node.tree ) ) {
- node.debug("Reject dropping a foreign node");
- DRAG_ENTER_RESPONSE = false;
- break;
- }
-
- // NOTE: dragenter is fired BEFORE the dragleave event
- // of the previous element!
- // https://www.w3.org/Bugs/Public/show_bug.cgi?id=19041
- setTimeout(function(){
- // node.info("DELAYED " + event.type, event.target, DRAG_ENTER_RESPONSE);
- // Auto-expand node (only when 'over' the node, not 'before', or 'after')
- if( dndOpts.autoExpandMS &&
- node.hasChildren() !== false && !node.expanded &&
- (!dndOpts.dragExpand || dndOpts.dragExpand(node, data) !== false)
- ) {
- node.scheduleAction("expand", dndOpts.autoExpandMS);
- }
- }, 0);
-
- $dropMarker.show();
-
- // Call dragEnter() to figure out if (and where) dropping is allowed
- if( dndOpts.preventRecursiveMoves && node.isDescendantOf(data.otherNode) ){
- res = false;
- }else{
- r = dndOpts.dragEnter(node, data);
- res = normalizeDragEnterResponse(r);
- }
- DRAG_ENTER_RESPONSE = res;
-
- allowDrop = res && ( res.over || res.before || res.after );
- break;
-
- case "dragover":
- // The dragover event is fired when an element or text
- // selection is being dragged over a valid drop target
- // (every few hundred milliseconds).
- LAST_HIT_MODE = handleDragOver(event, data);
- allowDrop = !!LAST_HIT_MODE;
- break;
-
- case "dragleave":
- // NOTE: dragleave is fired AFTER the dragenter event of the
- // FOLLOWING element.
- if( !node ) {
- tree.debug("Ignore non-node " + event.type + ": " + event.target.tagName + "." + event.target.className);
- break;
- }
- if( !$(node.span).hasClass(classDropOver) ) {
- node.debug("Ignore dragleave (multi)"); //, event.currentTarget);
- break;
- }
- $(node.span).removeClass(classDropOver + " " + classDropAccept + " " + classDropReject);
- node.scheduleAction("cancel");
- dndOpts.dragLeave(node, data);
- $dropMarker.hide();
- break;
-
- case "drop":
- // Data is only readable in the (dragenter and) drop event:
-
- if( $.inArray(nodeMimeType, dataTransfer.types) >= 0 ) {
- nodeData = dataTransfer.getData(nodeMimeType);
- tree.info(event.type + ": getData('application/x-fancytree-node'): '" + nodeData + "'");
- }
- if( !nodeData ) {
- // 1. Source is not a Fancytree node, or
- // 2. If the FT mime type was set, but returns '', this
- // is probably IE 11 (which only supports 'text')
- nodeData = dataTransfer.getData("text");
- tree.info(event.type + ": getData('text'): '" + nodeData + "'");
- }
- if( nodeData ) {
- try {
- // 'text' type may contain JSON if IE is involved
- // and setTextTypeJson option was set
- json = JSON.parse(nodeData);
- if( json.title !== undefined ) {
- data.otherNodeData = json;
- }
- } catch(ex) {
- // assume 'text' type contains plain text, so `otherNodeData`
- // should not be set
- }
- }
- tree.debug(event.type + ": nodeData: '" + nodeData + "', otherNodeData: ", data.otherNodeData);
-
- $(node.span).removeClass(classDropOver + " " + classDropAccept + " " + classDropReject);
- $dropMarker.hide();
-
- data.hitMode = LAST_HIT_MODE;
- data.dropEffect = dataTransfer.dropEffect;
- data.isCancelled = data.dropEffect === "none";
-
- // Let user implement the actual drop operation
- dndOpts.dragDrop(node, data);
-
- // Prevent browser's default drop handling
- event.preventDefault();
- break;
- }
- // Dnd API madness: we must PREVENT default handling to enable dropping
- if( allowDrop ) {
- event.preventDefault();
- return false;
- }
- });
- }
- }
-});
-}(jQuery, window, document));
-
-/*!
- * jquery.fancytree.edit.js
- *
- * Make node titles editable.
- * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
- *
- * Copyright (c) 2008-2017, Martin Wendt (http://wwWendt.de)
- *
- * Released under the MIT license
- * https://github.com/mar10/fancytree/wiki/LicenseInfo
- *
- * @version 2.23.0
- * @date 2017-05-27T20:09:38Z
- */
-
-;(function($, window, document, undefined) {
-
-"use strict";
-
-
-/*******************************************************************************
- * Private functions and variables
- */
-
-var isMac = /Mac/.test(navigator.platform),
- escapeHtml = $.ui.fancytree.escapeHtml,
- unescapeHtml = $.ui.fancytree.unescapeHtml;
-
-/**
- * [ext-edit] Start inline editing of current node title.
- *
- * @alias FancytreeNode#editStart
- * @requires Fancytree
- */
-$.ui.fancytree._FancytreeNodeClass.prototype.editStart = function(){
- var $input,
- node = this,
- tree = this.tree,
- local = tree.ext.edit,
- instOpts = tree.options.edit,
- $title = $(".fancytree-title", node.span),
- eventData = {
- node: node,
- tree: tree,
- options: tree.options,
- isNew: $(node[tree.statusClassPropName]).hasClass("fancytree-edit-new"),
- orgTitle: node.title,
- input: null,
- dirty: false
- };
-
- // beforeEdit may want to modify the title before editing
- if( instOpts.beforeEdit.call(node, {type: "beforeEdit"}, eventData) === false ) {
- return false;
- }
- $.ui.fancytree.assert(!local.currentNode, "recursive edit");
- local.currentNode = this;
- local.eventData = eventData;
-
- // Disable standard Fancytree mouse- and key handling
- tree.widget._unbind();
- // #116: ext-dnd prevents the blur event, so we have to catch outer clicks
- $(document).on("mousedown.fancytree-edit", function(event){
- if( ! $(event.target).hasClass("fancytree-edit-input") ){
- node.editEnd(true, event);
- }
- });
-
- // Replace node with
- $input = $("", {
- "class": "fancytree-edit-input",
- type: "text",
- value: tree.options.escapeTitles ? eventData.orgTitle : unescapeHtml(eventData.orgTitle)
- });
- local.eventData.input = $input;
- if ( instOpts.adjustWidthOfs != null ) {
- $input.width($title.width() + instOpts.adjustWidthOfs);
- }
- if ( instOpts.inputCss != null ) {
- $input.css(instOpts.inputCss);
- }
-
- $title.html($input);
-
- // Focus and bind keyboard handler
- $input
- .focus()
- .change(function(event){
- $input.addClass("fancytree-edit-dirty");
- }).keydown(function(event){
- switch( event.which ) {
- case $.ui.keyCode.ESCAPE:
- node.editEnd(false, event);
- break;
- case $.ui.keyCode.ENTER:
- node.editEnd(true, event);
- return false; // so we don't start editmode on Mac
- }
- event.stopPropagation();
- }).blur(function(event){
- return node.editEnd(true, event);
- });
-
- instOpts.edit.call(node, {type: "edit"}, eventData);
-};
-
-
-/**
- * [ext-edit] Stop inline editing.
- * @param {Boolean} [applyChanges=false] false: cancel edit, true: save (if modified)
- * @alias FancytreeNode#editEnd
- * @requires jquery.fancytree.edit.js
- */
-$.ui.fancytree._FancytreeNodeClass.prototype.editEnd = function(applyChanges, _event){
- var newVal,
- node = this,
- tree = this.tree,
- local = tree.ext.edit,
- eventData = local.eventData,
- instOpts = tree.options.edit,
- $title = $(".fancytree-title", node.span),
- $input = $title.find("input.fancytree-edit-input");
-
- if( instOpts.trim ) {
- $input.val($.trim($input.val()));
- }
- newVal = $input.val();
-
- eventData.dirty = ( newVal !== node.title );
- eventData.originalEvent = _event;
-
- // Find out, if saving is required
- if( applyChanges === false ) {
- // If true/false was passed, honor this (except in rename mode, if unchanged)
- eventData.save = false;
- } else if( eventData.isNew ) {
- // In create mode, we save everyting, except for empty text
- eventData.save = (newVal !== "");
- } else {
- // In rename mode, we save everyting, except for empty or unchanged text
- eventData.save = eventData.dirty && (newVal !== "");
- }
- // Allow to break (keep editor open), modify input, or re-define data.save
- if( instOpts.beforeClose.call(node, {type: "beforeClose"}, eventData) === false){
- return false;
- }
- if( eventData.save && instOpts.save.call(node, {type: "save"}, eventData) === false){
- return false;
- }
- $input
- .removeClass("fancytree-edit-dirty")
- .off();
- // Unbind outer-click handler
- $(document).off(".fancytree-edit");
-
- if( eventData.save ) {
- // # 171: escape user input (not required if global escaping is on)
- node.setTitle( tree.options.escapeTitles ? newVal : escapeHtml(newVal) );
- node.setFocus();
- }else{
- if( eventData.isNew ) {
- node.remove();
- node = eventData.node = null;
- local.relatedNode.setFocus();
- } else {
- node.renderTitle();
- node.setFocus();
- }
- }
- local.eventData = null;
- local.currentNode = null;
- local.relatedNode = null;
- // Re-enable mouse and keyboard handling
- tree.widget._bind();
- // Set keyboard focus, even if setFocus() claims 'nothing to do'
- $(tree.$container).focus();
- eventData.input = null;
- instOpts.close.call(node, {type: "close"}, eventData);
- return true;
-};
-
-
-/**
-* [ext-edit] Create a new child or sibling node and start edit mode.
-*
-* @param {String} [mode='child'] 'before', 'after', or 'child'
-* @param {Object} [init] NodeData (or simple title string)
-* @alias FancytreeNode#editCreateNode
-* @requires jquery.fancytree.edit.js
-* @since 2.4
-*/
-$.ui.fancytree._FancytreeNodeClass.prototype.editCreateNode = function(mode, init){
- var newNode,
- tree = this.tree,
- self = this;
-
- mode = mode || "child";
- if( init == null ) {
- init = { title: "" };
- } else if( typeof init === "string" ) {
- init = { title: init };
- } else {
- $.ui.fancytree.assert($.isPlainObject(init));
- }
- // Make sure node is expanded (and loaded) in 'child' mode
- if( mode === "child" && !this.isExpanded() && this.hasChildren() !== false ) {
- this.setExpanded().done(function(){
- self.editCreateNode(mode, init);
- });
- return;
- }
- newNode = this.addNode(init, mode);
-
- // #644: Don't filter new nodes.
- newNode.match = true;
- $(newNode[tree.statusClassPropName])
- .removeClass("fancytree-hide")
- .addClass("fancytree-match");
-
- newNode.makeVisible(/*{noAnimation: true}*/).done(function(){
- $(newNode[tree.statusClassPropName]).addClass("fancytree-edit-new");
- self.tree.ext.edit.relatedNode = self;
- newNode.editStart();
- });
-};
-
-
-/**
- * [ext-edit] Check if any node in this tree in edit mode.
- *
- * @returns {FancytreeNode | null}
- * @alias Fancytree#isEditing
- * @requires jquery.fancytree.edit.js
- */
-$.ui.fancytree._FancytreeClass.prototype.isEditing = function(){
- return this.ext.edit ? this.ext.edit.currentNode : null;
-};
-
-
-/**
- * [ext-edit] Check if this node is in edit mode.
- * @returns {Boolean} true if node is currently beeing edited
- * @alias FancytreeNode#isEditing
- * @requires jquery.fancytree.edit.js
- */
-$.ui.fancytree._FancytreeNodeClass.prototype.isEditing = function(){
- return this.tree.ext.edit ? this.tree.ext.edit.currentNode === this : false;
-};
-
-
-/*******************************************************************************
- * Extension code
- */
-$.ui.fancytree.registerExtension({
- name: "edit",
- version: "2.23.0",
- // Default options for this extension.
- options: {
- adjustWidthOfs: 4, // null: don't adjust input size to content
- allowEmpty: false, // Prevent empty input
- inputCss: {minWidth: "3em"},
- // triggerCancel: ["esc", "tab", "click"],
- // triggerStart: ["f2", "dblclick", "shift+click", "mac+enter"],
- triggerStart: ["f2", "shift+click", "mac+enter"],
- trim: true, // Trim whitespace before save
- // Events:
- beforeClose: $.noop, // Return false to prevent cancel/save (data.input is available)
- beforeEdit: $.noop, // Return false to prevent edit mode
- close: $.noop, // Editor was removed
- edit: $.noop, // Editor was opened (available as data.input)
-// keypress: $.noop, // Not yet implemented
- save: $.noop // Save data.input.val() or return false to keep editor open
- },
- // Local attributes
- currentNode: null,
-
- treeInit: function(ctx){
- this._superApply(arguments);
- this.$container.addClass("fancytree-ext-edit");
- },
- nodeClick: function(ctx) {
- if( $.inArray("shift+click", ctx.options.edit.triggerStart) >= 0 ){
- if( ctx.originalEvent.shiftKey ){
- ctx.node.editStart();
- return false;
- }
- }
- return this._superApply(arguments);
- },
- nodeDblclick: function(ctx) {
- if( $.inArray("dblclick", ctx.options.edit.triggerStart) >= 0 ){
- ctx.node.editStart();
- return false;
- }
- return this._superApply(arguments);
- },
- nodeKeydown: function(ctx) {
- switch( ctx.originalEvent.which ) {
- case 113: // [F2]
- if( $.inArray("f2", ctx.options.edit.triggerStart) >= 0 ){
- ctx.node.editStart();
- return false;
- }
- break;
- case $.ui.keyCode.ENTER:
- if( $.inArray("mac+enter", ctx.options.edit.triggerStart) >= 0 && isMac ){
- ctx.node.editStart();
- return false;
- }
- break;
- }
- return this._superApply(arguments);
- }
-});
-}(jQuery, window, document));
-
-/*!
- * jquery.fancytree.filter.js
- *
- * Remove or highlight tree nodes, based on a filter.
- * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
- *
- * Copyright (c) 2008-2017, Martin Wendt (http://wwWendt.de)
- *
- * Released under the MIT license
- * https://github.com/mar10/fancytree/wiki/LicenseInfo
- *
- * @version 2.23.0
- * @date 2017-05-27T20:09:38Z
- */
-
-;(function($, window, document, undefined) {
-
-"use strict";
-
-
-/*******************************************************************************
- * Private functions and variables
- */
-
-var KeyNoData = "__not_found__",
- escapeHtml = $.ui.fancytree.escapeHtml;
-
-function _escapeRegex(str){
- /*jshint regexdash:true */
- return (str + "").replace(/([.?*+\^\$\[\]\\(){}|-])/g, "\\$1");
-}
-
-function extractHtmlText(s){
- if( s.indexOf(">") >= 0 ) {
- return $("").html(s).text();
- }
- return s;
-}
-
-$.ui.fancytree._FancytreeClass.prototype._applyFilterImpl = function(filter, branchMode, _opts){
- var match, statusNode, re, reHighlight,
- count = 0,
- treeOpts = this.options,
- escapeTitles = treeOpts.escapeTitles,
- prevAutoCollapse = treeOpts.autoCollapse,
- opts = $.extend({}, treeOpts.filter, _opts),
- hideMode = opts.mode === "hide",
- leavesOnly = !!opts.leavesOnly && !branchMode;
-
- // Default to 'match title substring (not case sensitive)'
- if(typeof filter === "string"){
- // console.log("rex", filter.split('').join('\\w*').replace(/\W/, ""))
- if( opts.fuzzy ) {
- // See https://codereview.stackexchange.com/questions/23899/faster-javascript-fuzzy-string-matching-function/23905#23905
- // and http://www.quora.com/How-is-the-fuzzy-search-algorithm-in-Sublime-Text-designed
- // and http://www.dustindiaz.com/autocomplete-fuzzy-matching
- match = filter.split("").reduce(function(a, b) {
- return a + "[^" + b + "]*" + b;
- });
- } else {
- match = _escapeRegex(filter); // make sure a '.' is treated literally
- }
- re = new RegExp(".*" + match + ".*", "i");
- reHighlight = new RegExp(_escapeRegex(filter), "gi");
- filter = function(node){
- var display,
- text = escapeTitles ? node.title : extractHtmlText(node.title),
- res = !!re.test(text);
-
- if( res && opts.highlight ) {
- display = escapeTitles ? escapeHtml(node.title) : text;
- node.titleWithHighlight = display.replace(reHighlight, function(s){
- return "" + s + "";
- });
- // node.debug("filter", escapeTitles, text, node.titleWithHighlight);
- }
- return res;
- };
- }
-
- this.enableFilter = true;
- this.lastFilterArgs = arguments;
-
- this.$div.addClass("fancytree-ext-filter");
- if( hideMode ){
- this.$div.addClass("fancytree-ext-filter-hide");
- } else {
- this.$div.addClass("fancytree-ext-filter-dimm");
- }
- this.$div.toggleClass("fancytree-ext-filter-hide-expanders", !!opts.hideExpanders);
- // Reset current filter
- this.visit(function(node){
- delete node.match;
- delete node.titleWithHighlight;
- node.subMatchCount = 0;
- });
- statusNode = this.getRootNode()._findDirectChild(KeyNoData);
- if( statusNode ) {
- statusNode.remove();
- }
-
- // Adjust node.hide, .match, and .subMatchCount properties
- treeOpts.autoCollapse = false; // #528
-
- this.visit(function(node){
- if ( leavesOnly && node.children != null ) {
- return;
- }
- var res = filter(node),
- matchedByBranch = false;
-
- if( res === "skip" ) {
- node.visit(function(c){
- c.match = false;
- }, true);
- return "skip";
- }
- if( !res && (branchMode || res === "branch") && node.parent.match ) {
- res = true;
- matchedByBranch = true;
- }
- if( res ) {
- count++;
- node.match = true;
- node.visitParents(function(p){
- p.subMatchCount += 1;
- // Expand match (unless this is no real match, but only a node in a matched branch)
- if( opts.autoExpand && !matchedByBranch && !p.expanded ) {
- p.setExpanded(true, {noAnimation: true, noEvents: true, scrollIntoView: false});
- p._filterAutoExpanded = true;
- }
- });
- }
- });
- treeOpts.autoCollapse = prevAutoCollapse;
-
- if( count === 0 && opts.nodata && hideMode ) {
- statusNode = opts.nodata;
- if( $.isFunction(statusNode) ) {
- statusNode = statusNode();
- }
- if( statusNode === true ) {
- statusNode = {};
- } else if( typeof statusNode === "string" ) {
- statusNode = { title: statusNode };
- }
- statusNode = $.extend({
- statusNodeType: "nodata",
- key: KeyNoData,
- title: this.options.strings.noData
- }, statusNode);
-
- this.getRootNode().addNode(statusNode).match = true;
- }
- // Redraw whole tree
- this.render();
- return count;
-};
-
-/**
- * [ext-filter] Dimm or hide nodes.
- *
- * @param {function | string} filter
- * @param {boolean} [opts={autoExpand: false, leavesOnly: false}]
- * @returns {integer} count
- * @alias Fancytree#filterNodes
- * @requires jquery.fancytree.filter.js
- */
-$.ui.fancytree._FancytreeClass.prototype.filterNodes = function(filter, opts) {
- if( typeof opts === "boolean" ) {
- opts = { leavesOnly: opts };
- this.warn("Fancytree.filterNodes() leavesOnly option is deprecated since 2.9.0 / 2015-04-19. Use opts.leavesOnly instead.");
- }
- return this._applyFilterImpl(filter, false, opts);
-};
-
-/**
- * @deprecated
- */
-$.ui.fancytree._FancytreeClass.prototype.applyFilter = function(filter){
- this.warn("Fancytree.applyFilter() is deprecated since 2.1.0 / 2014-05-29. Use .filterNodes() instead.");
- return this.filterNodes.apply(this, arguments);
-};
-
-/**
- * [ext-filter] Dimm or hide whole branches.
- *
- * @param {function | string} filter
- * @param {boolean} [opts={autoExpand: false}]
- * @returns {integer} count
- * @alias Fancytree#filterBranches
- * @requires jquery.fancytree.filter.js
- */
-$.ui.fancytree._FancytreeClass.prototype.filterBranches = function(filter, opts){
- return this._applyFilterImpl(filter, true, opts);
-};
-
-
-/**
- * [ext-filter] Reset the filter.
- *
- * @alias Fancytree#clearFilter
- * @requires jquery.fancytree.filter.js
- */
-$.ui.fancytree._FancytreeClass.prototype.clearFilter = function(){
- var $title,
- statusNode = this.getRootNode()._findDirectChild(KeyNoData),
- escapeTitles = this.options.escapeTitles,
- enhanceTitle = this.options.enhanceTitle;
-
- if( statusNode ) {
- statusNode.remove();
- }
- this.visit(function(node){
- if( node.match && node.span ) { // #491, #601
- $title = $(node.span).find(">span.fancytree-title");
- if( escapeTitles ) {
- $title.text(node.title);
- } else {
- $title.html(node.title);
- }
- if( enhanceTitle ) {
- enhanceTitle({type: "enhanceTitle"}, {node: node, $title: $title});
- }
- }
- delete node.match;
- delete node.subMatchCount;
- delete node.titleWithHighlight;
- if ( node.$subMatchBadge ) {
- node.$subMatchBadge.remove();
- delete node.$subMatchBadge;
- }
- if( node._filterAutoExpanded && node.expanded ) {
- node.setExpanded(false, {noAnimation: true, noEvents: true, scrollIntoView: false});
- }
- delete node._filterAutoExpanded;
- });
- this.enableFilter = false;
- this.lastFilterArgs = null;
- this.$div.removeClass("fancytree-ext-filter fancytree-ext-filter-dimm fancytree-ext-filter-hide");
- this.render();
-};
-
-
-/**
- * [ext-filter] Return true if a filter is currently applied.
- *
- * @returns {Boolean}
- * @alias Fancytree#isFilterActive
- * @requires jquery.fancytree.filter.js
- * @since 2.13
- */
-$.ui.fancytree._FancytreeClass.prototype.isFilterActive = function(){
- return !!this.enableFilter;
-};
-
-
-/**
- * [ext-filter] Return true if this node is matched by current filter (or no filter is active).
- *
- * @returns {Boolean}
- * @alias FancytreeNode#isMatched
- * @requires jquery.fancytree.filter.js
- * @since 2.13
- */
-$.ui.fancytree._FancytreeNodeClass.prototype.isMatched = function(){
- return !(this.tree.enableFilter && !this.match);
-};
-
-
-/*******************************************************************************
- * Extension code
- */
-$.ui.fancytree.registerExtension({
- name: "filter",
- version: "2.23.0",
- // Default options for this extension.
- options: {
- autoApply: true, // Re-apply last filter if lazy data is loaded
- autoExpand: false, // Expand all branches that contain matches while filtered
- counter: true, // Show a badge with number of matching child nodes near parent icons
- fuzzy: false, // Match single characters in order, e.g. 'fb' will match 'FooBar'
- hideExpandedCounter: true, // Hide counter badge if parent is expanded
- hideExpanders: false, // Hide expanders if all child nodes are hidden by filter
- highlight: true, // Highlight matches by wrapping inside tags
- leavesOnly: false, // Match end nodes only
- nodata: true, // Display a 'no data' status node if result is empty
- mode: "dimm" // Grayout unmatched nodes (pass "hide" to remove unmatched node instead)
- },
- nodeLoadChildren: function(ctx, source) {
- return this._superApply(arguments).done(function() {
- if( ctx.tree.enableFilter && ctx.tree.lastFilterArgs && ctx.options.filter.autoApply ) {
- ctx.tree._applyFilterImpl.apply(ctx.tree, ctx.tree.lastFilterArgs);
- }
- });
- },
- nodeSetExpanded: function(ctx, flag, callOpts) {
- delete ctx.node._filterAutoExpanded;
- // Make sure counter badge is displayed again, when node is beeing collapsed
- if( !flag && ctx.options.filter.hideExpandedCounter && ctx.node.$subMatchBadge ) {
- ctx.node.$subMatchBadge.show();
- }
- return this._superApply(arguments);
- },
- nodeRenderStatus: function(ctx) {
- // Set classes for current status
- var res,
- node = ctx.node,
- tree = ctx.tree,
- opts = ctx.options.filter,
- $title = $(node.span).find("span.fancytree-title"),
- $span = $(node[tree.statusClassPropName]),
- enhanceTitle = ctx.options.enhanceTitle,
- escapeTitles = ctx.options.escapeTitles;
-
- res = this._super(ctx);
- // nothing to do, if node was not yet rendered
- if( !$span.length || !tree.enableFilter ) {
- return res;
- }
- $span
- .toggleClass("fancytree-match", !!node.match)
- .toggleClass("fancytree-submatch", !!node.subMatchCount)
- .toggleClass("fancytree-hide", !(node.match || node.subMatchCount));
- // Add/update counter badge
- if( opts.counter && node.subMatchCount && (!node.isExpanded() || !opts.hideExpandedCounter) ) {
- if( !node.$subMatchBadge ) {
- node.$subMatchBadge = $("");
- $("span.fancytree-icon, span.fancytree-custom-icon", node.span).append(node.$subMatchBadge);
- }
- node.$subMatchBadge.show().text(node.subMatchCount);
- } else if ( node.$subMatchBadge ) {
- node.$subMatchBadge.hide();
- }
- // node.debug("nodeRenderStatus", node.titleWithHighlight, node.title)
- // #601: also chek for $title.length, because we don't need to render
- // if node.span is null (i.e. not rendered)
- if( node.span && (!node.isEditing || !node.isEditing.call(node)) ) {
- if( node.titleWithHighlight ) {
- $title.html(node.titleWithHighlight);
- } else if ( escapeTitles ) {
- $title.text(node.title);
- } else {
- $title.html(node.title);
- }
- if( enhanceTitle ) {
- enhanceTitle({type: "enhanceTitle"}, {node: node, $title: $title});
- }
- }
- return res;
- }
-});
-}(jQuery, window, document));
-
-/*!
- * jquery.fancytree.glyph.js
- *
- * Use glyph fonts as instead of icon sprites.
- * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
- *
- * Copyright (c) 2008-2017, Martin Wendt (http://wwWendt.de)
- *
- * Released under the MIT license
- * https://github.com/mar10/fancytree/wiki/LicenseInfo
- *
- * @version 2.23.0
- * @date 2017-05-27T20:09:38Z
- */
-
-;(function($, window, document, undefined) {
-
-"use strict";
-
-/* *****************************************************************************
- * Private functions and variables
- */
-
-function _getIcon(opts, type){
- return opts.map[type];
-}
-
-$.ui.fancytree.registerExtension({
- name: "glyph",
- version: "2.23.0",
- // Default options for this extension.
- options: {
- map: {
- // Samples from Font Awesome 3.2
- // http://fortawesome.github.io/Font-Awesome/3.2.1/icons/
- // See here for alternatives:
- // http://fortawesome.github.io/Font-Awesome/icons/
- // http://getbootstrap.com/components/
- checkbox: "icon-check-empty",
- checkboxSelected: "icon-check",
- checkboxUnknown: "icon-check icon-muted",
- error: "icon-exclamation-sign",
- expanderClosed: "icon-caret-right",
- expanderLazy: "icon-angle-right",
- expanderOpen: "icon-caret-down",
- nodata: "icon-meh",
- noExpander: "",
- dragHelper: "icon-caret-right",
- dropMarker: "icon-caret-right",
- // Default node icons.
- // (Use tree.options.icon callback to define custom icons
- // based on node data)
- doc: "icon-file-alt",
- docOpen: "icon-file-alt",
- loading: "icon-refresh icon-spin",
- folder: "icon-folder-close-alt",
- folderOpen: "icon-folder-open-alt"
- }
- },
-
- treeInit: function(ctx){
- var tree = ctx.tree;
- this._superApply(arguments);
- tree.$container.addClass("fancytree-ext-glyph");
- },
- nodeRenderStatus: function(ctx) {
- var icon, res, span,
- node = ctx.node,
- $span = $(node.span),
- opts = ctx.options.glyph,
- map = opts.map;
-
- res = this._super(ctx);
-
- if( node.isRoot() ){
- return res;
- }
- span = $span.children("span.fancytree-expander").get(0);
- if( span ){
- // if( node.isLoading() ){
- // icon = "loading";
- if( node.expanded && node.hasChildren() ){
- icon = "expanderOpen";
- }else if( node.isUndefined() ){
- icon = "expanderLazy";
- }else if( node.hasChildren() ){
- icon = "expanderClosed";
- }else{
- icon = "noExpander";
- }
- span.className = "fancytree-expander " + map[icon];
- }
-
- if( node.tr ){
- span = $("td", node.tr).find("span.fancytree-checkbox").get(0);
- }else{
- span = $span.children("span.fancytree-checkbox").get(0);
- }
- if( span ){
- icon = node.selected ? "checkboxSelected" : (node.partsel ? "checkboxUnknown" : "checkbox");
- span.className = "fancytree-checkbox " + map[icon];
- }
-
- // Standard icon (note that this does not match .fancytree-custom-icon,
- // that might be set by opts.icon callbacks)
- span = $span.children("span.fancytree-icon").get(0);
- if( span ){
- if( node.statusNodeType ){
- icon = _getIcon(opts, node.statusNodeType); // loading, error
- }else if( node.folder ){
- icon = node.expanded && node.hasChildren() ? _getIcon(opts, "folderOpen") : _getIcon(opts, "folder");
- }else{
- icon = node.expanded ? _getIcon(opts, "docOpen") : _getIcon(opts, "doc");
- }
- span.className = "fancytree-icon " + icon;
- }
- return res;
- },
- nodeSetStatus: function(ctx, status, message, details) {
- var res, span,
- opts = ctx.options.glyph,
- node = ctx.node;
-
- res = this._superApply(arguments);
-
- if( status === "error" || status === "loading" || status === "nodata" ){
- if(node.parent){
- span = $("span.fancytree-expander", node.span).get(0);
- if( span ) {
- span.className = "fancytree-expander " + _getIcon(opts, status);
- }
- }else{ //
- span = $(".fancytree-statusnode-" + status, node[this.nodeContainerAttrName])
- .find("span.fancytree-icon").get(0);
- if( span ) {
- span.className = "fancytree-icon " + _getIcon(opts, status);
- }
- }
- }
- return res;
- }
-});
-}(jQuery, window, document));
-
-/*!
- * jquery.fancytree.gridnav.js
- *
- * Support keyboard navigation for trees with embedded input controls.
- * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
- *
- * Copyright (c) 2008-2017, Martin Wendt (http://wwWendt.de)
- *
- * Released under the MIT license
- * https://github.com/mar10/fancytree/wiki/LicenseInfo
- *
- * @version 2.23.0
- * @date 2017-05-27T20:09:38Z
- */
-
-;(function($, window, document, undefined) {
-
-"use strict";
-
-
-/*******************************************************************************
- * Private functions and variables
- */
-
-// Allow these navigation keys even when input controls are focused
-
-var KC = $.ui.keyCode,
- // which keys are *not* handled by embedded control, but passed to tree
- // navigation handler:
- NAV_KEYS = {
- "text": [KC.UP, KC.DOWN],
- "checkbox": [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT],
- "link": [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT],
- "radiobutton": [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT],
- "select-one": [KC.LEFT, KC.RIGHT],
- "select-multiple": [KC.LEFT, KC.RIGHT]
- };
-
-
-/* Calculate TD column index (considering colspans).*/
-function getColIdx($tr, $td) {
- var colspan,
- td = $td.get(0),
- idx = 0;
-
- $tr.children().each(function () {
- if( this === td ) {
- return false;
- }
- colspan = $(this).prop("colspan");
- idx += colspan ? colspan : 1;
- });
- return idx;
-}
-
-
-/* Find TD at given column index (considering colspans).*/
-function findTdAtColIdx($tr, colIdx) {
- var colspan,
- res = null,
- idx = 0;
-
- $tr.children().each(function () {
- if( idx >= colIdx ) {
- res = $(this);
- return false;
- }
- colspan = $(this).prop("colspan");
- idx += colspan ? colspan : 1;
- });
- return res;
-}
-
-
-/* Find adjacent cell for a given direction. Skip empty cells and consider merged cells */
-function findNeighbourTd($target, keyCode){
- var $tr, colIdx,
- $td = $target.closest("td"),
- $tdNext = null;
-
- switch( keyCode ){
- case KC.LEFT:
- $tdNext = $td.prev();
- break;
- case KC.RIGHT:
- $tdNext = $td.next();
- break;
- case KC.UP:
- case KC.DOWN:
- $tr = $td.parent();
- colIdx = getColIdx($tr, $td);
- while( true ) {
- $tr = (keyCode === KC.UP) ? $tr.prev() : $tr.next();
- if( !$tr.length ) {
- break;
- }
- // Skip hidden rows
- if( $tr.is(":hidden") ) {
- continue;
- }
- // Find adjacent cell in the same column
- $tdNext = findTdAtColIdx($tr, colIdx);
- // Skip cells that don't conatain a focusable element
- if( $tdNext && $tdNext.find(":input,a").length ) {
- break;
- }
- }
- break;
- }
- return $tdNext;
-}
-
-
-/*******************************************************************************
- * Extension code
- */
-$.ui.fancytree.registerExtension({
- name: "gridnav",
- version: "2.23.0",
- // Default options for this extension.
- options: {
- autofocusInput: false, // Focus first embedded input if node gets activated
- handleCursorKeys: true // Allow UP/DOWN in inputs to move to prev/next node
- },
-
- treeInit: function(ctx){
- // gridnav requires the table extension to be loaded before itself
- this._requireExtension("table", true, true);
- this._superApply(arguments);
-
- this.$container.addClass("fancytree-ext-gridnav");
-
- // Activate node if embedded input gets focus (due to a click)
- this.$container.on("focusin", function(event){
- var ctx2,
- node = $.ui.fancytree.getNode(event.target);
-
- if( node && !node.isActive() ){
- // Call node.setActive(), but also pass the event
- ctx2 = ctx.tree._makeHookContext(node, event);
- ctx.tree._callHook("nodeSetActive", ctx2, true);
- }
- });
- },
- nodeSetActive: function(ctx, flag, callOpts) {
- var $outer,
- opts = ctx.options.gridnav,
- node = ctx.node,
- event = ctx.originalEvent || {},
- triggeredByInput = $(event.target).is(":input");
-
- flag = (flag !== false);
-
- this._superApply(arguments);
-
- if( flag ){
- if( ctx.options.titlesTabbable ){
- if( !triggeredByInput ) {
- $(node.span).find("span.fancytree-title").focus();
- node.setFocus();
- }
- // If one node is tabbable, the container no longer needs to be
- ctx.tree.$container.attr("tabindex", "-1");
- // ctx.tree.$container.removeAttr("tabindex");
- } else if( opts.autofocusInput && !triggeredByInput ){
- // Set focus to input sub input (if node was clicked, but not
- // when TAB was pressed )
- $outer = $(node.tr || node.span);
- $outer.find(":input:enabled:first").focus();
- }
- }
- },
- nodeKeydown: function(ctx) {
- var inputType, handleKeys, $td,
- opts = ctx.options.gridnav,
- event = ctx.originalEvent,
- $target = $(event.target);
-
- if( $target.is(":input:enabled") ) {
- inputType = $target.prop("type");
- } else if( $target.is("a") ) {
- inputType = "link";
- }
- // ctx.tree.debug("ext-gridnav nodeKeydown", event, inputType);
-
- if( inputType && opts.handleCursorKeys ){
- handleKeys = NAV_KEYS[inputType];
- if( handleKeys && $.inArray(event.which, handleKeys) >= 0 ){
- $td = findNeighbourTd($target, event.which);
- if( $td && $td.length ) {
- // ctx.node.debug("ignore keydown in input", event.which, handleKeys);
- $td.find(":input:enabled,a").focus();
- // Prevent Fancytree default navigation
- return false;
- }
- }
- return true;
- }
- // ctx.tree.debug("ext-gridnav NOT HANDLED", event, inputType);
- return this._superApply(arguments);
- }
-});
-}(jQuery, window, document));
-
-/*!
- * jquery.fancytree.persist.js
- *
- * Persist tree status in cookiesRemove or highlight tree nodes, based on a filter.
- * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
- *
- * @depends: js-cookie or jquery-cookie
- *
- * Copyright (c) 2008-2017, Martin Wendt (http://wwWendt.de)
- *
- * Released under the MIT license
- * https://github.com/mar10/fancytree/wiki/LicenseInfo
- *
- * @version 2.23.0
- * @date 2017-05-27T20:09:38Z
- */
-
-;(function($, window, document, undefined) {
-
-"use strict";
-/* global Cookies:false */
-
-/*******************************************************************************
- * Private functions and variables
- */
-var cookieGetter, cookieRemover, cookieSetter,
- _assert = $.ui.fancytree.assert,
- ACTIVE = "active",
- EXPANDED = "expanded",
- FOCUS = "focus",
- SELECTED = "selected";
-
-if( typeof Cookies === "function" ) {
- // Assume https://github.com/js-cookie/js-cookie
- cookieSetter = Cookies.set;
- cookieGetter = Cookies.get;
- cookieRemover = Cookies.remove;
-} else {
- // Fall back to https://github.com/carhartl/jquery-cookie
- cookieSetter = cookieGetter = $.cookie;
- cookieRemover = $.removeCookie;
-}
-
-/* Recursively load lazy nodes
- * @param {string} mode 'load', 'expand', false
- */
-function _loadLazyNodes(tree, local, keyList, mode, dfd) {
- var i, key, l, node,
- foundOne = false,
- expandOpts = tree.options.persist.expandOpts,
- deferredList = [],
- missingKeyList = [];
-
- keyList = keyList || [];
- dfd = dfd || $.Deferred();
-
- for( i=0, l=keyList.length; i 0 ) {
- // If we read new nodes from server, try to resolve yet-missing keys
- _loadLazyNodes(tree, local, missingKeyList, mode, dfd);
- } else {
- if( missingKeyList.length ) {
- tree.warn("_loadLazyNodes: could not load those keys: ", missingKeyList);
- for( i=0, l=missingKeyList.length; i= 0){
- local._data(prefix + ACTIVE, null);
- }
- if(types.indexOf(EXPANDED) >= 0){
- local._data(prefix + EXPANDED, null);
- }
- if(types.indexOf(FOCUS) >= 0){
- local._data(prefix + FOCUS, null);
- }
- if(types.indexOf(SELECTED) >= 0){
- local._data(prefix + SELECTED, null);
- }
-};
-
-
-/**
- * [ext-persist] Return persistence information from cookies
- *
- * Called like
- * $("#tree").fancytree("getTree").getPersistData();
- *
- * @alias Fancytree#getPersistData
- * @requires jquery.fancytree.persist.js
- */
-$.ui.fancytree._FancytreeClass.prototype.getPersistData = function(){
- var local = this.ext.persist,
- prefix = local.cookiePrefix,
- delim = local.cookieDelimiter,
- res = {};
-
- res[ACTIVE] = local._data(prefix + ACTIVE);
- res[EXPANDED] = (local._data(prefix + EXPANDED) || "").split(delim);
- res[SELECTED] = (local._data(prefix + SELECTED) || "").split(delim);
- res[FOCUS] = local._data(prefix + FOCUS);
- return res;
-};
-
-
-/* *****************************************************************************
- * Extension code
- */
-$.ui.fancytree.registerExtension({
- name: "persist",
- version: "2.23.0",
- // Default options for this extension.
- options: {
- cookieDelimiter: "~",
- cookiePrefix: undefined, // 'fancytree--' by default
- cookie: {
- raw: false,
- expires: "",
- path: "",
- domain: "",
- secure: false
- },
- expandLazy: false, // true: recursively expand and load lazy nodes
- expandOpts: undefined, // optional `opts` argument passed to setExpanded()
- fireActivate: true, // false: suppress `activate` event after active node was restored
- overrideSource: true, // true: cookie takes precedence over `source` data attributes.
- store: "auto", // 'cookie': force cookie, 'local': force localStore, 'session': force sessionStore
- types: "active expanded focus selected"
- },
-
- /* Generic read/write string data to cookie, sessionStorage or localStorage. */
- _data: function(key, value){
- var ls = this._local.localStorage; // null, sessionStorage, or localStorage
-
- if( value === undefined ) {
- return ls ? ls.getItem(key) : cookieGetter(key);
- } else if ( value === null ) {
- if( ls ) {
- ls.removeItem(key);
- } else {
- cookieRemover(key);
- }
- } else {
- if( ls ) {
- ls.setItem(key, value);
- } else {
- cookieSetter(key, value, this.options.persist.cookie);
- }
- }
- },
-
- /* Append `key` to a cookie. */
- _appendKey: function(type, key, flag){
- key = "" + key; // #90
- var local = this._local,
- instOpts = this.options.persist,
- delim = instOpts.cookieDelimiter,
- cookieName = local.cookiePrefix + type,
- data = local._data(cookieName),
- keyList = data ? data.split(delim) : [],
- idx = $.inArray(key, keyList);
- // Remove, even if we add a key, so the key is always the last entry
- if(idx >= 0){
- keyList.splice(idx, 1);
- }
- // Append key to cookie
- if(flag){
- keyList.push(key);
- }
- local._data(cookieName, keyList.join(delim));
- },
-
- treeInit: function(ctx){
- var tree = ctx.tree,
- opts = ctx.options,
- local = this._local,
- instOpts = this.options.persist;
-
- // For 'auto' or 'cookie' mode, the cookie plugin must be available
- _assert((instOpts.store !== "auto" && instOpts.store !== "cookie") || cookieGetter,
- "Missing required plugin for 'persist' extension: js.cookie.js or jquery.cookie.js");
-
- local.cookiePrefix = instOpts.cookiePrefix || ("fancytree-" + tree._id + "-");
- local.storeActive = instOpts.types.indexOf(ACTIVE) >= 0;
- local.storeExpanded = instOpts.types.indexOf(EXPANDED) >= 0;
- local.storeSelected = instOpts.types.indexOf(SELECTED) >= 0;
- local.storeFocus = instOpts.types.indexOf(FOCUS) >= 0;
- if( instOpts.store === "cookie" || !window.localStorage ) {
- local.localStorage = null;
- } else {
- local.localStorage = (instOpts.store === "local") ? window.localStorage : window.sessionStorage;
- }
-
- // Bind init-handler to apply cookie state
- tree.$div.bind("fancytreeinit", function(event){
- if ( tree._triggerTreeEvent("beforeRestore", null, {}) === false ) {
- return;
- }
-
- var cookie, dfd, i, keyList, node,
- prevFocus = local._data(local.cookiePrefix + FOCUS), // record this before node.setActive() overrides it;
- noEvents = instOpts.fireActivate === false;
-
- // tree.debug("document.cookie:", document.cookie);
-
- cookie = local._data(local.cookiePrefix + EXPANDED);
- keyList = cookie && cookie.split(instOpts.cookieDelimiter);
-
- if( local.storeExpanded ) {
- // Recursively load nested lazy nodes if expandLazy is 'expand' or 'load'
- // Also remove expand-cookies for unmatched nodes
- dfd = _loadLazyNodes(tree, local, keyList, instOpts.expandLazy ? "expand" : false , null);
- } else {
- // nothing to do
- dfd = new $.Deferred().resolve();
- }
-
- dfd.done(function(){
- if(local.storeSelected){
- cookie = local._data(local.cookiePrefix + SELECTED);
- if(cookie){
- keyList = cookie.split(instOpts.cookieDelimiter);
- for(i=0; i 1 && siblings[0] !== node){
- // use the lowest descendant of the preceeding sibling
- i = $.inArray(node, siblings);
- prev = siblings[i - 1];
- _assert(prev.tr);
- // descend to lowest child (with a
tag)
- while(prev.children && prev.children.length){
- last = prev.children[prev.children.length - 1];
- if(!last.tr){
- break;
- }
- prev = last;
- }
- }else{
- // if there is no preceding sibling, use the direct parent
- prev = parent;
- }
- return prev;
-}
-
-/* Render callback for 'wide' mode. */
-// function _renderStatusNodeWide(event, data) {
-// var node = data.node,
-// nodeColumnIdx = data.options.table.nodeColumnIdx,
-// $tdList = $(node.tr).find(">td");
-
-// $tdList.eq(nodeColumnIdx).attr("colspan", data.tree.columnCount);
-// $tdList.not(":eq(" + nodeColumnIdx + ")").remove();
-// }
-
-
-$.ui.fancytree.registerExtension({
- name: "table",
- version: "2.23.0",
- // Default options for this extension.
- options: {
- checkboxColumnIdx: null, // render the checkboxes into the this column index (default: nodeColumnIdx)
- // customStatus: false, // true: generate renderColumns events for status nodes
- indentation: 16, // indent every node level by 16px
- nodeColumnIdx: 0 // render node expander, icon, and title to this column (default: #0)
- },
- // Overide virtual methods for this extension.
- // `this` : is this extension object
- // `this._super`: the virtual function that was overriden (member of prev. extension or Fancytree)
- treeInit: function(ctx){
- var i, columnCount, n, $row, $tbody,
- tree = ctx.tree,
- opts = ctx.options,
- tableOpts = opts.table,
- $table = tree.widget.element;
-
- if( tableOpts.customStatus != null ) {
- if( opts.renderStatusColumns != null) {
- $.error("The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' only instead.");
- } else {
- tree.warn("The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' instead.");
- opts.renderStatusColumns = tableOpts.customStatus;
- }
- }
- if( opts.renderStatusColumns ) {
- if( opts.renderStatusColumns === true ) {
- opts.renderStatusColumns = opts.renderColumns;
- // } else if( opts.renderStatusColumns === "wide" ) {
- // opts.renderStatusColumns = _renderStatusNodeWide;
- }
- }
-
- $table.addClass("fancytree-container fancytree-ext-table");
- tree.tbody = $table.find(">tbody")[0];
- $tbody = $(tree.tbody);
-
- // Prepare row templates:
- // Determine column count from table header if any
- columnCount = $("thead >tr:last >th", $table).length;
- // Read TR templates from tbody if any
- $row = $tbody.children("tr:first");
- if( $row.length ) {
- n = $row.children("td").length;
- if( columnCount && n !== columnCount ) {
- tree.warn("Column count mismatch between thead (" + columnCount + ") and tbody (" + n + "): using tbody.");
- columnCount = n;
- }
- $row = $row.clone();
- } else {
- // Only thead is defined: create default row markup
- _assert(columnCount >= 1, "Need either or
with
elements to determine column count.");
- $row = $("
");
- for(i=0; i");
- }
- }
- $row.find(">td").eq(tableOpts.nodeColumnIdx)
- .html("");
- if( opts.aria ) {
- $row.attr("role", "row");
- $row.find("td").attr("role", "gridcell");
- }
- tree.rowFragment = document.createDocumentFragment();
- tree.rowFragment.appendChild($row.get(0));
-
- // // If tbody contains a second row, use this as status node template
- // $row = $tbody.children("tr:eq(1)");
- // if( $row.length === 0 ) {
- // tree.statusRowFragment = tree.rowFragment;
- // } else {
- // $row = $row.clone();
- // tree.statusRowFragment = document.createDocumentFragment();
- // tree.statusRowFragment.appendChild($row.get(0));
- // }
- //
- $tbody.empty();
-
- // Make sure that status classes are set on the node's
elements
- tree.statusClassPropName = "tr";
- tree.ariaPropName = "tr";
- this.nodeContainerAttrName = "tr";
-
- // #489: make sure $container is set to
, even if ext-dnd is listed before ext-table
- tree.$container = $table;
-
- this._superApply(arguments);
-
- // standard Fancytree created a root UL
- $(tree.rootNode.ul).remove();
- tree.rootNode.ul = null;
-
- // Add container to the TAB chain
- // #577: Allow to set tabindex to "0", "-1" and ""
- this.$container.attr("tabindex", opts.tabindex);
- // this.$container.attr("tabindex", opts.tabbable ? "0" : "-1");
- if(opts.aria) {
- tree.$container
- .attr("role", "treegrid")
- .attr("aria-readonly", true);
- }
- },
- nodeRemoveChildMarkup: function(ctx) {
- var node = ctx.node;
-// node.debug("nodeRemoveChildMarkup()");
- node.visit(function(n){
- if(n.tr){
- $(n.tr).remove();
- n.tr = null;
- }
- });
- },
- nodeRemoveMarkup: function(ctx) {
- var node = ctx.node;
-// node.debug("nodeRemoveMarkup()");
- if(node.tr){
- $(node.tr).remove();
- node.tr = null;
- }
- this.nodeRemoveChildMarkup(ctx);
- },
- /* Override standard render. */
- nodeRender: function(ctx, force, deep, collapsed, _recursive) {
- var children, firstTr, i, l, newRow, prevNode, prevTr, subCtx,
- tree = ctx.tree,
- node = ctx.node,
- opts = ctx.options,
- isRootNode = !node.parent;
-
- if( tree._enableUpdate === false ) {
- // $.ui.fancytree.debug("*** nodeRender _enableUpdate: false");
- return;
- }
- if( !_recursive ){
- ctx.hasCollapsedParents = node.parent && !node.parent.expanded;
- }
- // $.ui.fancytree.debug("*** nodeRender " + node + ", isRoot=" + isRootNode, "tr=" + node.tr, "hcp=" + ctx.hasCollapsedParents, "parent.tr=" + (node.parent && node.parent.tr));
- if( !isRootNode ){
- if( node.tr && force ) {
- this.nodeRemoveMarkup(ctx);
- }
- if( !node.tr ) {
- if( ctx.hasCollapsedParents && !deep ) {
- // #166: we assume that the parent will be (recursively) rendered
- // later anyway.
- // node.debug("nodeRender ignored due to unrendered parent");
- return;
- }
- // Create new
after previous row
- // if( node.isStatusNode() ) {
- // newRow = tree.statusRowFragment.firstChild.cloneNode(true);
- // } else {
- newRow = tree.rowFragment.firstChild.cloneNode(true);
- // }
- prevNode = findPrevRowNode(node);
- // $.ui.fancytree.debug("*** nodeRender " + node + ": prev: " + prevNode.key);
- _assert(prevNode);
- if(collapsed === true && _recursive){
- // hide all child rows, so we can use an animation to show it later
- newRow.style.display = "none";
- }else if(deep && ctx.hasCollapsedParents){
- // also hide this row if deep === true but any parent is collapsed
- newRow.style.display = "none";
-// newRow.style.color = "red";
- }
- if(!prevNode.tr){
- _assert(!prevNode.parent, "prev. row must have a tr, or be system root");
- // tree.tbody.appendChild(newRow);
- insertFirstChild(tree.tbody, newRow); // #675
- }else{
- insertSiblingAfter(prevNode.tr, newRow);
- }
- node.tr = newRow;
- if( node.key && opts.generateIds ){
- node.tr.id = opts.idPrefix + node.key;
- }
- node.tr.ftnode = node;
- // if(opts.aria){
- // $(node.tr).attr("aria-labelledby", "ftal_" + opts.idPrefix + node.key);
- // }
- node.span = $("span.fancytree-node", node.tr).get(0);
- // Set icon, link, and title (normally this is only required on initial render)
- this.nodeRenderTitle(ctx);
- // Allow tweaking, binding, after node was created for the first time
-// tree._triggerNodeEvent("createNode", ctx);
- if ( opts.createNode ){
- opts.createNode.call(tree, {type: "createNode"}, ctx);
- }
- } else {
- if( force ) {
- // Set icon, link, and title (normally this is only required on initial render)
- this.nodeRenderTitle(ctx); // triggers renderColumns()
- } else {
- // Update element classes according to node state
- this.nodeRenderStatus(ctx);
- }
- }
- }
- // Allow tweaking after node state was rendered
-// tree._triggerNodeEvent("renderNode", ctx);
- if ( opts.renderNode ){
- opts.renderNode.call(tree, {type: "renderNode"}, ctx);
- }
- // Visit child nodes
- // Add child markup
- children = node.children;
- if(children && (isRootNode || deep || node.expanded)){
- for(i=0, l=children.length; i order matches node.children order.
- if(children && !_recursive){ // we only have to do it once, for the root branch
- prevTr = node.tr || null;
- firstTr = tree.tbody.firstChild;
- // Iterate over all descendants
- node.visit(function(n){
- if(n.tr){
- if(!n.parent.expanded && n.tr.style.display !== "none"){
- // fix after a node was dropped over a collapsed
- n.tr.style.display = "none";
- setChildRowVisibility(n, false);
- }
- if(n.tr.previousSibling !== prevTr){
- node.debug("_fixOrder: mismatch at node: " + n);
- var nextTr = prevTr ? prevTr.nextSibling : firstTr;
- tree.tbody.insertBefore(n.tr, nextTr);
- }
- prevTr = n.tr;
- }
- });
- }
- // Update element classes according to node state
- // if(!isRootNode){
- // this.nodeRenderStatus(ctx);
- // }
- },
- nodeRenderTitle: function(ctx, title) {
- var $cb, res,
- node = ctx.node,
- opts = ctx.options,
- isStatusNode = node.isStatusNode();
-
- res = this._super(ctx, title);
-
- if( node.isRootNode() ) {
- return res;
- }
- // Move checkbox to custom column
- if(opts.checkbox && !isStatusNode && opts.table.checkboxColumnIdx != null ){
- $cb = $("span.fancytree-checkbox", node.span); //.detach();
- $(node.tr).find("td").eq(+opts.table.checkboxColumnIdx).html($cb);
- }
- // Update element classes according to node state
- this.nodeRenderStatus(ctx);
-
- if( isStatusNode ) {
- if( opts.renderStatusColumns ) {
- // Let user code write column content
- opts.renderStatusColumns.call(ctx.tree, {type: "renderStatusColumns"}, ctx);
- } // else: default rendering for status node: leave other cells empty
- } else if ( opts.renderColumns ) {
- opts.renderColumns.call(ctx.tree, {type: "renderColumns"}, ctx);
- }
- return res;
- },
- nodeRenderStatus: function(ctx) {
- var indent,
- node = ctx.node,
- opts = ctx.options;
-
- this._super(ctx);
-
- $(node.tr).removeClass("fancytree-node");
- // indent
- indent = (node.getLevel() - 1) * opts.table.indentation;
- $(node.span).css({paddingLeft: indent + "px"}); // #460
- // $(node.span).css({marginLeft: indent + "px"});
- },
- /* Expand node, return Deferred.promise. */
- nodeSetExpanded: function(ctx, flag, callOpts) {
- // flag defaults to true
- flag = (flag !== false);
-
- if((ctx.node.expanded && flag) || (!ctx.node.expanded && !flag)) {
- // Expanded state isn't changed - just call base implementation
- return this._superApply(arguments);
- }
-
- var dfd = new $.Deferred(),
- subOpts = $.extend({}, callOpts, {noEvents: true, noAnimation: true});
-
- callOpts = callOpts || {};
-
- function _afterExpand(ok) {
- setChildRowVisibility(ctx.node, flag);
- if( ok ) {
- if( flag && ctx.options.autoScroll && !callOpts.noAnimation && ctx.node.hasChildren() ) {
- // Scroll down to last child, but keep current node visible
- ctx.node.getLastChild().scrollIntoView(true, {topNode: ctx.node}).always(function(){
- if( !callOpts.noEvents ) {
- ctx.tree._triggerNodeEvent(flag ? "expand" : "collapse", ctx);
- }
- dfd.resolveWith(ctx.node);
- });
- } else {
- if( !callOpts.noEvents ) {
- ctx.tree._triggerNodeEvent(flag ? "expand" : "collapse", ctx);
- }
- dfd.resolveWith(ctx.node);
- }
- } else {
- if( !callOpts.noEvents ) {
- ctx.tree._triggerNodeEvent(flag ? "expand" : "collapse", ctx);
- }
- dfd.rejectWith(ctx.node);
- }
- }
- // Call base-expand with disabled events and animation
- this._super(ctx, flag, subOpts).done(function () {
- _afterExpand(true);
- }).fail(function () {
- _afterExpand(false);
- });
- return dfd.promise();
- },
- nodeSetStatus: function(ctx, status, message, details) {
- if(status === "ok"){
- var node = ctx.node,
- firstChild = ( node.children ? node.children[0] : null );
- if ( firstChild && firstChild.isStatusNode() ) {
- $(firstChild.tr).remove();
- }
- }
- return this._superApply(arguments);
- },
- treeClear: function(ctx) {
- this.nodeRemoveChildMarkup(this._makeHookContext(this.rootNode));
- return this._superApply(arguments);
- },
- treeDestroy: function(ctx) {
- this.$container.find("tbody").empty();
- this.$source && this.$source.removeClass("ui-helper-hidden");
- return this._superApply(arguments);
- }
- /*,
- treeSetFocus: function(ctx, flag) {
-// alert("treeSetFocus" + ctx.tree.$container);
- ctx.tree.$container.focus();
- $.ui.fancytree.focusTree = ctx.tree;
- }*/
-});
-}(jQuery, window, document));
-
-/*!
- * jquery.fancytree.themeroller.js
- *
- * Enable jQuery UI ThemeRoller styles.
- * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
- *
- * @see http://jqueryui.com/themeroller/
- *
- * Copyright (c) 2008-2017, Martin Wendt (http://wwWendt.de)
- *
- * Released under the MIT license
- * https://github.com/mar10/fancytree/wiki/LicenseInfo
- *
- * @version 2.23.0
- * @date 2017-05-27T20:09:38Z
- */
-
-;(function($, window, document, undefined) {
-
-"use strict";
-
-/*******************************************************************************
- * Extension code
- */
-$.ui.fancytree.registerExtension({
- name: "themeroller",
- version: "2.23.0",
- // Default options for this extension.
- options: {
- activeClass: "ui-state-active", // Class added to active node
- // activeClass: "ui-state-highlight",
- addClass: "ui-corner-all", // Class added to all nodes
- focusClass: "ui-state-focus", // Class added to focused node
- hoverClass: "ui-state-hover", // Class added to hovered node
- selectedClass: "ui-state-highlight" // Class added to selected nodes
- // selectedClass: "ui-state-active"
- },
-
- treeInit: function(ctx){
- var $el = ctx.widget.element,
- opts = ctx.options.themeroller;
-
- this._superApply(arguments);
-
- if($el[0].nodeName === "TABLE"){
- $el.addClass("ui-widget ui-corner-all");
- $el.find(">thead tr").addClass("ui-widget-header");
- $el.find(">tbody").addClass("ui-widget-conent");
- }else{
- $el.addClass("ui-widget ui-widget-content ui-corner-all");
- }
-
- $el.delegate(".fancytree-node", "mouseenter mouseleave", function(event){
- var node = $.ui.fancytree.getNode(event.target),
- flag = (event.type === "mouseenter");
-
- $(node.tr ? node.tr : node.span)
- .toggleClass(opts.hoverClass + " " + opts.addClass, flag);
- });
- },
- treeDestroy: function(ctx){
- this._superApply(arguments);
- ctx.widget.element.removeClass("ui-widget ui-widget-content ui-corner-all");
- },
- nodeRenderStatus: function(ctx){
- var classes = {},
- node = ctx.node,
- $el = $(node.tr ? node.tr : node.span),
- opts = ctx.options.themeroller;
-
- this._super(ctx);
-/*
- .ui-state-highlight: Class to be applied to highlighted or selected elements. Applies "highlight" container styles to an element and its child text, links, and icons.
- .ui-state-error: Class to be applied to error messaging container elements. Applies "error" container styles to an element and its child text, links, and icons.
- .ui-state-error-text: An additional class that applies just the error text color without background. Can be used on form labels for instance. Also applies error icon color to child icons.
-
- .ui-state-default: Class to be applied to clickable button-like elements. Applies "clickable default" container styles to an element and its child text, links, and icons.
- .ui-state-hover: Class to be applied on mouseover to clickable button-like elements. Applies "clickable hover" container styles to an element and its child text, links, and icons.
- .ui-state-focus: Class to be applied on keyboard focus to clickable button-like elements. Applies "clickable hover" container styles to an element and its child text, links, and icons.
- .ui-state-active: Class to be applied on mousedown to clickable button-like elements. Applies "clickable active" container styles to an element and its child text, links, and icons.
-*/
- // Set ui-state-* class (handle the case that the same class is assigned
- // to different states)
- classes[opts.activeClass] = false;
- classes[opts.focusClass] = false;
- classes[opts.selectedClass] = false;
- if( node.isActive() ) { classes[opts.activeClass] = true; }
- if( node.hasFocus() ) { classes[opts.focusClass] = true; }
- // activeClass takes precedence before selectedClass:
- if( node.isSelected() && !node.isActive() ) { classes[opts.selectedClass] = true; }
- $el.toggleClass(opts.activeClass, classes[opts.activeClass]);
- $el.toggleClass(opts.focusClass, classes[opts.focusClass]);
- $el.toggleClass(opts.selectedClass, classes[opts.selectedClass]);
- // Additional classes (e.g. 'ui-corner-all')
- $el.addClass(opts.addClass);
- }
-});
-}(jQuery, window, document));
-
-/*!
- * jquery.fancytree.wide.js
- * Support for 100% wide selection bars.
- * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
- *
- * Copyright (c) 2008-2017, Martin Wendt (http://wwWendt.de)
- *
- * Released under the MIT license
- * https://github.com/mar10/fancytree/wiki/LicenseInfo
- *
- * @version 2.23.0
- * @date 2017-05-27T20:09:38Z
- */
-
-;(function($, window, document, undefined) {
-
-"use strict";
-
-var reNumUnit = /^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/; // split "1.5em" to ["1.5", "em"]
-
-/*******************************************************************************
- * Private functions and variables
- */
-// var _assert = $.ui.fancytree.assert;
-
-/* Calculate inner width without scrollbar */
-// function realInnerWidth($el) {
-// // http://blog.jquery.com/2012/08/16/jquery-1-8-box-sizing-width-csswidth-and-outerwidth/
-// // inst.contWidth = parseFloat(this.$container.css("width"), 10);
-// // 'Client width without scrollbar' - 'padding'
-// return $el[0].clientWidth - ($el.innerWidth() - parseFloat($el.css("width"), 10));
-// }
-
-/* Create a global embedded CSS style for the tree. */
-function defineHeadStyleElement(id, cssText) {
- id = "fancytree-style-" + id;
- var $headStyle = $("#" + id);
-
- if( !cssText ) {
- $headStyle.remove();
- return null;
- }
- if( !$headStyle.length ) {
- $headStyle = $("")
- .attr("id", id)
- .addClass("fancytree-style")
- .prop("type", "text/css")
- .appendTo("head");
- }
- try {
- $headStyle.html(cssText);
- } catch ( e ) {
- // fix for IE 6-8
- $headStyle[0].styleSheet.cssText = cssText;
- }
- return $headStyle;
-}
-
-/* Calculate the CSS rules that indent title spans. */
-function renderLevelCss(containerId, depth, levelOfs, lineOfs, labelOfs, measureUnit)
-{
- var i,
- prefix = "#" + containerId + " span.fancytree-level-",
- rules = [];
-
- for(i = 0; i < depth; i++) {
- rules.push(prefix + (i + 1) + " span.fancytree-title { padding-left: " +
- (i * levelOfs + lineOfs) + measureUnit + "; }");
- }
- // Some UI animations wrap the UL inside a DIV and set position:relative on both.
- // This breaks the left:0 and padding-left:nn settings of the title
- rules.push(
- "#" + containerId + " div.ui-effects-wrapper ul li span.fancytree-title, " +
- "#" + containerId + " ul.fancytree-animating span.fancytree-title " + // #716
- "{ padding-left: " + labelOfs + measureUnit + "; position: static; width: auto; }");
- return rules.join("\n");
-}
-
-
-// /**
-// * [ext-wide] Recalculate the width of the selection bar after the tree container
-// * was resized.
-// * May be called explicitly on container resize, since there is no resize event
-// * for DIV tags.
-// *
-// * @alias Fancytree#wideUpdate
-// * @requires jquery.fancytree.wide.js
-// */
-// $.ui.fancytree._FancytreeClass.prototype.wideUpdate = function(){
-// var inst = this.ext.wide,
-// prevCw = inst.contWidth,
-// prevLo = inst.lineOfs;
-
-// inst.contWidth = realInnerWidth(this.$container);
-// // Each title is precceeded by 2 or 3 icons (16px + 3 margin)
-// // + 1px title border and 3px title padding
-// // TODO: use code from treeInit() below
-// inst.lineOfs = (this.options.checkbox ? 3 : 2) * 19;
-// if( prevCw !== inst.contWidth || prevLo !== inst.lineOfs ) {
-// this.debug("wideUpdate: " + inst.contWidth);
-// this.visit(function(node){
-// node.tree._callHook("nodeRenderTitle", node);
-// });
-// }
-// };
-
-/*******************************************************************************
- * Extension code
- */
-$.ui.fancytree.registerExtension({
- name: "wide",
- version: "2.23.0",
- // Default options for this extension.
- options: {
- iconWidth: null, // Adjust this if @fancy-icon-width != "16px"
- iconSpacing: null, // Adjust this if @fancy-icon-spacing != "3px"
- labelSpacing: null, // Adjust this if padding between icon and label != "3px"
- levelOfs: null // Adjust this if ul padding != "16px"
- },
-
- treeCreate: function(ctx){
- this._superApply(arguments);
- this.$container.addClass("fancytree-ext-wide");
-
- var containerId, cssText, iconSpacingUnit, labelSpacingUnit, iconWidthUnit, levelOfsUnit,
- instOpts = ctx.options.wide,
- // css sniffing
- $dummyLI = $("
",{"class":"ui-fancytree fancytree-container fancytree-plain"}).appendTo(this.$div),this.$container=c,this.rootNode.ul=c[0],null==this.options.debugLevel&&(this.options.debugLevel=w.debugLevel)}if(a.ui&&a.ui.fancytree)return void a.ui.fancytree.warn("Fancytree: ignored duplicate include");var u,v,w=null,x=new RegExp(/\.|\//),y=/[&<>"'\/]/g,z=/[<>"'\/]/g,A="$recursive_request",B={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},C={16:!0,17:!0,18:!0},D={8:"backspace",9:"tab",10:"return",13:"return",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",59:";",61:"=",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scroll",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},E={0:"",1:"left",2:"middle",3:"right"},F="active expanded focus folder lazy radiogroup selected unselectable unselectableIgnore".split(" "),G={},H="checkbox expanded extraClasses folder icon key lazy radiogroup refKey selected statusNodeType title tooltip unselectable unselectableIgnore unselectableStatus".split(" "),I={},J={},K={active:!0,children:!0,data:!0,focus:!0};for(u=0;u=0,"insertBefore must be an existing child"),this.children.splice.apply(this.children,[g,0].concat(k))),h&&!c){for(d=0,f=k.length;d=0;d--)e=this.children[d],"paging"===e.statusNodeType&&this.removeChild(e);return void(this.partload=!1)}return b=a.extend({title:this.tree.options.strings.moreData,statusNodeType:"paging",icon:!1},b),this.partload=!0,this.addNode(b,c)},appendSibling:function(a){return this.addNode(a,"after")},applyPatch:function(b){if(null===b)return this.remove(),k(this);var c,d,e,f={children:!0,expanded:!0,parent:!0};for(c in b)e=b[c],f[c]||a.isFunction(e)||(I[c]?this[c]=e:this.data[c]=e);return b.hasOwnProperty("children")&&(this.removeChildren(),b.children&&this._setChildren(b.children)),this.isVisible()&&(this.renderTitle(),this.renderStatus()),d=b.hasOwnProperty("expanded")?this.setExpanded(b.expanded):k(this)},collapseSiblings:function(){return this.tree._callHook("nodeCollapseSiblings",this)},copyTo:function(a,b,c){return a.addNode(this.toDict(!0,c),b)},countChildren:function(a){var b,c,d,e=this.children;if(!e)return 0;if(d=e.length,a!==!1)for(b=0,c=d;b=2&&(Array.prototype.unshift.call(arguments,this.toString()),f("log",arguments))},discard:function(){return this.warn("FancytreeNode.discard() is deprecated since 2014-02-16. Use .resetLazy() instead."),this.resetLazy()},discardMarkup:function(a){var b=a?"nodeRemoveMarkup":"nodeRemoveChildMarkup";this.tree._callHook(b,this)},findAll:function(b){b=a.isFunction(b)?b:q(b);var c=[];return this.visit(function(a){b(a)&&c.push(a)}),c},findFirst:function(b){b=a.isFunction(b)?b:q(b);var c=null;return this.visit(function(a){if(b(a))return c=a,!1}),c},_changeSelectStatusAttrs:function(a){var b=!1,c=this.tree.options,f=w.evalOption("unselectable",this,this,c,!1),g=w.evalOption("unselectableStatus",this,this,c,d);switch(f&&null!=g&&(a=g),a){case!1:b=this.selected||this.partsel,this.selected=!1,this.partsel=!1;break;case!0:b=!this.selected||!this.partsel,this.selected=!0,this.partsel=!0;break;case d:b=this.selected||!this.partsel,this.selected=!1,this.partsel=!0;break;default:e(!1,"invalid state: "+a)}return b&&this.renderStatus(),b},fixSelection3AfterClick:function(a){var b=this.isSelected();this.visit(function(a){a._changeSelectStatusAttrs(b)}),this.fixSelection3FromEndNodes(a)},fixSelection3FromEndNodes:function(a){function b(a){var e,f,g,h,i,j,k,l,m,n=a.children;if(n&&n.length){for(j=!0,k=!1,e=0,f=n.length;e=1&&(Array.prototype.unshift.call(arguments,this.toString()),f("info",arguments))},isActive:function(){return this.tree.activeNode===this},isChildOf:function(a){return this.parent&&this.parent===a},isDescendantOf:function(a){if(!a||a.tree!==this.tree)return!1;for(var b=this.parent;b;){if(b===a)return!0;b=b.parent}return!1},isExpanded:function(){return!!this.expanded},isFirstSibling:function(){var a=this.parent;return!a||a.children[0]===this},isFolder:function(){return!!this.folder},isLastSibling:function(){var a=this.parent;return!a||a.children[a.children.length-1]===this},isLazy:function(){return!!this.lazy},isLoaded:function(){return!this.lazy||this.hasChildren()!==d},isLoading:function(){return!!this._isLoading},isRoot:function(){return this.isRootNode()},isPartsel:function(){return!this.selected&&!!this.partsel},isPartload:function(){return!!this.partload},isRootNode:function(){return this.tree.rootNode===this},isSelected:function(){return!!this.selected},isStatusNode:function(){return!!this.statusNodeType},isPagingNode:function(){return"paging"===this.statusNodeType},isTopLevel:function(){return this.tree.rootNode===this.parent},isUndefined:function(){return this.hasChildren()===d},isVisible:function(){var a,b,c=this.getParentList(!1,!1);for(a=0,b=c.length;a=0;c--)e.push(g[c].setExpanded(!0,b));return a.when.apply(a,e).done(function(){j?d.scrollIntoView(i).done(function(){f.resolve()}):f.resolve()}),f.promise()},moveTo:function(b,c,f){c===d||"over"===c?c="child":"firstChild"===c&&(b.children&&b.children.length?(c="before",b=b.children[0]):c="child");var g,h=this.parent,i="child"===c?b:b.parent;if(this!==b){if(this.parent?i.isDescendantOf(this)&&a.error("Cannot move a node to its own descendant"):a.error("Cannot move system root"),i!==h&&h.triggerModifyChild("remove",this),1===this.parent.children.length){if(this.parent===i)return;this.parent.children=this.parent.lazy?[]:null,this.parent.expanded=!1}else g=a.inArray(this,this.parent.children),e(g>=0,"invalid source parent"),this.parent.children.splice(g,1);if(this.parent=i,i.hasChildren())switch(c){case"child":i.children.push(this);break;case"before":g=a.inArray(b,i.children),e(g>=0,"invalid target parent"),i.children.splice(g,0,this);break;case"after":g=a.inArray(b,i.children),e(g>=0,"invalid target parent"),i.children.splice(g+1,0,this);break;default:a.error("Invalid mode "+c)}else i.children=[this];f&&b.visit(f,!0),i===h?i.triggerModifyChild("move",this):i.triggerModifyChild("add",this),this.tree!==b.tree&&(this.warn("Cross-tree moveTo is experimantal!"),this.visit(function(a){a.tree=b.tree},!0)),h.isDescendantOf(i)||h.render(),i.isDescendantOf(h)||i===h||i.render()}},navigate:function(b,c){function d(d){if(d){try{d.makeVisible({scrollIntoView:!1})}catch(e){}return a(d.span).is(":visible")?c===!1?d.setFocus():d.setActive():(d.debug("Navigate: skipping hidden node"),void d.navigate(b,c))}}var e,f,g,h=!0,i=a.ui.keyCode,j=null;switch(b){case i.BACKSPACE:this.parent&&this.parent.parent&&(g=d(this.parent));break;case i.HOME:this.tree.visit(function(b){if(a(b.span).is(":visible"))return g=d(b),!1});break;case i.END:this.tree.visit(function(b){a(b.span).is(":visible")&&(g=b)}),g&&(g=d(g));break;case i.LEFT:this.expanded?(this.setExpanded(!1),g=d(this)):this.parent&&this.parent.parent&&(g=d(this.parent));break;case i.RIGHT:this.expanded||!this.children&&!this.lazy?this.children&&this.children.length&&(g=d(this.children[0])):(this.setExpanded(),g=d(this));break;case i.UP:for(j=this.getPrevSibling();j&&!a(j.span).is(":visible");)j=j.getPrevSibling();for(;j&&j.expanded&&j.children&&j.children.length;)j=j.children[j.children.length-1];!j&&this.parent&&this.parent.parent&&(j=this.parent),g=d(j);break;case i.DOWN:if(this.expanded&&this.children&&this.children.length)j=this.children[0];else for(f=this.getParentList(!1,!0),e=f.length-1;e>=0;e--){for(j=f[e].getNextSibling();j&&!a(j.span).is(":visible");)j=j.getNextSibling();if(j)break}g=d(j);break;default:h=!1}return g||k()},remove:function(){return this.parent.removeChild(this)},removeChild:function(a){return this.tree._callHook("nodeRemoveChild",this,a)},removeChildren:function(){return this.tree._callHook("nodeRemoveChildren",this)},removeClass:function(a){return this.toggleClass(a,!1)},render:function(a,b){return this.tree._callHook("nodeRender",this,a,b)},renderTitle:function(){return this.tree._callHook("nodeRenderTitle",this)},renderStatus:function(){return this.tree._callHook("nodeRenderStatus",this)},replaceWith:function(b){var c,d=this.parent,f=a.inArray(this,d.children),g=this;return e(this.isPagingNode(),"replaceWith() currently requires a paging status node"),c=this.tree._callHook("nodeLoadChildren",this,b),c.done(function(a){var b=g.children;for(u=0;uv+u-t&&(z=j+q-u+t,y&&(e(y.isRootNode()||a(y.span).is(":visible"),"topNode must be visible"),id?1:-1},e.sort(a),b)for(c=0,d=e.length;c=0,c=c===d?!f:!!c)f||(l+=e+" ",j=!0);else for(;l.indexOf(" "+e+" ")>-1;)l=l.replace(" "+e+" "," ");return this.extraClasses=a.trim(l),j},toggleExpanded:function(){return this.tree._callHook("nodeToggleExpanded",this)},toggleSelected:function(){return this.tree._callHook("nodeToggleSelected",this)},toString:function(){return""},triggerModifyChild:function(b,c,d){var e,f=this.tree.options.modifyChild;f&&(c&&c.parent!==this&&a.error("childNode "+c+" is not a child of "+this),e={node:this,tree:this.tree,operation:b,childNode:c||null},d&&a.extend(e,d),f({type:"modifyChild"},e))},triggerModify:function(a,b){this.parent.triggerModifyChild(a,this,b)},visit:function(a,b){var c,d,e=!0,f=this.children;if(b===!0&&(e=a(this),e===!1||"skip"===e))return e;if(f)for(c=0,d=f.length;c=2&&(Array.prototype.unshift.call(arguments,this.toString()),f("log",arguments))},enableUpdate:function(a){return a=a!==!1,!!this._enableUpdate==!!a?a:(this._enableUpdate=a,a?(this.debug("enableUpdate(true): redraw "),this.render()):this.debug("enableUpdate(false)..."),!a)},findAll:function(a){return this.rootNode.findAll(a)},findFirst:function(a){return this.rootNode.findFirst(a)},findNextNode:function(b,c,d){var e=null,f=c.parent.children,g=null,h=function(a,b,c){var d,e,f=a.children,g=f.length,i=f[b];if(i&&c(i)===!1)return!1;if(i&&i.children&&i.expanded&&h(i,0,c)===!1)return!1;for(d=b+1;d",{type:"checkbox",name:g,value:b.key,checked:!0}))}d=d||{};var f,g="string"==typeof b?b:"ft_"+this._id+"[]",h="string"==typeof c?c:"ft_"+this._id+"_active",i="fancytree_result_"+this._id,j=a("#"+i),k=3===this.options.selectMode&&d.stopOnParents!==!1;j.length?j.empty():j=a("
",{id:i}).hide().insertAfter(this.$container),c!==!1&&this.activeNode&&j.append(a("",{type:"radio",name:h,value:this.activeNode.key,checked:!0})),d.filter?this.visit(function(a){var b=d.filter(a);return"skip"===b?b:void(b!==!1&&e(a))}):b!==!1&&(f=this.getSelectedNodes(k),a.each(f,function(a,b){e(b)}))},getActiveNode:function(){return this.activeNode},getFirstChild:function(){return this.rootNode.getFirstChild()},getFocusNode:function(){return this.focusNode},getNodeByKey:function(a,b){var d,e;return!b&&(d=c.getElementById(this.options.idPrefix+a))?d.ftnode?d.ftnode:null:(b=b||this.rootNode,e=null,b.visit(function(b){if(b.key===a)return e=b,!1},!0),e)},getRootNode:function(){return this.rootNode},getSelectedNodes:function(a){return this.rootNode.getSelectedNodes(a)},hasFocus:function(){return!!this._hasFocus},info:function(a){this.options.debugLevel>=1&&(Array.prototype.unshift.call(arguments,this.toString()),f("info",arguments))},loadKeyPath:function(b,c,e){function f(a,b,d){c.call(r,b,"loading"),b.load().done(function(){r.loadKeyPath.call(r,l[a],c,b).always(m(d,r))}).fail(function(e){r.warn("loadKeyPath: error loading: "+a+" (parent: "+o+")"),c.call(r,b,"error"),d.reject()})}var g,h,i,j,k,l,n,o,p,q=this.options.keyPathSeparator,r=this;for(c=c||a.noop,a.isArray(b)||(b=[b]),l={},i=0;i"},_triggerNodeEvent:function(a,b,c,e){var f=this._makeHookContext(b,c,e),g=this.widget._trigger(a,c,f);return g!==!1&&f.result!==d?f.result:g},_triggerTreeEvent:function(a,b,c){var e=this._makeHookContext(this,b,c),f=this.widget._trigger(a,b,e);return f!==!1&&e.result!==d?e.result:f},visit:function(a){return this.rootNode.visit(a,!1)},warn:function(a){Array.prototype.unshift.call(arguments,this.toString()),f("warn",arguments)}},a.extend(t.prototype,{nodeClick:function(a){var b,c,d=a.targetType,e=a.node;if("expander"===d){if(e.isLoading())return void e.debug("Got 2nd click while loading: ignored");this._callHook("nodeToggleExpanded",a)}else if("checkbox"===d)this._callHook("nodeToggleSelected",a),a.options.focusOnSelect&&this._callHook("nodeSetFocus",a,!0);else{if(c=!1,b=!0,e.folder)switch(a.options.clickFolderMode){case 2:c=!0,b=!1;break;case 3:b=!0,c=!0}b&&(this.nodeSetFocus(a),this._callHook("nodeSetActive",a,!0)),c&&this._callHook("nodeToggleExpanded",a)}},nodeCollapseSiblings:function(a,b){var c,d,e,f=a.node;if(f.parent)for(c=f.parent.children,d=0,e=c.length;d500&&(i.lastQuicksearchTerm=""),i.lastQuicksearchTime=d,i.lastQuicksearchTerm+=l,c=i.findNextNode(i.lastQuicksearchTerm,i.getActiveNode()),c&&c.setActive(),void g.preventDefault();switch(w.eventToString(g)){case"+":case"=":i.nodeSetExpanded(b,!0);break;case"-":i.nodeSetExpanded(b,!1);break;case"space":h.isPagingNode()?i._triggerNodeEvent("clickPaging",b,g):j.checkbox?i.nodeToggleSelected(b):i.nodeSetActive(b,!0);break;case"return":i.nodeSetActive(b,!0);break;case"home":case"end":case"backspace":case"left":case"right":case"up":case"down":e=h.navigate(g.which,p,!0);break;default:o=!1}o&&g.preventDefault()},nodeLoadChildren:function(b,c){var d,f,g,h=b.tree,i=b.node,j=(new Date).getTime();return a.isFunction(c)&&(c=c.call(h,{type:"source"},b),e(!a.isFunction(c),"source callback must not return another function")),c.url&&(i._requestId&&i.warn("Recursive load request #"+j+" while #"+i._requestId+" is pending."),d=a.extend({},b.options.ajax,c),i._requestId=j,d.debugDelay?(f=d.debugDelay,a.isArray(f)&&(f=f[0]+Math.random()*(f[1]-f[0])),i.warn("nodeLoadChildren waiting debugDelay "+Math.round(f)+" ms ..."),d.debugDelay=!1,g=a.Deferred(function(b){setTimeout(function(){a.ajax(d).done(function(){b.resolveWith(this,arguments)}).fail(function(){b.rejectWith(this,arguments)})},f)})):g=a.ajax(d),c=new a.Deferred,g.done(function(d,e,f){var g,k;if("json"!==this.dataType&&"jsonp"!==this.dataType||"string"!=typeof d||a.error("Ajax request returned a string (did you get the JSON dataType wrong?)."),i._requestId&&i._requestId>j)return void c.rejectWith(this,[A]);if(b.options.postProcess){try{k=h._triggerNodeEvent("postProcess",b,b.originalEvent,{response:d,error:null,dataType:this.dataType})}catch(l){k={error:l,message:""+l,details:"postProcess failed"}}if(k.error)return g=a.isPlainObject(k.error)?k.error:{message:k.error},g=h._makeHookContext(i,null,g),void c.rejectWith(this,[g]);d=a.isArray(k)?k:d}else d&&d.hasOwnProperty("d")&&b.options.enableAspx&&(d="string"==typeof d.d?a.parseJSON(d.d):d.d);c.resolveWith(this,[d])}).fail(function(a,b,d){var e=h._makeHookContext(i,null,{error:a,args:Array.prototype.slice.call(arguments),message:d,details:a.status+": "+d});c.rejectWith(this,[e])})),a.isFunction(c.then)&&a.isFunction(c["catch"])&&(g=c,
-c=new a.Deferred,g.then(function(a){c.resolve(a)},function(a){c.reject(a)})),a.isFunction(c.promise)&&(h.nodeSetStatus(b,"loading"),c.done(function(a){h.nodeSetStatus(b,"ok"),i._requestId=null}).fail(function(a){var c;return a===A?void i.warn("Ignored response for obsolete load request #"+j+" (expected #"+i._requestId+")"):(a.node&&a.error&&a.message?c=a:(c=h._makeHookContext(i,null,{error:a,args:Array.prototype.slice.call(arguments),message:a?a.message||a.toString():""}),"[object Object]"===c.message&&(c.message="")),i.warn("Load children failed ("+c.message+")",c),void(h._triggerNodeEvent("loadError",c,null)!==!1&&h.nodeSetStatus(b,"error",c.message,c.details)))})),a.when(c).done(function(b){var c;a.isPlainObject(b)&&(e(i.isRootNode(),"source may only be an object for root nodes (expecting an array of child objects otherwise)"),e(a.isArray(b.children),"if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')"),c=b,b=b.children,delete c.children,a.extend(h.data,c)),e(a.isArray(b),"expected array of children"),i._setChildren(b),h._triggerNodeEvent("loadChildren",i)})},nodeLoadKeyPath:function(a,b){},nodeRemoveChild:function(b,c){var d,f=b.node,g=a.extend({},b,{node:c}),h=f.children;return 1===h.length?(e(c===h[0],"invalid single child"),this.nodeRemoveChildren(b)):(this.activeNode&&(c===this.activeNode||this.activeNode.isDescendantOf(c))&&this.activeNode.setActive(!1),this.focusNode&&(c===this.focusNode||this.focusNode.isDescendantOf(c))&&(this.focusNode=null),this.nodeRemoveMarkup(g),this.nodeRemoveChildren(g),d=a.inArray(c,h),e(d>=0,"invalid child"),f.triggerModifyChild("remove",c),c.visit(function(a){a.parent=null},!0),this._callHook("treeRegisterNode",this,!1,c),void h.splice(d,1))},nodeRemoveChildMarkup:function(b){var c=b.node;c.ul&&(c.isRootNode()?a(c.ul).empty():(a(c.ul).remove(),c.ul=null),c.visit(function(a){a.li=a.ul=null}))},nodeRemoveChildren:function(b){var c,d=b.tree,e=b.node,f=e.children;f&&(this.activeNode&&this.activeNode.isDescendantOf(e)&&this.activeNode.setActive(!1),this.focusNode&&this.focusNode.isDescendantOf(e)&&(this.focusNode=null),this.nodeRemoveChildMarkup(b),c=a.extend({},b),e.triggerModifyChild("remove",null),e.visit(function(a){a.parent=null,d._callHook("treeRegisterNode",d,!1,a)}),e.lazy?e.children=[]:e.children=null,e.isRootNode()||(e.expanded=!1),this.nodeRenderStatus(b))},nodeRemoveMarkup:function(b){var c=b.node;c.li&&(a(c.li).remove(),c.li=null),this.nodeRemoveChildMarkup(b)},nodeRender:function(b,d,f,g,h){var i,j,k,l,m,n,o,p=b.node,q=b.tree,r=b.options,s=r.aria,t=!1,u=p.parent,v=!u,w=p.children,x=null;if(q._enableUpdate!==!1&&(v||u.ul)){if(e(v||u.ul,"parent UL must exist"),v||(p.li&&(d||p.li.parentNode!==p.parent.ul)&&(p.li.parentNode===p.parent.ul?x=p.li.nextSibling:this.debug("Unlinking "+p+" (must be child of "+p.parent+")"),this.nodeRemoveMarkup(b)),p.li?this.nodeRenderStatus(b):(t=!0,p.li=c.createElement("li"),p.li.ftnode=p,p.key&&r.generateIds&&(p.li.id=r.idPrefix+p.key),p.span=c.createElement("span"),p.span.className="fancytree-node",s&&!p.tr&&a(p.li).attr("role","treeitem"),p.li.appendChild(p.span),this.nodeRenderTitle(b),r.createNode&&r.createNode.call(q,{type:"createNode"},b)),r.renderNode&&r.renderNode.call(q,{type:"renderNode"},b)),w){if(v||p.expanded||f===!0){for(p.ul||(p.ul=c.createElement("ul"),(g!==!0||h)&&p.expanded||(p.ul.style.display="none"),s&&a(p.ul).attr("role","group"),p.li?p.li.appendChild(p.ul):p.tree.$div.append(p.ul)),l=0,m=w.length;l1&&s.push("")):s.push(""),e=w.evalOption("checkbox",l,l,n,!1),e&&!l.isStatusNode()&&(i=q?" role='checkbox'":"",f="fancytree-checkbox",("radio"===e||l.parent&&l.parent.radiogroup)&&(f+=" fancytree-radio"),s.push("")),l.data.iconClass!==d&&(l.icon?a.error("'iconClass' node option is deprecated since v2.14.0: use 'icon' only instead"):(l.warn("'iconClass' node option is deprecated since v2.14.0: use 'icon' instead"),l.icon=l.data.iconClass)),g=w.evalOption("icon",l,l,n,!0),"boolean"!=typeof g&&(g=""+g),g!==!1&&(i=q?" role='presentation'":"","string"==typeof g?x.test(g)?(g="/"===g.charAt(0)?g:(n.imagePath||"")+g,s.push("")):s.push(""):s.push("")),h="",n.renderTitle&&(h=n.renderTitle.call(m,{type:"renderTitle"},b)||""),h||(k=w.evalOption("tooltip",l,l,n,null),k===!0&&(k=l.title),k=k?" title='"+p(k)+"'":"",j=n.titlesTabbable?" tabindex='0'":"",h=""+(n.escapeTitles?o(l.title):l.title)+""),s.push(h),l.span.innerHTML=s.join(""),this.nodeRenderStatus(b),n.enhanceTitle&&(b.$title=a(">span.fancytree-title",l.span),h=n.enhanceTitle.call(m,{type:"enhanceTitle"},b)||""))},nodeRenderStatus:function(b){var c,d=b.node,e=b.tree,f=b.options,g=d.hasChildren(),h=d.isLastSibling(),i=f.aria,j=f._classNames,k=[],l=d[e.statusClassPropName];l&&e._enableUpdate!==!1&&(i&&(c=a(d.tr||d.li)),k.push(j.node),e.activeNode===d&&k.push(j.active),e.focusNode===d&&k.push(j.focused),d.expanded&&k.push(j.expanded),i&&(g!==!1?c.attr("aria-expanded",Boolean(d.expanded)):c.removeAttr("aria-expanded")),d.folder&&k.push(j.folder),g!==!1&&k.push(j.hasChildren),h&&k.push(j.lastsib),d.lazy&&null==d.children&&k.push(j.lazy),d.partload&&k.push(j.partload),d.partsel&&k.push(j.partsel),w.evalOption("unselectable",d,d,f,!1)&&k.push(j.unselectable),d._isLoading&&k.push(j.loading),d._error&&k.push(j.error),d.statusNodeType&&k.push(j.statusNodePrefix+d.statusNodeType),d.selected?(k.push(j.selected),i&&c.attr("aria-selected",!0)):i&&c.attr("aria-selected",!1),d.extraClasses&&k.push(d.extraClasses),g===!1?k.push(j.combinedExpanderPrefix+"n"+(h?"l":"")):k.push(j.combinedExpanderPrefix+(d.expanded?"e":"c")+(d.lazy&&null==d.children?"d":"")+(h?"l":"")),k.push(j.combinedIconPrefix+(d.expanded?"e":"c")+(d.folder?"f":"")),l.className=k.join(" "),d.li&&a(d.li).toggleClass(j.lastsib,h))},nodeSetActive:function(b,c,d){d=d||{};var f,g=b.node,h=b.tree,i=b.options,j=d.noEvents===!0,m=d.noFocus===!0,n=g===h.activeNode;return c=c!==!1,n===c?k(g):c&&!j&&this._triggerNodeEvent("beforeActivate",g,b.originalEvent)===!1?l(g,["rejected"]):(c?(h.activeNode&&(e(h.activeNode!==g,"node was active (inconsistency)"),f=a.extend({},b,{node:h.activeNode}),h.nodeSetActive(f,!1),e(null===h.activeNode,"deactivate was out of sync?")),i.activeVisible&&g.makeVisible({scrollIntoView:m&&null==h.focusNode}),h.activeNode=g,h.nodeRenderStatus(b),m||h.nodeSetFocus(b),j||h._triggerNodeEvent("activate",g,b.originalEvent)):(e(h.activeNode===g,"node was not active (inconsistency)"),h.activeNode=null,this.nodeRenderStatus(b),j||b.tree._triggerNodeEvent("deactivate",g,b.originalEvent)),k(g))},nodeSetExpanded:function(b,c,e){e=e||{};var f,g,h,i,j,m,n=b.node,o=b.tree,p=b.options,q=e.noAnimation===!0,r=e.noEvents===!0;if(c=c!==!1,n.expanded&&c||!n.expanded&&!c)return k(n);if(c&&!n.lazy&&!n.hasChildren())return k(n);if(!c&&n.getLevel()ul.fancytree-container").empty(),b.rootNode.children=null},treeCreate:function(a){},treeDestroy:function(a){this.$div.find(">ul.fancytree-container").remove(),this.$source&&this.$source.removeClass("ui-helper-hidden")},treeInit:function(a){var b=a.tree,c=b.options;b.$container.attr("tabindex",c.tabindex),c.rtl?b.$container.attr("DIR","RTL").addClass("fancytree-rtl"):b.$container.removeAttr("DIR").removeClass("fancytree-rtl"),c.aria&&(b.$container.attr("role","tree"),1!==c.selectMode&&b.$container.attr("aria-multiselectable",!0)),this.treeLoad(a)},treeLoad:function(b,c){var d,f,g,h,i=b.tree,j=b.widget.element,k=a.extend({},b,{node:this.rootNode});if(i.rootNode.children&&this.treeClear(b),c=c||this.options.source)"string"==typeof c&&a.error("Not implemented");else switch(f=j.data("type")||"html"){case"html":g=j.find(">ul:first"),g.addClass("ui-fancytree-source ui-helper-hidden"),c=a.ui.fancytree.parseHtml(g),this.data=a.extend(this.data,n(g));break;case"json":c=a.parseJSON(j.text()),j.contents().filter(function(){return 3===this.nodeType}).remove(),a.isPlainObject(c)&&(e(a.isArray(c.children),"if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')"),d=c,c=c.children,delete d.children,a.extend(i.data,d));break;default:a.error("Invalid data-type: "+f)}return h=this.nodeLoadChildren(k,c).done(function(){i.render(),3===b.options.selectMode&&i.rootNode.fixSelection3FromEndNodes(),i.activeNode&&i.options.activeVisible&&i.activeNode.makeVisible(),i._triggerTreeEvent("init",null,{status:!0})}).fail(function(){i.render(),i._triggerTreeEvent("init",null,{status:!1})})},treeRegisterNode:function(a,b,c){},treeSetFocus:function(b,c,d){function e(a){!a.activeNode&&a.getFirstChild()&&a.getFirstChild().setFocus()}if(c=c!==!1,c!==this.hasFocus()&&(this._hasFocus=c,!c&&this.focusNode?this.focusNode.setFocus(!1):!c||d&&d.calledByNode||a(this.$container).focus(),this.$container.toggleClass("fancytree-treefocus",c),this._triggerTreeEvent(c?"focusTree":"blurTree"),c)){var f=this;setTimeout(function(){e(f)},0)}},treeSetOption:function(b,c,d){var e=b.tree,f=!0,g=!1;switch(c){case"aria":case"checkbox":case"icon":case"minExpandLevel":case"tabindex":e._callHook("treeCreate",e),g=!0;break;case"escapeTitles":case"tooltip":g=!0;break;case"rtl":d===!1?e.$container.removeAttr("DIR").removeClass("fancytree-rtl"):e.$container.attr("DIR","RTL").addClass("fancytree-rtl"),g=!0;break;case"source":f=!1,e._callHook("treeLoad",e,d),g=!0}e.debug("set option "+c+"="+d+" <"+typeof d+">"),f&&(this.widget._super?this.widget._super.call(this.widget,c,d):a.Widget.prototype._setOption.call(this.widget,c,d)),g&&e.render(!0,!1)}}),a.widget("ui.fancytree",{options:{activeVisible:!0,ajax:{type:"GET",cache:!1,dataType:"json"},aria:!0,autoActivate:!0,autoCollapse:!1,autoScroll:!1,checkbox:!1,clickFolderMode:4,debugLevel:null,disabled:!1,enableAspx:!0,escapeTitles:!1,extensions:[],toggleEffect:{effect:"blind",options:{direction:"vertical",scale:"box"},duration:200},generateIds:!1,icon:!0,idPrefix:"ft_",focusOnSelect:!1,keyboard:!0,keyPathSeparator:"/",minExpandLevel:1,quicksearch:!1,rtl:!1,scrollOfs:{top:0,bottom:0},scrollParent:null,selectMode:2,strings:{loading:"Loading...",loadError:"Load error!",moreData:"More...",noData:"No data."},tabindex:"0",titlesTabbable:!1,tooltip:!1,_classNames:{node:"fancytree-node",folder:"fancytree-folder",animating:"fancytree-animating",combinedExpanderPrefix:"fancytree-exp-",combinedIconPrefix:"fancytree-ico-",hasChildren:"fancytree-has-children",active:"fancytree-active",selected:"fancytree-selected",expanded:"fancytree-expanded",lazy:"fancytree-lazy",focused:"fancytree-focused",partload:"fancytree-partload",partsel:"fancytree-partsel",radio:"fancytree-radio",unselectable:"fancytree-unselectable",lastsib:"fancytree-lastsib",loading:"fancytree-loading",error:"fancytree-error",statusNodePrefix:"fancytree-statusnode-"},lazyLoad:null,postProcess:null},_create:function(){this.tree=new t(this),this.$source=this.source||"json"===this.element.data("type")?this.element:this.element.find(">ul:first");var b,c,f,g=this.options,h=g.extensions,i=this.tree;for(f=0;f=2&&f("log",arguments)},error:function(a){f("error",arguments)},escapeHtml:o,fixPositionOptions:function(b){if((b.offset||(""+b.my+b.at).indexOf("%")>=0)&&a.error("expected new position syntax (but '%' is not supported)"),!a.ui.fancytree.jquerySupports.positionMyOfs){var c=/(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec(b.my),d=/(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec(b.at),e=(c[2]?+c[2]:0)+(d[2]?+d[2]:0),f=(c[4]?+c[4]:0)+(d[4]?+d[4]:0);b=a.extend({},b,{my:c[1]+" "+c[3],at:d[1]+" "+d[3]}),(e||f)&&(b.offset=""+e+" "+f)}return b},getEventTargetType:function(a){return this.getEventTarget(a).type},getEventTarget:function(b){var c=b&&b.target?b.target.className:"",e={node:this.getNode(b.target),type:d};return/\bfancytree-title\b/.test(c)?e.type="title":/\bfancytree-expander\b/.test(c)?e.type=e.node.hasChildren()===!1?"prefix":"expander":/\bfancytree-checkbox\b/.test(c)?e.type="checkbox":/\bfancytree-icon\b/.test(c)?e.type="icon":/\bfancytree-node\b/.test(c)?e.type="title":b&&b.target&&a(b.target).closest(".fancytree-title").length&&(e.type="title"),e},getNode:function(a){if(a instanceof s)return a;for(a instanceof jQuery?a=a[0]:a.originalEvent!==d&&(a=a.target);a;){if(a.ftnode)return a.ftnode;a=a.parentNode}return null},getTree:function(b){var c;return b instanceof t?b:(b===d&&(b=0),"number"==typeof b?b=a(".fancytree-container").eq(b):"string"==typeof b?b=a(b).eq(0):b.selector!==d?b=b.eq(0):b.originalEvent!==d&&(b=a(b.target)),b=b.closest(":ui-fancytree"),c=b.data("ui-fancytree")||b.data("fancytree"),c?c.tree:null)},evalOption:function(b,c,d,e,f){var g,h,i=c.tree,j=e[b],k=d[b];return a.isFunction(j)?(g={node:c,tree:i,widget:i.widget,options:i.widget.options},h=j.call(i,{type:b},g),null==h&&(h=k)):h=null!=k?k:j,null==h&&(h=f),h},eventToString:function(a){var b=a.which,c=a.type,d=[];return a.altKey&&d.push("alt"),a.ctrlKey&&d.push("ctrl"),a.metaKey&&d.push("meta"),a.shiftKey&&d.push("shift"),"click"===c||"dblclick"===c?d.push(E[a.button]+c):C[b]||d.push(D[b]||String.fromCharCode(b).toLowerCase()),d.join("+")},info:function(b){a.ui.fancytree.debugLevel>=1&&f("info",arguments)},keyEventToString:function(a){return this.warn("keyEventToString() is deprecated: use eventToString()"),this.eventToString(a)},overrideMethod:function(b,c,d){var e,f=b[c]||a.noop;b[c]=function(){try{return e=this._super,this._super=f,d.apply(this,arguments)}finally{this._super=e}}},parseHtml:function(b){var c,e,f,g,h,i,j,k,l=b.find(">li"),m=[];return l.each(function(){var l,o,p=a(this),q=p.find(">span:first",this),r=q.length?null:p.find(">a:first"),s={tooltip:null,data:{}};for(q.length?s.title=q.html():r&&r.length?(s.title=r.html(),s.data.href=r.attr("href"),s.data.target=r.attr("target"),s.tooltip=r.attr("title")):(s.title=p.html(),h=s.title.search(/
=0&&(s.title=s.title.substring(0,h))),s.title=a.trim(s.title),g=0,i=F.length;gul:first"),b.length?s.children=a.ui.fancytree.parseHtml(b):s.children=s.lazy?d:null,m.push(s)}),m},registerExtension:function(b){e(null!=b.name,"extensions must have a `name` property."),e(null!=b.version,"extensions must have a `version` property."),a.ui.fancytree._extensions[b.name]=b},unescapeHtml:function(a){var b=c.createElement("div");return b.innerHTML=a,0===b.childNodes.length?"":b.childNodes[0].nodeValue},warn:function(a){f("warn",arguments)}})}(jQuery,window,document);
+
+!function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree.ui-deps"],a):"object"==typeof module&&module.exports?(require("jquery.fancytree.ui-deps"),module.exports=a(require("jquery"))):a(jQuery)}(function(a){"use strict";function b(b,c){b||(c=c?": "+c:"",a.error("Fancytree assertion failed"+c))}function c(a,b){var c,d,e=window.console?window.console[a]:null;if(e)try{e.apply(window.console,b)}catch(f){for(d="",c=0;ch;return!0}function f(a,b,c,d,e){var f=function(){var c=b[a],f=d[a],g=b.ext[e],h=function(){return c.apply(b,arguments)},i=function(a){return c.apply(b,a)};return function(){var a=b._local,c=b._super,d=b._superApply;try{return b._local=g,b._super=h,b._superApply=i,f.apply(b,arguments)}finally{b._local=a,b._super=c,b._superApply=d}}}();return f}function g(b,c,d,e){for(var g in d)"function"==typeof d[g]?"function"==typeof b[g]?b[g]=f(g,b,c,d,e):"_"===g.charAt(0)?b.ext[e][g]=f(g,b,c,d,e):a.error("Could not override tree."+g+". Use prefix '_' to create tree."+e+"._"+g):"options"!==g&&(b.ext[e][g]=d[g])}function h(b,c){return void 0===b?a.Deferred(function(){this.resolve()}).promise():a.Deferred(function(){this.resolveWith(b,c)}).promise()}function i(b,c){return void 0===b?a.Deferred(function(){this.reject()}).promise():a.Deferred(function(){this.rejectWith(b,c)}).promise()}function j(a,b){return function(){a.resolveWith(b)}}function k(b){var c=a.extend({},b.data()),d=c.json;return delete c.fancytree,delete c.uiFancytree,d&&(delete c.json,c=a.extend(c,d)),c}function l(a){return(""+a).replace(v,function(a){return x[a]})}function m(a){return a=a.toLowerCase(),function(b){return b.title.toLowerCase().indexOf(a)>=0}}function n(a){var b=new RegExp("^"+a,"i");return function(a){return b.test(a.title)}}function o(c,d){var e,f,g,h;for(this.parent=c,this.tree=c.tree,this.ul=null,this.li=null,this.statusNodeType=null,this._isLoading=!1,this._error=null,this.data={},e=0,f=D.length;eul.fancytree-container").remove();var c,d={tree:this};this.rootNode=new o(d,{title:"root",key:"root_"+this._id,children:null,expanded:!0}),this.rootNode.parent=null,c=a("
",{"class":"ui-fancytree fancytree-container fancytree-plain"}).appendTo(this.$div),this.$container=c,this.rootNode.ul=c[0],null==this.options.debugLevel&&(this.options.debugLevel=s.debugLevel)}if(a.ui&&a.ui.fancytree)return void a.ui.fancytree.warn("Fancytree: ignored duplicate include");var q,r,s=null,t=new RegExp(/\.|\//),u=/[&<>"'\/]/g,v=/[<>"'\/]/g,w="$recursive_request",x={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},y={16:!0,17:!0,18:!0},z={8:"backspace",9:"tab",10:"return",13:"return",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",59:";",61:"=",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scroll",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},A={0:"",1:"left",2:"middle",3:"right"},B="active expanded focus folder lazy radiogroup selected unselectable unselectableIgnore".split(" "),C={},D="checkbox expanded extraClasses folder icon key lazy radiogroup refKey selected statusNodeType title tooltip unselectable unselectableIgnore unselectableStatus".split(" "),E={},F={},G={active:!0,children:!0,data:!0,focus:!0};for(q=0;q=0,"insertBefore must be an existing child"),this.children.splice.apply(this.children,[g,0].concat(k))),h&&!d){for(e=0,f=k.length;e=0;d--)e=this.children[d],"paging"===e.statusNodeType&&this.removeChild(e);return void(this.partload=!1)}return b=a.extend({title:this.tree.options.strings.moreData,statusNodeType:"paging",icon:!1},b),this.partload=!0,this.addNode(b,c)},appendSibling:function(a){return this.addNode(a,"after")},applyPatch:function(b){if(null===b)return this.remove(),h(this);var c,d,e,f={children:!0,expanded:!0,parent:!0};for(c in b)e=b[c],f[c]||a.isFunction(e)||(E[c]?this[c]=e:this.data[c]=e);return b.hasOwnProperty("children")&&(this.removeChildren(),b.children&&this._setChildren(b.children)),this.isVisible()&&(this.renderTitle(),this.renderStatus()),d=b.hasOwnProperty("expanded")?this.setExpanded(b.expanded):h(this)},collapseSiblings:function(){return this.tree._callHook("nodeCollapseSiblings",this)},copyTo:function(a,b,c){return a.addNode(this.toDict(!0,c),b)},countChildren:function(a){var b,c,d,e=this.children;if(!e)return 0;if(d=e.length,a!==!1)for(b=0,c=d;b=2&&(Array.prototype.unshift.call(arguments,this.toString()),c("log",arguments))},discard:function(){return this.warn("FancytreeNode.discard() is deprecated since 2014-02-16. Use .resetLazy() instead."),this.resetLazy()},discardMarkup:function(a){var b=a?"nodeRemoveMarkup":"nodeRemoveChildMarkup";this.tree._callHook(b,this)},findAll:function(b){b=a.isFunction(b)?b:m(b);var c=[];return this.visit(function(a){b(a)&&c.push(a)}),c},findFirst:function(b){b=a.isFunction(b)?b:m(b);var c=null;return this.visit(function(a){if(b(a))return c=a,!1}),c},_changeSelectStatusAttrs:function(a){var c=!1,d=this.tree.options,e=s.evalOption("unselectable",this,this,d,!1),f=s.evalOption("unselectableStatus",this,this,d,void 0);switch(e&&null!=f&&(a=f),a){case!1:c=this.selected||this.partsel,this.selected=!1,this.partsel=!1;break;case!0:c=!this.selected||!this.partsel,this.selected=!0,this.partsel=!0;break;case void 0:c=this.selected||!this.partsel,this.selected=!1,this.partsel=!0;break;default:b(!1,"invalid state: "+a)}return c&&this.renderStatus(),c},fixSelection3AfterClick:function(a){var b=this.isSelected();this.visit(function(a){a._changeSelectStatusAttrs(b)}),this.fixSelection3FromEndNodes(a)},fixSelection3FromEndNodes:function(a){function c(a){var b,e,f,g,h,i,j,k,l,m=a.children;if(m&&m.length){for(i=!0,j=!1,b=0,e=m.length;b=1&&(Array.prototype.unshift.call(arguments,this.toString()),c("info",arguments))},isActive:function(){return this.tree.activeNode===this},isChildOf:function(a){return this.parent&&this.parent===a},isDescendantOf:function(b){if(!b||b.tree!==this.tree)return!1;for(var c=this.parent;c;){if(c===b)return!0;c===c.parent&&a.error("Recursive parent link: "+c),c=c.parent}return!1},isExpanded:function(){return!!this.expanded},isFirstSibling:function(){var a=this.parent;return!a||a.children[0]===this},isFolder:function(){return!!this.folder},isLastSibling:function(){var a=this.parent;return!a||a.children[a.children.length-1]===this},isLazy:function(){return!!this.lazy},isLoaded:function(){return!this.lazy||void 0!==this.hasChildren()},isLoading:function(){return!!this._isLoading},isRoot:function(){return this.isRootNode()},isPartsel:function(){return!this.selected&&!!this.partsel},isPartload:function(){return!!this.partload},isRootNode:function(){return this.tree.rootNode===this},isSelected:function(){return!!this.selected},isStatusNode:function(){return!!this.statusNodeType},isPagingNode:function(){return"paging"===this.statusNodeType},isTopLevel:function(){return this.tree.rootNode===this.parent},isUndefined:function(){return void 0===this.hasChildren()},isVisible:function(){var a,b,c=this.getParentList(!1,!1);for(a=0,b=c.length;a=0;c--)e.push(g[c].setExpanded(!0,b));return a.when.apply(a,e).done(function(){j?d.scrollIntoView(i).done(function(){f.resolve()}):f.resolve()}),f.promise()},moveTo:function(c,d,e){void 0===d||"over"===d?d="child":"firstChild"===d&&(c.children&&c.children.length?(d="before",c=c.children[0]):d="child");var f,g=this.parent,h="child"===d?c:c.parent;if(this!==c){if(this.parent?h.isDescendantOf(this)&&a.error("Cannot move a node to its own descendant"):a.error("Cannot move system root"),h!==g&&g.triggerModifyChild("remove",this),1===this.parent.children.length){if(this.parent===h)return;this.parent.children=this.parent.lazy?[]:null,this.parent.expanded=!1}else f=a.inArray(this,this.parent.children),b(f>=0,"invalid source parent"),this.parent.children.splice(f,1);if(this.parent=h,h.hasChildren())switch(d){case"child":h.children.push(this);break;case"before":f=a.inArray(c,h.children),b(f>=0,"invalid target parent"),h.children.splice(f,0,this);break;case"after":f=a.inArray(c,h.children),b(f>=0,"invalid target parent"),h.children.splice(f+1,0,this);break;default:a.error("Invalid mode "+d)}else h.children=[this];e&&c.visit(e,!0),h===g?h.triggerModifyChild("move",this):h.triggerModifyChild("add",this),this.tree!==c.tree&&(this.warn("Cross-tree moveTo is experimantal!"),this.visit(function(a){a.tree=c.tree},!0)),g.isDescendantOf(h)||g.render(),h.isDescendantOf(g)||h===g||h.render()}},navigate:function(b,c){function d(d){if(d){try{d.makeVisible({scrollIntoView:!1})}catch(e){}return a(d.span).is(":visible")?c===!1?d.setFocus():d.setActive():(d.debug("Navigate: skipping hidden node"),void d.navigate(b,c))}}var e,f,g,i=!0,j=a.ui.keyCode,k=null;switch(b){case j.BACKSPACE:this.parent&&this.parent.parent&&(g=d(this.parent));break;case j.HOME:this.tree.visit(function(b){if(a(b.span).is(":visible"))return g=d(b),!1});break;case j.END:this.tree.visit(function(b){a(b.span).is(":visible")&&(g=b)}),g&&(g=d(g));break;case j.LEFT:this.expanded?(this.setExpanded(!1),g=d(this)):this.parent&&this.parent.parent&&(g=d(this.parent));break;case j.RIGHT:this.expanded||!this.children&&!this.lazy?this.children&&this.children.length&&(g=d(this.children[0])):(this.setExpanded(),g=d(this));break;case j.UP:for(k=this.getPrevSibling();k&&!a(k.span).is(":visible");)k=k.getPrevSibling();for(;k&&k.expanded&&k.children&&k.children.length;)k=k.children[k.children.length-1];!k&&this.parent&&this.parent.parent&&(k=this.parent),g=d(k);break;case j.DOWN:if(this.expanded&&this.children&&this.children.length)k=this.children[0];else for(f=this.getParentList(!1,!0),e=f.length-1;e>=0;e--){for(k=f[e].getNextSibling();k&&!a(k.span).is(":visible");)k=k.getNextSibling();if(k)break}g=d(k);break;default:i=!1}return g||h()},remove:function(){return this.parent.removeChild(this)},removeChild:function(a){return this.tree._callHook("nodeRemoveChild",this,a)},removeChildren:function(){return this.tree._callHook("nodeRemoveChildren",this)},removeClass:function(a){return this.toggleClass(a,!1)},render:function(a,b){return this.tree._callHook("nodeRender",this,a,b)},renderTitle:function(){return this.tree._callHook("nodeRenderTitle",this)},renderStatus:function(){return this.tree._callHook("nodeRenderStatus",this)},replaceWith:function(c){var d,e=this.parent,f=a.inArray(this,e.children),g=this;return b(this.isPagingNode(),"replaceWith() currently requires a paging status node"),d=this.tree._callHook("nodeLoadChildren",this,c),d.done(function(a){var b=g.children;for(q=0;qs+r-q&&(w=g+n-r+q,v&&(b(v.isRootNode()||a(v.span).is(":visible"),"topNode must be visible"),fd?1:-1},e.sort(a),b)for(c=0,d=e.length;c=0,c=void 0===c?!e:!!c)e||(k+=d+" ",i=!0);else for(;k.indexOf(" "+d+" ")>-1;)k=k.replace(" "+d+" "," ");return this.extraClasses=a.trim(k),i},toggleExpanded:function(){return this.tree._callHook("nodeToggleExpanded",this)},toggleSelected:function(){return this.tree._callHook("nodeToggleSelected",this)},toString:function(){return""},triggerModifyChild:function(b,c,d){var e,f=this.tree.options.modifyChild;f&&(c&&c.parent!==this&&a.error("childNode "+c+" is not a child of "+this),e={node:this,tree:this.tree,operation:b,childNode:c||null},d&&a.extend(e,d),f({type:"modifyChild"},e))},triggerModify:function(a,b){this.parent.triggerModifyChild(a,this,b)},visit:function(a,b){var c,d,e=!0,f=this.children;if(b===!0&&(e=a(this),e===!1||"skip"===e))return e;if(f)for(c=0,d=f.length;c=2&&(Array.prototype.unshift.call(arguments,this.toString()),c("log",arguments))},enableUpdate:function(a){return a=a!==!1,!!this._enableUpdate==!!a?a:(this._enableUpdate=a,a?(this.debug("enableUpdate(true): redraw "),this.render()):this.debug("enableUpdate(false)..."),!a)},findAll:function(a){return this.rootNode.findAll(a)},findFirst:function(a){return this.rootNode.findFirst(a)},findNextNode:function(b,c,d){var e=null,f=c.parent.children,g=null,h=function(a,b,c){var d,e,f=a.children,g=f.length,i=f[b];if(i&&c(i)===!1)return!1;if(i&&i.children&&i.expanded&&h(i,0,c)===!1)return!1;for(d=b+1;d",{type:"checkbox",name:g,value:b.key,checked:!0}))}d=d||{};var f,g="string"==typeof b?b:"ft_"+this._id+"[]",h="string"==typeof c?c:"ft_"+this._id+"_active",i="fancytree_result_"+this._id,j=a("#"+i),k=3===this.options.selectMode&&d.stopOnParents!==!1;j.length?j.empty():j=a("
",{id:i}).hide().insertAfter(this.$container),c!==!1&&this.activeNode&&j.append(a("",{type:"radio",name:h,value:this.activeNode.key,checked:!0})),d.filter?this.visit(function(a){var b=d.filter(a);return"skip"===b?b:void(b!==!1&&e(a))}):b!==!1&&(f=this.getSelectedNodes(k),a.each(f,function(a,b){e(b)}))},getActiveNode:function(){return this.activeNode},getFirstChild:function(){return this.rootNode.getFirstChild()},getFocusNode:function(){return this.focusNode},getNodeByKey:function(a,b){var c,d;return!b&&(c=document.getElementById(this.options.idPrefix+a))?c.ftnode?c.ftnode:null:(b=b||this.rootNode,d=null,b.visit(function(b){if(b.key===a)return d=b,!1},!0),d)},getRootNode:function(){return this.rootNode},getSelectedNodes:function(a){return this.rootNode.getSelectedNodes(a)},hasFocus:function(){return!!this._hasFocus},info:function(a){this.options.debugLevel>=1&&(Array.prototype.unshift.call(arguments,this.toString()),c("info",arguments))},loadKeyPath:function(b,c,d){function e(a,b,d){c.call(q,b,"loading"),b.load().done(function(){q.loadKeyPath.call(q,l[a],c,b).always(j(d,q))}).fail(function(e){q.warn("loadKeyPath: error loading: "+a+" (parent: "+n+")"),c.call(q,b,"error"),d.reject()})}var f,g,h,i,k,l,m,n,o,p=this.options.keyPathSeparator,q=this;for(c=c||a.noop,a.isArray(b)||(b=[b]),l={},h=0;h"},_triggerNodeEvent:function(a,b,c,d){var e=this._makeHookContext(b,c,d),f=this.widget._trigger(a,c,e);return f!==!1&&void 0!==e.result?e.result:f},_triggerTreeEvent:function(a,b,c){var d=this._makeHookContext(this,b,c),e=this.widget._trigger(a,b,d);return e!==!1&&void 0!==d.result?d.result:e},visit:function(a){return this.rootNode.visit(a,!1)},warn:function(a){Array.prototype.unshift.call(arguments,this.toString()),c("warn",arguments)}},a.extend(p.prototype,{nodeClick:function(a){var b,c,d=a.targetType,e=a.node;if("expander"===d){if(e.isLoading())return void e.debug("Got 2nd click while loading: ignored");this._callHook("nodeToggleExpanded",a)}else if("checkbox"===d)this._callHook("nodeToggleSelected",a),a.options.focusOnSelect&&this._callHook("nodeSetFocus",a,!0);else{if(c=!1,b=!0,e.folder)switch(a.options.clickFolderMode){case 2:c=!0,b=!1;break;case 3:b=!0,c=!0}b&&(this.nodeSetFocus(a),this._callHook("nodeSetActive",a,!0)),c&&this._callHook("nodeToggleExpanded",a)}},nodeCollapseSiblings:function(a,b){var c,d,e,f=a.node;if(f.parent)for(c=f.parent.children,d=0,e=c.length;d500&&(i.lastQuicksearchTerm=""),i.lastQuicksearchTime=d,i.lastQuicksearchTerm+=l,c=i.findNextNode(i.lastQuicksearchTerm,i.getActiveNode()),c&&c.setActive(),void g.preventDefault();switch(s.eventToString(g)){case"+":case"=":i.nodeSetExpanded(b,!0);break;case"-":i.nodeSetExpanded(b,!1);break;case"space":h.isPagingNode()?i._triggerNodeEvent("clickPaging",b,g):s.evalOption("checkbox",h,h,j,!1)?i.nodeToggleSelected(b):i.nodeSetActive(b,!0);break;case"return":i.nodeSetActive(b,!0);break;case"home":case"end":case"backspace":case"left":case"right":case"up":case"down":e=h.navigate(g.which,p,!0);break;default:o=!1}o&&g.preventDefault()},nodeLoadChildren:function(c,d){var e,f,g,h=c.tree,i=c.node,j=(new Date).getTime();return a.isFunction(d)&&(d=d.call(h,{type:"source"},c),b(!a.isFunction(d),"source callback must not return another function")),d.url&&(i._requestId&&i.warn("Recursive load request #"+j+" while #"+i._requestId+" is pending."),e=a.extend({},c.options.ajax,d),i._requestId=j,e.debugDelay?(f=e.debugDelay,a.isArray(f)&&(f=f[0]+Math.random()*(f[1]-f[0])),i.warn("nodeLoadChildren waiting debugDelay "+Math.round(f)+" ms ..."),e.debugDelay=!1,g=a.Deferred(function(b){setTimeout(function(){a.ajax(e).done(function(){b.resolveWith(this,arguments)}).fail(function(){b.rejectWith(this,arguments)})},f)})):g=a.ajax(e),d=new a.Deferred,g.done(function(b,e,f){var g,k;if("json"!==this.dataType&&"jsonp"!==this.dataType||"string"!=typeof b||a.error("Ajax request returned a string (did you get the JSON dataType wrong?)."),i._requestId&&i._requestId>j)return void d.rejectWith(this,[w]);
+if(c.options.postProcess){try{k=h._triggerNodeEvent("postProcess",c,c.originalEvent,{response:b,error:null,dataType:this.dataType})}catch(l){k={error:l,message:""+l,details:"postProcess failed"}}if(k.error)return g=a.isPlainObject(k.error)?k.error:{message:k.error},g=h._makeHookContext(i,null,g),void d.rejectWith(this,[g]);b=a.isArray(k)?k:b}else b&&b.hasOwnProperty("d")&&c.options.enableAspx&&(b="string"==typeof b.d?a.parseJSON(b.d):b.d);d.resolveWith(this,[b])}).fail(function(a,b,c){var e=h._makeHookContext(i,null,{error:a,args:Array.prototype.slice.call(arguments),message:c,details:a.status+": "+c});d.rejectWith(this,[e])})),a.isFunction(d.then)&&a.isFunction(d["catch"])&&(g=d,d=new a.Deferred,g.then(function(a){d.resolve(a)},function(a){d.reject(a)})),a.isFunction(d.promise)?(h.nodeSetStatus(c,"loading"),d.done(function(a){h.nodeSetStatus(c,"ok"),i._requestId=null}).fail(function(a){var b;return a===w?void i.warn("Ignored response for obsolete load request #"+j+" (expected #"+i._requestId+")"):(a.node&&a.error&&a.message?b=a:(b=h._makeHookContext(i,null,{error:a,args:Array.prototype.slice.call(arguments),message:a?a.message||a.toString():""}),"[object Object]"===b.message&&(b.message="")),i.warn("Load children failed ("+b.message+")",b),void(h._triggerNodeEvent("loadError",b,null)!==!1&&h.nodeSetStatus(c,"error",b.message,b.details)))})):c.options.postProcess&&h._triggerNodeEvent("postProcess",c,c.originalEvent,{response:d,error:null,dataType:typeof d}),a.when(d).done(function(c){var d;a.isPlainObject(c)&&(b(i.isRootNode(),"source may only be an object for root nodes (expecting an array of child objects otherwise)"),b(a.isArray(c.children),"if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')"),d=c,c=c.children,delete d.children,a.extend(h.data,d)),b(a.isArray(c),"expected array of children"),i._setChildren(c),h._triggerNodeEvent("loadChildren",i)})},nodeLoadKeyPath:function(a,b){},nodeRemoveChild:function(c,d){var e,f=c.node,g=a.extend({},c,{node:d}),h=f.children;return 1===h.length?(b(d===h[0],"invalid single child"),this.nodeRemoveChildren(c)):(this.activeNode&&(d===this.activeNode||this.activeNode.isDescendantOf(d))&&this.activeNode.setActive(!1),this.focusNode&&(d===this.focusNode||this.focusNode.isDescendantOf(d))&&(this.focusNode=null),this.nodeRemoveMarkup(g),this.nodeRemoveChildren(g),e=a.inArray(d,h),b(e>=0,"invalid child"),f.triggerModifyChild("remove",d),d.visit(function(a){a.parent=null},!0),this._callHook("treeRegisterNode",this,!1,d),void h.splice(e,1))},nodeRemoveChildMarkup:function(b){var c=b.node;c.ul&&(c.isRootNode()?a(c.ul).empty():(a(c.ul).remove(),c.ul=null),c.visit(function(a){a.li=a.ul=null}))},nodeRemoveChildren:function(b){var c,d=b.tree,e=b.node,f=e.children;f&&(this.activeNode&&this.activeNode.isDescendantOf(e)&&this.activeNode.setActive(!1),this.focusNode&&this.focusNode.isDescendantOf(e)&&(this.focusNode=null),this.nodeRemoveChildMarkup(b),c=a.extend({},b),e.triggerModifyChild("remove",null),e.visit(function(a){a.parent=null,d._callHook("treeRegisterNode",d,!1,a)}),e.lazy?e.children=[]:e.children=null,e.isRootNode()||(e.expanded=!1),this.nodeRenderStatus(b))},nodeRemoveMarkup:function(b){var c=b.node;c.li&&(a(c.li).remove(),c.li=null),this.nodeRemoveChildMarkup(b)},nodeRender:function(c,d,e,f,g){var h,i,j,k,l,m,n,o=c.node,p=c.tree,q=c.options,r=q.aria,s=!1,t=o.parent,u=!t,v=o.children,w=null;if(p._enableUpdate!==!1&&(u||t.ul)){if(b(u||t.ul,"parent UL must exist"),u||(o.li&&(d||o.li.parentNode!==o.parent.ul)&&(o.li.parentNode===o.parent.ul?w=o.li.nextSibling:this.debug("Unlinking "+o+" (must be child of "+o.parent+")"),this.nodeRemoveMarkup(c)),o.li?this.nodeRenderStatus(c):(s=!0,o.li=document.createElement("li"),o.li.ftnode=o,o.key&&q.generateIds&&(o.li.id=q.idPrefix+o.key),o.span=document.createElement("span"),o.span.className="fancytree-node",r&&!o.tr&&a(o.li).attr("role","treeitem"),o.li.appendChild(o.span),this.nodeRenderTitle(c),q.createNode&&q.createNode.call(p,{type:"createNode"},c)),q.renderNode&&q.renderNode.call(p,{type:"renderNode"},c)),v){if(u||o.expanded||e===!0){for(o.ul||(o.ul=document.createElement("ul"),(f!==!0||g)&&o.expanded||(o.ul.style.display="none"),r&&a(o.ul).attr("role","group"),o.li?o.li.appendChild(o.ul):o.tree.$div.append(o.ul)),k=0,l=v.length;k1&&q.push("")):q.push(""),d=s.evalOption("checkbox",k,k,n,!1),d&&!k.isStatusNode()&&(h=o?" role='checkbox'":"",e="fancytree-checkbox",("radio"===d||k.parent&&k.parent.radiogroup)&&(e+=" fancytree-radio"),q.push("")),void 0!==k.data.iconClass&&(k.icon?a.error("'iconClass' node option is deprecated since v2.14.0: use 'icon' only instead"):(k.warn("'iconClass' node option is deprecated since v2.14.0: use 'icon' instead"),k.icon=k.data.iconClass)),f=s.evalOption("icon",k,k,n,!0),"boolean"!=typeof f&&(f=""+f),f!==!1&&(h=o?" role='presentation'":"","string"==typeof f?t.test(f)?(f="/"===f.charAt(0)?f:(n.imagePath||"")+f,q.push("")):q.push(""):q.push("")),g="",n.renderTitle&&(g=n.renderTitle.call(m,{type:"renderTitle"},b)||""),g||(j=s.evalOption("tooltip",k,k,n,null),j===!0&&(j=k.title),j=j?" title='"+l(j)+"'":"",i=n.titlesTabbable?" tabindex='0'":"",g=""+(n.escapeTitles?s.escapeHtml(k.title):k.title)+""),q.push(g),k.span.innerHTML=q.join(""),this.nodeRenderStatus(b),n.enhanceTitle&&(b.$title=a(">span.fancytree-title",k.span),g=n.enhanceTitle.call(m,{type:"enhanceTitle"},b)||""))},nodeRenderStatus:function(b){var c,d=b.node,e=b.tree,f=b.options,g=d.hasChildren(),h=d.isLastSibling(),i=f.aria,j=f._classNames,k=[],l=d[e.statusClassPropName];l&&e._enableUpdate!==!1&&(i&&(c=a(d.tr||d.li)),k.push(j.node),e.activeNode===d&&k.push(j.active),e.focusNode===d&&k.push(j.focused),d.expanded&&k.push(j.expanded),i&&(g!==!1?c.attr("aria-expanded",Boolean(d.expanded)):c.removeAttr("aria-expanded")),d.folder&&k.push(j.folder),g!==!1&&k.push(j.hasChildren),h&&k.push(j.lastsib),d.lazy&&null==d.children&&k.push(j.lazy),d.partload&&k.push(j.partload),d.partsel&&k.push(j.partsel),s.evalOption("unselectable",d,d,f,!1)&&k.push(j.unselectable),d._isLoading&&k.push(j.loading),d._error&&k.push(j.error),d.statusNodeType&&k.push(j.statusNodePrefix+d.statusNodeType),d.selected?(k.push(j.selected),i&&c.attr("aria-selected",!0)):i&&c.attr("aria-selected",!1),d.extraClasses&&k.push(d.extraClasses),g===!1?k.push(j.combinedExpanderPrefix+"n"+(h?"l":"")):k.push(j.combinedExpanderPrefix+(d.expanded?"e":"c")+(d.lazy&&null==d.children?"d":"")+(h?"l":"")),k.push(j.combinedIconPrefix+(d.expanded?"e":"c")+(d.folder?"f":"")),l.className=k.join(" "),d.li&&a(d.li).toggleClass(j.lastsib,h))},nodeSetActive:function(c,d,e){e=e||{};var f,g=c.node,j=c.tree,k=c.options,l=e.noEvents===!0,m=e.noFocus===!0,n=g===j.activeNode;return d=d!==!1,n===d?h(g):d&&!l&&this._triggerNodeEvent("beforeActivate",g,c.originalEvent)===!1?i(g,["rejected"]):(d?(j.activeNode&&(b(j.activeNode!==g,"node was active (inconsistency)"),f=a.extend({},c,{node:j.activeNode}),j.nodeSetActive(f,!1),b(null===j.activeNode,"deactivate was out of sync?")),k.activeVisible&&g.makeVisible({scrollIntoView:m&&null==j.focusNode}),j.activeNode=g,j.nodeRenderStatus(c),m||j.nodeSetFocus(c),l||j._triggerNodeEvent("activate",g,c.originalEvent)):(b(j.activeNode===g,"node was not active (inconsistency)"),j.activeNode=null,this.nodeRenderStatus(c),l||c.tree._triggerNodeEvent("deactivate",g,c.originalEvent)),h(g))},nodeSetExpanded:function(b,c,d){d=d||{};var e,f,g,j,k,l,m=b.node,n=b.tree,o=b.options,p=d.noAnimation===!0,q=d.noEvents===!0;if(c=c!==!1,m.expanded&&c||!m.expanded&&!c)return h(m);if(c&&!m.lazy&&!m.hasChildren())return h(m);if(!c&&m.getLevel()ul.fancytree-container").empty(),b.rootNode.children=null},treeCreate:function(a){},treeDestroy:function(a){this.$div.find(">ul.fancytree-container").remove(),this.$source&&this.$source.removeClass("ui-helper-hidden")},treeInit:function(a){var b=a.tree,c=b.options;b.$container.attr("tabindex",c.tabindex),c.rtl?b.$container.attr("DIR","RTL").addClass("fancytree-rtl"):b.$container.removeAttr("DIR").removeClass("fancytree-rtl"),c.aria&&(b.$container.attr("role","tree"),1!==c.selectMode&&b.$container.attr("aria-multiselectable",!0)),this.treeLoad(a)},treeLoad:function(c,d){var e,f,g,h,i=c.tree,j=c.widget.element,l=a.extend({},c,{node:this.rootNode});if(i.rootNode.children&&this.treeClear(c),d=d||this.options.source)"string"==typeof d&&a.error("Not implemented");else switch(f=j.data("type")||"html"){case"html":g=j.find(">ul:first"),g.addClass("ui-fancytree-source ui-helper-hidden"),d=a.ui.fancytree.parseHtml(g),this.data=a.extend(this.data,k(g));break;case"json":d=a.parseJSON(j.text()),j.contents().filter(function(){return 3===this.nodeType}).remove(),a.isPlainObject(d)&&(b(a.isArray(d.children),"if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')"),e=d,d=d.children,delete e.children,a.extend(i.data,e));break;default:a.error("Invalid data-type: "+f)}return h=this.nodeLoadChildren(l,d).done(function(){i.render(),3===c.options.selectMode&&i.rootNode.fixSelection3FromEndNodes(),i.activeNode&&i.options.activeVisible&&i.activeNode.makeVisible(),i._triggerTreeEvent("init",null,{status:!0})}).fail(function(){i.render(),i._triggerTreeEvent("init",null,{status:!1})})},treeRegisterNode:function(a,b,c){},treeSetFocus:function(b,c,d){var e;c=c!==!1,c!==this.hasFocus()&&(this._hasFocus=c,!c&&this.focusNode?this.focusNode.setFocus(!1):!c||d&&d.calledByNode||a(this.$container).focus(),this.$container.toggleClass("fancytree-treefocus",c),this._triggerTreeEvent(c?"focusTree":"blurTree"),c&&!this.activeNode&&(e=this._lastMousedownNode||this.getFirstChild(),e&&e.setFocus()))},treeSetOption:function(b,c,d){var e=b.tree,f=!0,g=!1,h=!1;switch(c){case"aria":case"checkbox":case"icon":case"minExpandLevel":case"tabindex":g=!0,h=!0;break;case"escapeTitles":case"tooltip":h=!0;break;case"rtl":d===!1?e.$container.removeAttr("DIR").removeClass("fancytree-rtl"):e.$container.attr("DIR","RTL").addClass("fancytree-rtl"),h=!0;break;case"source":f=!1,e._callHook("treeLoad",e,d),h=!0}e.debug("set option "+c+"="+d+" <"+typeof d+">"),f&&(this.widget._super?this.widget._super.call(this.widget,c,d):a.Widget.prototype._setOption.call(this.widget,c,d)),g&&e._callHook("treeCreate",e),h&&e.render(!0,!1)}}),a.widget("ui.fancytree",{options:{activeVisible:!0,ajax:{type:"GET",cache:!1,dataType:"json"},aria:!0,autoActivate:!0,autoCollapse:!1,autoScroll:!1,checkbox:!1,clickFolderMode:4,debugLevel:null,disabled:!1,enableAspx:!0,escapeTitles:!1,extensions:[],toggleEffect:{effect:"blind",options:{direction:"vertical",scale:"box"},duration:200},generateIds:!1,icon:!0,idPrefix:"ft_",focusOnSelect:!1,keyboard:!0,keyPathSeparator:"/",minExpandLevel:1,quicksearch:!1,rtl:!1,scrollOfs:{top:0,bottom:0},scrollParent:null,selectMode:2,strings:{loading:"Loading...",loadError:"Load error!",moreData:"More...",noData:"No data."},tabindex:"0",titlesTabbable:!1,tooltip:!1,_classNames:{node:"fancytree-node",folder:"fancytree-folder",animating:"fancytree-animating",combinedExpanderPrefix:"fancytree-exp-",combinedIconPrefix:"fancytree-ico-",hasChildren:"fancytree-has-children",active:"fancytree-active",selected:"fancytree-selected",expanded:"fancytree-expanded",lazy:"fancytree-lazy",focused:"fancytree-focused",partload:"fancytree-partload",partsel:"fancytree-partsel",radio:"fancytree-radio",unselectable:"fancytree-unselectable",lastsib:"fancytree-lastsib",loading:"fancytree-loading",error:"fancytree-error",statusNodePrefix:"fancytree-statusnode-"},lazyLoad:null,postProcess:null},_create:function(){this.tree=new p(this),this.$source=this.source||"json"===this.element.data("type")?this.element:this.element.find(">ul:first");var c,d,e,f=this.options,h=f.extensions,i=this.tree;for(e=0;e thead").length?d.debug("Ignore focus event outside table body.",b):d._callHook("treeSetFocus",d,e)))}).on("selectstart"+e,"span.fancytree-title",function(a){a.preventDefault()}).on("keydown"+e,function(a){if(c.disabled||c.keyboard===!1)return!0;var b,e=d.focusNode,f=d._makeHookContext(e||d,a),g=d.phase;try{return d.phase="userEvent",b=e?d._triggerNodeEvent("keydown",e,a):d._triggerTreeEvent("keydown",a),"preventNav"===b?b=!0:b!==!1&&(b=d._callHook("nodeKeydown",f)),b}finally{d.phase=g}}).on("mousedown"+e,function(a){var b=s.getEventTarget(a);d._lastMousedownNode=b?b.node:null,d._setExpiringValue("mouseDownNode",d._lastMousedownNode)}).on("click"+e+" dblclick"+e,function(a){if(c.disabled)return!0;var d,e=s.getEventTarget(a),f=e.node,g=b.tree,h=g.phase;if(!f)return!0;d=g._makeHookContext(f,a);try{switch(g.phase="userEvent",a.type){case"click":return d.targetType=e.type,f.isPagingNode()?g._triggerNodeEvent("clickPaging",d,a)===!0:g._triggerNodeEvent("click",d,a)!==!1&&g._callHook("nodeClick",d);case"dblclick":return d.targetType=e.type,g._triggerNodeEvent("dblclick",d,a)!==!1&&g._callHook("nodeDblclick",d)}}finally{g.phase=h}})},getActiveNode:function(){return this.tree.activeNode},getNodeByKey:function(a){return this.tree.getNodeByKey(a)},getRootNode:function(){return this.tree.rootNode},getTree:function(){return this.tree}}),s=a.ui.fancytree,a.extend(a.ui.fancytree,{version:"2.26.0",buildType: "production",debugLevel: 1,_nextId:1,_nextNodeKey:1,_extensions:{},_FancytreeClass:p,_FancytreeNodeClass:o,jquerySupports:{positionMyOfs:e(a.ui.version,1,9)},assert:function(a,c){return b(a,c)},createTree:function(b,c){var d=a(b).fancytree(c).fancytree("getTree");return d},debounce:function(a,b,c,d){var e;return 3===arguments.length&&"boolean"!=typeof c&&(d=c,c=!1),function(){var f=arguments;d=d||this,c&&!e&&b.apply(d,f),clearTimeout(e),e=setTimeout(function(){c||b.apply(d,f),e=null},a)}},debug:function(b){a.ui.fancytree.debugLevel>=2&&c("log",arguments)},error:function(a){c("error",arguments)},escapeHtml:function(a){return(""+a).replace(u,function(a){return x[a]})},fixPositionOptions:function(b){if((b.offset||(""+b.my+b.at).indexOf("%")>=0)&&a.error("expected new position syntax (but '%' is not supported)"),!a.ui.fancytree.jquerySupports.positionMyOfs){var c=/(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec(b.my),d=/(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec(b.at),e=(c[2]?+c[2]:0)+(d[2]?+d[2]:0),f=(c[4]?+c[4]:0)+(d[4]?+d[4]:0);b=a.extend({},b,{my:c[1]+" "+c[3],at:d[1]+" "+d[3]}),(e||f)&&(b.offset=""+e+" "+f)}return b},getEventTarget:function(b){var c=b&&b.target?b.target.className:"",d={node:this.getNode(b.target),type:void 0};return/\bfancytree-title\b/.test(c)?d.type="title":/\bfancytree-expander\b/.test(c)?d.type=d.node.hasChildren()===!1?"prefix":"expander":/\bfancytree-checkbox\b/.test(c)?d.type="checkbox":/\bfancytree(-custom)?-icon\b/.test(c)?d.type="icon":/\bfancytree-node\b/.test(c)?d.type="title":b&&a(b.target).is("ul[role=group]")?(s.info("Ignoring click on outer UL."),d.node=null):b&&b.target&&a(b.target).closest(".fancytree-title").length&&(d.type="title"),d},getEventTargetType:function(a){return this.getEventTarget(a).type},getNode:function(b){if(b instanceof o)return b;for(b instanceof a?b=b[0]:void 0!==b.originalEvent&&(b=b.target);b;){if(b.ftnode)return b.ftnode;b=b.parentNode}return null},getTree:function(b){var c;return b instanceof p?b:(void 0===b&&(b=0),"number"==typeof b?b=a(".fancytree-container").eq(b):"string"==typeof b?b=a(b).eq(0):void 0!==b.selector?b=b.eq(0):void 0!==b.originalEvent&&(b=a(b.target)),b=b.closest(":ui-fancytree"),c=b.data("ui-fancytree")||b.data("fancytree"),c?c.tree:null)},evalOption:function(b,c,d,e,f){var g,h,i=c.tree,j=e[b],k=d[b];return a.isFunction(j)?(g={node:c,tree:i,widget:i.widget,options:i.widget.options},h=j.call(i,{type:b},g),null==h&&(h=k)):h=null!=k?k:j,null==h&&(h=f),h},eventToString:function(a){var b=a.which,c=a.type,d=[];return a.altKey&&d.push("alt"),a.ctrlKey&&d.push("ctrl"),a.metaKey&&d.push("meta"),a.shiftKey&&d.push("shift"),"click"===c||"dblclick"===c?d.push(A[a.button]+c):y[b]||d.push(z[b]||String.fromCharCode(b).toLowerCase()),d.join("+")},info:function(b){a.ui.fancytree.debugLevel>=1&&c("info",arguments)},keyEventToString:function(a){return this.warn("keyEventToString() is deprecated: use eventToString()"),this.eventToString(a)},overrideMethod:function(b,c,d){var e,f=b[c]||a.noop;b[c]=function(){try{return e=this._super,this._super=f,d.apply(this,arguments)}finally{this._super=e}}},parseHtml:function(b){var c,d,e,f,g,h,i,j,l=b.find(">li"),m=[];return l.each(function(){var l,n,o=a(this),p=o.find(">span:first",this),q=p.length?null:o.find(">a:first"),r={tooltip:null,data:{}};for(p.length?r.title=p.html():q&&q.length?(r.title=q.html(),r.data.href=q.attr("href"),r.data.target=q.attr("target"),r.tooltip=q.attr("title")):(r.title=o.html(),g=r.title.search(/
"},start:function(a,b){var c=b.helper.data("ftSourceNode");return!!c}},b.options.dnd.draggable)),c&&c.dragDrop&&b.widget.element.droppable(a.extend({addClasses:!1,tolerance:"intersect",greedy:!1},b.options.dnd.droppable))}var h=!1,i="fancytree-drop-accept",j="fancytree-drop-after",k="fancytree-drop-before",l="fancytree-drop-over",m="fancytree-drop-reject",n="fancytree-drop-target";a.ui.fancytree.registerExtension({name:"dnd",version:"2.23.0",options:{autoExpandMS:1e3,draggable:null,droppable:null,focusOnClick:!1,preventVoidMoves:!0,preventRecursiveMoves:!0,smartRevert:!0,dropMarkerOffsetX:-24,dropMarkerInsertOffsetX:-16,dragStart:null,dragStop:null,initHelper:null,updateHelper:null,dragEnter:null,dragOver:null,dragExpand:null,dragDrop:null,dragLeave:null},treeInit:function(b){var c=b.tree;this._superApply(arguments),c.options.dnd.dragStart&&c.$container.on("mousedown",function(c){if(b.options.dnd.focusOnClick){var d=a.ui.fancytree.getNode(c);d&&d.debug("Re-enable focus that was prevented by jQuery UI draggable."),setTimeout(function(){a(c.target).closest(":tabbable").focus()},10)}}),g(c)},_setDndStatus:function(b,c,d,f,g){var h,o="center",p=this._local,q=this.options.dnd,r=this.options.glyph,s=b?a(b.span):null,t=a(c.span),u=t.find("span.fancytree-title");if(p.$dropMarker||(p.$dropMarker=a("").hide().css({"z-index":1e3}).prependTo(a(this.$div).parent()),r&&p.$dropMarker.addClass(r.map.dropMarker)),"after"===f||"before"===f||"over"===f){switch(h=q.dropMarkerOffsetX||0,f){case"before":o="top",h+=q.dropMarkerInsertOffsetX||0;break;case"after":o="bottom",h+=q.dropMarkerInsertOffsetX||0}p.$dropMarker.toggleClass(j,"after"===f).toggleClass(l,"over"===f).toggleClass(k,"before"===f).show().position(a.ui.fancytree.fixPositionOptions({my:"left"+e(h)+" center",at:"left "+o,of:u}))}else p.$dropMarker.hide();s&&s.toggleClass(i,g===!0).toggleClass(m,g===!1),t.toggleClass(n,"after"===f||"before"===f||"over"===f).toggleClass(j,"after"===f).toggleClass(k,"before"===f).toggleClass(i,g===!0).toggleClass(m,g===!1),d.toggleClass(i,g===!0).toggleClass(m,g===!1)},_onDragEvent:function(b,e,f,g,h,i){var j,k,l,m,n,o,p,q,r,s=this.options,t=s.dnd,u=this._makeHookContext(e,g,{otherNode:f,ui:h,draggable:i}),v=null,w=this,x=a(e.span);switch(t.smartRevert&&(i.options.revert="invalid"),b){case"start":e.isStatusNode()?v=!1:t.dragStart&&(v=t.dragStart(e,u)),v===!1?(this.debug("tree.dragStart() cancelled"),h.helper.trigger("mouseup").hide()):(t.smartRevert&&(m=e[u.tree.nodeContainerAttrName].getBoundingClientRect(),l=a(i.options.appendTo)[0].getBoundingClientRect(),i.originalPosition.left=Math.max(0,m.left-l.left),i.originalPosition.top=Math.max(0,m.top-l.top)),x.addClass("fancytree-drag-source"),a(c).on("keydown.fancytree-dnd,mousedown.fancytree-dnd",function(b){"keydown"===b.type&&b.which===a.ui.keyCode.ESCAPE?w.ext.dnd._cancelDrag():"mousedown"===b.type&&w.ext.dnd._cancelDrag()}));break;case"enter":r=(!t.preventRecursiveMoves||!e.isDescendantOf(f))&&(t.dragEnter?t.dragEnter(e,u):null),v=!!r&&(a.isArray(r)?{over:a.inArray("over",r)>=0,before:a.inArray("before",r)>=0,after:a.inArray("after",r)>=0}:{over:r===!0||"over"===r,before:r===!0||"before"===r,after:r===!0||"after"===r}),h.helper.data("enterResponse",v);break;case"over":p=h.helper.data("enterResponse"),q=null,p===!1||("string"==typeof p?q=p:(k=x.offset(),n={x:g.pageX-k.left,y:g.pageY-k.top},o={x:n.x/x.width(),y:n.y/x.height()},p.after&&o.y>.75?q="after":!p.over&&p.after&&o.y>.5?q="after":p.before&&o.y<=.25?q="before":!p.over&&p.before&&o.y<=.5?q="before":p.over&&(q="over"),t.preventVoidMoves&&(e===f?(this.debug(" drop over source node prevented"),q=null):"before"===q&&f&&e===f.getNextSibling()?(this.debug(" drop after source node prevented"),q=null):"after"===q&&f&&e===f.getPrevSibling()?(this.debug(" drop before source node prevented"),q=null):"over"===q&&f&&f.parent===e&&f.isLastSibling()&&(this.debug(" drop last child over own parent prevented"),q=null)),h.helper.data("hitMode",q))),"before"===q||"after"===q||!t.autoExpandMS||e.hasChildren()===!1||e.expanded||t.dragExpand&&t.dragExpand(e,u)===!1||e.scheduleAction("expand",t.autoExpandMS),q&&t.dragOver&&(u.hitMode=q,v=t.dragOver(e,u)),j=v!==!1&&null!==q,t.smartRevert&&(i.options.revert=!j),this._local._setDndStatus(f,e,h.helper,q,j);break;case"drop":q=h.helper.data("hitMode"),q&&t.dragDrop&&(u.hitMode=q,t.dragDrop(e,u));break;case"leave":e.scheduleAction("cancel"),h.helper.data("enterResponse",null),h.helper.data("hitMode",null),this._local._setDndStatus(f,e,h.helper,"out",d),t.dragLeave&&t.dragLeave(e,u);break;case"stop":x.removeClass("fancytree-drag-source"),a(c).off(".fancytree-dnd"),t.dragStop&&t.dragStop(e,u);break;default:a.error("Unsupported drag event: "+b)}return v},_cancelDrag:function(){var b=a.ui.ddmanager.current;b&&b.cancel()}})}(jQuery,window,document);
+!function(a){"function"==typeof define&&define.amd?define(["jquery","jquery-ui/ui/widgets/draggable","jquery-ui/ui/widgets/droppable","./jquery.fancytree"],a):"object"==typeof module&&module.exports?(require("jquery.fancytree"),module.exports=a(require("jquery"))):a(jQuery)}(function(a){"use strict";function b(a){return 0===a?"":a>0?"+"+a:""+a}function c(){e||(a.ui.plugin.add("draggable","connectToFancytree",{start:function(b,c){var d=a(this).data("ui-draggable")||a(this).data("draggable"),e=c.helper.data("ftSourceNode")||null;if(e)return d.offset.click.top=-2,d.offset.click.left=16,e.tree.ext.dnd._onDragEvent("start",e,null,b,c,d)},drag:function(b,c){var d,e,f,g=a(this).data("ui-draggable")||a(this).data("draggable"),h=c.helper.data("ftSourceNode")||null,i=c.helper.data("ftTargetNode")||null,j=a.ui.fancytree.getNode(b.target),k=h&&h.tree.options.dnd;return b.target&&!j&&(e=a(b.target).closest("div.fancytree-drag-helper,#fancytree-drop-marker").length>0)?(f=h||i||a.ui.fancytree,void f.debug("Drag event over helper: ignored.")):(c.helper.data("ftTargetNode",j),k&&k.updateHelper&&(d=h.tree._makeHookContext(h,b,{otherNode:j,ui:c,draggable:g,dropMarker:a("#fancytree-drop-marker")}),k.updateHelper.call(h.tree,h,d)),i&&i!==j&&i.tree.ext.dnd._onDragEvent("leave",i,h,b,c,g),void(j&&j.tree.options.dnd.dragDrop&&(j===i?j.tree.ext.dnd._onDragEvent("over",j,h,b,c,g):(j.tree.ext.dnd._onDragEvent("enter",j,h,b,c,g),j.tree.ext.dnd._onDragEvent("over",j,h,b,c,g)))))},stop:function(b,c){var d,e=a(this).data("ui-draggable")||a(this).data("draggable"),f=c.helper.data("ftSourceNode")||null,g=c.helper.data("ftTargetNode")||null,h="mouseup"===b.type&&1===b.which;h||(d=f||g||a.ui.fancytree,d.debug("Drag was cancelled")),g&&(h&&g.tree.ext.dnd._onDragEvent("drop",g,f,b,c,e),g.tree.ext.dnd._onDragEvent("leave",g,f,b,c,e)),f&&f.tree.ext.dnd._onDragEvent("stop",f,null,b,c,e)}}),e=!0)}function d(b){var d=b.options.dnd||null,e=b.options.glyph||null;d&&c(),d&&d.dragStart&&b.widget.element.draggable(a.extend({addClasses:!1,appendTo:b.$container,containment:!1,delay:0,distance:4,revert:!1,scroll:!0,scrollSpeed:7,scrollSensitivity:10,connectToFancytree:!0,helper:function(b){var c,d,f,g=a.ui.fancytree.getNode(b.target);return g?(f=g.tree.options.dnd,d=a(g.span),c=a("
"},start:function(a,b){var c=b.helper.data("ftSourceNode");return!!c}},b.options.dnd.draggable)),d&&d.dragDrop&&b.widget.element.droppable(a.extend({addClasses:!1,tolerance:"intersect",greedy:!1},b.options.dnd.droppable))}var e=!1,f="fancytree-drop-accept",g="fancytree-drop-after",h="fancytree-drop-before",i="fancytree-drop-over",j="fancytree-drop-reject",k="fancytree-drop-target";return a.ui.fancytree.registerExtension({name:"dnd",version:"2.26.0",options:{autoExpandMS:1e3,draggable:null,droppable:null,focusOnClick:!1,preventVoidMoves:!0,preventRecursiveMoves:!0,smartRevert:!0,dropMarkerOffsetX:-24,dropMarkerInsertOffsetX:-16,dragStart:null,dragStop:null,initHelper:null,updateHelper:null,dragEnter:null,dragOver:null,dragExpand:null,dragDrop:null,dragLeave:null},treeInit:function(b){var c=b.tree;this._superApply(arguments),c.options.dnd.dragStart&&c.$container.on("mousedown",function(c){if(b.options.dnd.focusOnClick){var d=a.ui.fancytree.getNode(c);d&&d.debug("Re-enable focus that was prevented by jQuery UI draggable."),setTimeout(function(){a(c.target).closest(":tabbable").focus()},10)}}),d(c)},_setDndStatus:function(c,d,e,l,m){var n,o="center",p=this._local,q=this.options.dnd,r=this.options.glyph,s=c?a(c.span):null,t=a(d.span),u=t.find("span.fancytree-title");if(p.$dropMarker||(p.$dropMarker=a("").hide().css({"z-index":1e3}).prependTo(a(this.$div).parent()),r&&p.$dropMarker.addClass(r.map.dropMarker)),"after"===l||"before"===l||"over"===l){switch(n=q.dropMarkerOffsetX||0,l){case"before":o="top",n+=q.dropMarkerInsertOffsetX||0;break;case"after":o="bottom",n+=q.dropMarkerInsertOffsetX||0}p.$dropMarker.toggleClass(g,"after"===l).toggleClass(i,"over"===l).toggleClass(h,"before"===l).show().position(a.ui.fancytree.fixPositionOptions({my:"left"+b(n)+" center",at:"left "+o,of:u}))}else p.$dropMarker.hide();s&&s.toggleClass(f,m===!0).toggleClass(j,m===!1),t.toggleClass(k,"after"===l||"before"===l||"over"===l).toggleClass(g,"after"===l).toggleClass(h,"before"===l).toggleClass(f,m===!0).toggleClass(j,m===!1),e.toggleClass(f,m===!0).toggleClass(j,m===!1)},_onDragEvent:function(b,c,d,e,f,g){var h,i,j,k,l,m,n,o,p,q=this.options,r=q.dnd,s=this._makeHookContext(c,e,{otherNode:d,ui:f,draggable:g}),t=null,u=this,v=a(c.span);switch(r.smartRevert&&(g.options.revert="invalid"),b){case"start":c.isStatusNode()?t=!1:r.dragStart&&(t=r.dragStart(c,s)),t===!1?(this.debug("tree.dragStart() cancelled"),f.helper.trigger("mouseup").hide()):(r.smartRevert&&(k=c[s.tree.nodeContainerAttrName].getBoundingClientRect(),j=a(g.options.appendTo)[0].getBoundingClientRect(),g.originalPosition.left=Math.max(0,k.left-j.left),g.originalPosition.top=Math.max(0,k.top-j.top)),v.addClass("fancytree-drag-source"),a(document).on("keydown.fancytree-dnd,mousedown.fancytree-dnd",function(b){"keydown"===b.type&&b.which===a.ui.keyCode.ESCAPE?u.ext.dnd._cancelDrag():"mousedown"===b.type&&u.ext.dnd._cancelDrag()}));break;case"enter":p=(!r.preventRecursiveMoves||!c.isDescendantOf(d))&&(r.dragEnter?r.dragEnter(c,s):null),t=!!p&&(a.isArray(p)?{over:a.inArray("over",p)>=0,before:a.inArray("before",p)>=0,after:a.inArray("after",p)>=0}:{over:p===!0||"over"===p,before:p===!0||"before"===p,after:p===!0||"after"===p}),f.helper.data("enterResponse",t);break;case"over":n=f.helper.data("enterResponse"),o=null,n===!1||("string"==typeof n?o=n:(i=v.offset(),l={x:e.pageX-i.left,y:e.pageY-i.top},m={x:l.x/v.width(),y:l.y/v.height()},n.after&&m.y>.75?o="after":!n.over&&n.after&&m.y>.5?o="after":n.before&&m.y<=.25?o="before":!n.over&&n.before&&m.y<=.5?o="before":n.over&&(o="over"),r.preventVoidMoves&&(c===d?(this.debug(" drop over source node prevented"),o=null):"before"===o&&d&&c===d.getNextSibling()?(this.debug(" drop after source node prevented"),o=null):"after"===o&&d&&c===d.getPrevSibling()?(this.debug(" drop before source node prevented"),o=null):"over"===o&&d&&d.parent===c&&d.isLastSibling()&&(this.debug(" drop last child over own parent prevented"),o=null)),f.helper.data("hitMode",o))),"before"===o||"after"===o||!r.autoExpandMS||c.hasChildren()===!1||c.expanded||r.dragExpand&&r.dragExpand(c,s)===!1||c.scheduleAction("expand",r.autoExpandMS),o&&r.dragOver&&(s.hitMode=o,t=r.dragOver(c,s)),h=t!==!1&&null!==o,r.smartRevert&&(g.options.revert=!h),this._local._setDndStatus(d,c,f.helper,o,h);break;case"drop":o=f.helper.data("hitMode"),o&&r.dragDrop&&(s.hitMode=o,r.dragDrop(c,s));break;case"leave":c.scheduleAction("cancel"),f.helper.data("enterResponse",null),f.helper.data("hitMode",null),this._local._setDndStatus(d,c,f.helper,"out",void 0),r.dragLeave&&r.dragLeave(c,s);break;case"stop":v.removeClass("fancytree-drag-source"),a(document).off(".fancytree-dnd"),r.dragStop&&r.dragStop(c,s);break;default:a.error("Unsupported drag event: "+b)}return t},_cancelDrag:function(){var b=a.ui.ddmanager.current;b&&b.cancel()}}),a.ui.fancytree});
/*! Extension 'jquery.fancytree.dnd5.min.js' */
-!function(a,b,c,d){"use strict";function e(a){return 0===a?"":a>0?"+"+a:""+a}function f(b){var c;return!!b&&(c=a.isPlainObject(b)?{over:!!b.over,before:!!b.before,after:!!b.after}:a.isArray(b)?{over:a.inArray("over",b)>=0,before:a.inArray("before",b)>=0,after:a.inArray("after",b)>=0}:{over:b===!0||"over"===b,before:b===!0||"before"===b,after:b===!0||"after"===b},0!==Object.keys(c).length&&c)}function g(d,e){var f,g,h,i=d.options.dnd5,j=d.$scrollParent[0],k=i.scrollSensitivity,l=i.scrollSpeed,m=0;return j!==c&&"HTML"!==j.tagName?(f=d.$scrollParent.offset(),g=j.scrollTop,f.top+j.offsetHeight-e.pageY0&&(j.scrollTop=m=g+l)):g>0&&e.pageY-f.top0&&e.pageY-g.75?i="after":!t.over&&t.after&&h>.5?i="after":t.before&&h<=.25?i="before":!t.over&&t.before&&h<=.5?i="before":t.over&&(i="over"),s.preventVoidMoves&&(v===w?(v.debug("drop over source node prevented"),i=null):"before"===i&&w&&v===w.getNextSibling()?(v.debug("drop after source node prevented"),i=null):"after"===i&&w&&v===w.getPrevSibling()?(v.debug("drop before source node prevented"),i=null):"over"===i&&w&&w.parent===v&&w.isLastSibling()&&(v.debug("drop last child over own parent prevented"),i=null))),c.hitMode=i,i&&s.dragOver&&(s.dragOver(v,c),i=c.hitMode),u=i,"after"===i||"before"===i||"over"===i){switch(d=s.dropMarkerOffsetX||0,i){case"before":x="top",d+=s.dropMarkerInsertOffsetX||0;break;case"after":x="bottom",d+=s.dropMarkerInsertOffsetX||0}r.toggleClass(l,"after"===i).toggleClass(n,"over"===i).toggleClass(m,"before"===i).show().position(a.ui.fancytree.fixPositionOptions({my:"left"+e(d)+" center",at:"left "+x,of:z}))}else r.hide();return a(v.span).toggleClass(p,"after"===i||"before"===i||"over"===i).toggleClass(l,"after"===i).toggleClass(m,"before"===i).toggleClass(k,"over"===i).toggleClass(o,i===!1),i}var i="fancytree-drag-source",j="fancytree-drag-remove",k="fancytree-drop-accept",l="fancytree-drop-after",m="fancytree-drop-before",n="fancytree-drop-over",o="fancytree-drop-reject",p="fancytree-drop-target",q="application/x-fancytree-node",r=null,s=null,t=null,u=null;a.ui.fancytree.registerExtension({name:"dnd5",version:"2.23.0",options:{autoExpandMS:1500,setTextTypeJson:!1,preventForeignNodes:!1,preventNonNodes:!1,preventRecursiveMoves:!0,preventVoidMoves:!0,scroll:!0,scrollSensitivity:20,scrollSpeed:5,dropMarkerOffsetX:-24,dropMarkerInsertOffsetX:-16,dragStart:null,dragDrag:a.noop,dragEnd:a.noop,dragEnter:null,dragOver:a.noop,dragExpand:a.noop,dragDrop:a.noop,dragLeave:a.noop},treeInit:function(b){var c=b.tree,e=b.options,g=e.dnd5,l=a.ui.fancytree.getNode;a.inArray("dnd",e.extensions)>=0&&a.error("Extensions 'dnd' and 'dnd5' are mutually exclusive."),g.dragStop&&a.error("dragStop is not used by ext-dnd5. Use dragEnd instead."),g.dragStart&&a.ui.fancytree.overrideMethod(b.options,"createNode",function(a,b){this._super.apply(this,arguments),b.node.span.draggable=!0}),this._superApply(arguments),this.$container.addClass("fancytree-ext-dnd5"),this.$scrollParent=this.$container.children(":first").scrollParent(),r=a("#fancytree-drop-marker"),r.length||(r=a("").hide().css({"z-index":1e3,"pointer-events":"none"}).prependTo("body")),g.dragStart&&c.$container.on("dragstart drag dragend",function(b){var e,f=l(b),h=b.dataTransfer||b.originalEvent.dataTransfer,k="move"===h.dropEffect,m=f?a(f.span):null,n={node:f,tree:c,options:c.options,originalEvent:b,dataTransfer:h,isCancelled:d};switch(b.type){case"dragstart":a(f.span).addClass(i),s=f,e=JSON.stringify(f.toDict());try{h.setData(q,e),h.setData("text/html",a(f.span).html()),h.setData("text/plain",f.title)}catch(o){c.warn("Could not set data (IE only accepts 'text') - "+o)}return g.setTextTypeJson?h.setData("text",e):h.setData("text",f.title),h.effectAllowed="all",h.setDragImage&&h.setDragImage(a(f.span).find(".fancytree-title")[0],-10,-10),g.dragStart(f,n)!==!1;case"drag":m.toggleClass(j,k),g.dragDrag(f,n);break;case"dragend":a(f.span).removeClass(i+" "+j),s=null,t=null,n.isCancelled="none"===h.dropEffect,r.hide(),g.dragEnd(f,n)}}),g.dragEnter&&c.$container.on("dragenter dragover dragleave drop",function(b){var e,i,j,m,p=null,v=l(b),w=b.dataTransfer||b.originalEvent.dataTransfer,x={node:v,tree:c,options:c.options,hitMode:t,originalEvent:b,dataTransfer:w,otherNode:s||null,otherNodeData:null,dropEffect:d,isCancelled:d};switch(b.type){case"dragenter":if(!v){c.debug("Ignore non-node "+b.type+": "+b.target.tagName+"."+b.target.className),t=!1;break}if(a(v.span).addClass(n).removeClass(k+" "+o),g.preventNonNodes&&!i){v.debug("Reject dropping a non-node"),t=!1;break}if(g.preventForeignNodes&&(!s||s.tree!==v.tree)){v.debug("Reject dropping a foreign node"),t=!1;break}setTimeout(function(){!g.autoExpandMS||v.hasChildren()===!1||v.expanded||g.dragExpand&&g.dragExpand(v,x)===!1||v.scheduleAction("expand",g.autoExpandMS)},0),r.show(),g.preventRecursiveMoves&&v.isDescendantOf(x.otherNode)?m=!1:(j=g.dragEnter(v,x),m=f(j)),t=m,p=m&&(m.over||m.before||m.after);break;case"dragover":u=h(b,x),p=!!u;break;case"dragleave":if(!v){c.debug("Ignore non-node "+b.type+": "+b.target.tagName+"."+b.target.className);break}if(!a(v.span).hasClass(n)){v.debug("Ignore dragleave (multi)");break}a(v.span).removeClass(n+" "+k+" "+o),v.scheduleAction("cancel"),g.dragLeave(v,x),r.hide();break;case"drop":if(a.inArray(q,w.types)>=0&&(i=w.getData(q),c.info(b.type+": getData('application/x-fancytree-node'): '"+i+"'")),i||(i=w.getData("text"),c.info(b.type+": getData('text'): '"+i+"'")),i)try{e=JSON.parse(i),e.title!==d&&(x.otherNodeData=e)}catch(y){}c.debug(b.type+": nodeData: '"+i+"', otherNodeData: ",x.otherNodeData),a(v.span).removeClass(n+" "+k+" "+o),r.hide(),x.hitMode=u,x.dropEffect=w.dropEffect,x.isCancelled="none"===x.dropEffect,g.dragDrop(v,x),b.preventDefault()}if(p)return b.preventDefault(),!1})}})}(jQuery,window,document);
+!function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],a):"object"==typeof module&&module.exports?(require("jquery.fancytree"),module.exports=a(require("jquery"))):a(jQuery)}(function(a){"use strict";function b(a){return 0===a?"":a>0?"+"+a:""+a}function c(b){var c;return!!b&&(c=a.isPlainObject(b)?{over:!!b.over,before:!!b.before,after:!!b.after}:a.isArray(b)?{over:a.inArray("over",b)>=0,before:a.inArray("before",b)>=0,after:a.inArray("after",b)>=0}:{over:b===!0||"over"===b,before:b===!0||"before"===b,after:b===!0||"after"===b},0!==Object.keys(c).length&&c)}function d(b,c){var d,e,f,g=b.options.dnd5,h=b.$scrollParent[0],i=g.scrollSensitivity,j=g.scrollSpeed,k=0;return h!==document&&"HTML"!==h.tagName?(d=b.$scrollParent.offset(),e=h.scrollTop,d.top+h.offsetHeight-c.pageY0&&(h.scrollTop=k=e+j)):e>0&&c.pageY-d.top0&&c.pageY-e.75?p="after":!q.over&&q.after&&n>.5?p="after":q.before&&n<=.25?p="before":!q.over&&q.before&&n<=.5?p="before":q.over&&(p="over"),u.preventVoidMoves&&(v===w?(v.debug("drop over source node prevented"),p=null):"before"===p&&w&&v===w.getNextSibling()?(v.debug("drop after source node prevented"),p=null):"after"===p&&w&&v===w.getPrevSibling()?(v.debug("drop before source node prevented"),p=null):"over"===p&&w&&w.parent===v&&w.isLastSibling()&&(v.debug("drop last child over own parent prevented"),p=null))),e.hitMode=p,p&&u.dragOver&&(u.dragOver(v,e),p=e.hitMode),r=p,"after"===p||"before"===p||"over"===p){switch(f=u.dropMarkerOffsetX||0,p){case"before":x="top",f+=u.dropMarkerInsertOffsetX||0;break;case"after":x="bottom",f+=u.dropMarkerInsertOffsetX||0}o.toggleClass(i,"after"===p).toggleClass(k,"over"===p).toggleClass(j,"before"===p).show().position(a.ui.fancytree.fixPositionOptions({my:"left"+b(f)+" center",at:"left "+x,of:z}))}else o.hide();return a(v.span).toggleClass(m,"after"===p||"before"===p||"over"===p).toggleClass(i,"after"===p).toggleClass(j,"before"===p).toggleClass(h,"over"===p).toggleClass(l,p===!1),p}var f="fancytree-drag-source",g="fancytree-drag-remove",h="fancytree-drop-accept",i="fancytree-drop-after",j="fancytree-drop-before",k="fancytree-drop-over",l="fancytree-drop-reject",m="fancytree-drop-target",n="application/x-fancytree-node",o=null,p=null,q=null,r=null;return a.ui.fancytree.registerExtension({name:"dnd5",version:"2.26.0",options:{autoExpandMS:1500,setTextTypeJson:!1,preventForeignNodes:!1,preventNonNodes:!1,preventRecursiveMoves:!0,preventVoidMoves:!0,scroll:!0,scrollSensitivity:20,scrollSpeed:5,dropMarkerOffsetX:-24,dropMarkerInsertOffsetX:-16,dragStart:null,dragDrag:a.noop,dragEnd:a.noop,dragEnter:null,dragOver:a.noop,dragExpand:a.noop,dragDrop:a.noop,dragLeave:a.noop},treeInit:function(b){var d,i=b.tree,j=b.options,m=j.glyph||null,s=j.dnd5,t=a.ui.fancytree.getNode;a.inArray("dnd",j.extensions)>=0&&a.error("Extensions 'dnd' and 'dnd5' are mutually exclusive."),s.dragStop&&a.error("dragStop is not used by ext-dnd5. Use dragEnd instead."),s.dragStart&&a.ui.fancytree.overrideMethod(b.options,"createNode",function(a,b){this._super.apply(this,arguments),b.node.span.draggable=!0}),this._superApply(arguments),this.$container.addClass("fancytree-ext-dnd5"),d=a("").appendTo(this.$container),this.$scrollParent=d.scrollParent(),d.remove(),o=a("#fancytree-drop-marker"),o.length||(o=a("").hide().css({"z-index":1e3,"pointer-events":"none"}).prependTo("body"),m&&o.addClass(m.map.dropMarker)),s.dragStart&&i.$container.on("dragstart drag dragend",function(b){var c,d=t(b),e=b.dataTransfer||b.originalEvent.dataTransfer,h="move"===e.dropEffect,j=d?a(d.span):null,k={node:d,tree:i,options:i.options,originalEvent:b,dataTransfer:e,isCancelled:void 0};switch(b.type){case"dragstart":a(d.span).addClass(f),p=d,c=JSON.stringify(d.toDict());try{e.setData(n,c),e.setData("text/html",a(d.span).html()),e.setData("text/plain",d.title)}catch(l){i.warn("Could not set data (IE only accepts 'text') - "+l)}return s.setTextTypeJson?e.setData("text",c):e.setData("text",d.title),e.effectAllowed="all",e.setDragImage&&e.setDragImage(a(d.span).find(".fancytree-title")[0],-10,-10),s.dragStart(d,k)!==!1;case"drag":j.toggleClass(g,h),s.dragDrag(d,k);break;case"dragend":a(d.span).removeClass(f+" "+g),p=null,q=null,k.isCancelled="none"===e.dropEffect,o.hide(),s.dragEnd(d,k)}}),s.dragEnter&&i.$container.on("dragenter dragover dragleave drop",function(b){var d,f,g,j,m=null,u=t(b),v=b.dataTransfer||b.originalEvent.dataTransfer,w={node:u,tree:i,options:i.options,hitMode:q,originalEvent:b,dataTransfer:v,otherNode:p||null,otherNodeData:null,dropEffect:void 0,isCancelled:void 0};switch(b.type){case"dragenter":if(!u){i.debug("Ignore non-node "+b.type+": "+b.target.tagName+"."+b.target.className),q=!1;break}if(a(u.span).addClass(k).removeClass(h+" "+l),s.preventNonNodes&&!f){u.debug("Reject dropping a non-node"),q=!1;break}if(s.preventForeignNodes&&(!p||p.tree!==u.tree)){u.debug("Reject dropping a foreign node"),q=!1;break}setTimeout(function(){!s.autoExpandMS||u.hasChildren()===!1||u.expanded||s.dragExpand&&s.dragExpand(u,w)===!1||u.scheduleAction("expand",s.autoExpandMS)},0),o.show(),s.preventRecursiveMoves&&u.isDescendantOf(w.otherNode)?j=!1:(g=s.dragEnter(u,w),j=c(g)),q=j,m=j&&(j.over||j.before||j.after);break;case"dragover":r=e(b,w),m=!!r;break;case"dragleave":if(!u){i.debug("Ignore non-node "+b.type+": "+b.target.tagName+"."+b.target.className);break}if(!a(u.span).hasClass(k)){u.debug("Ignore dragleave (multi)");break}a(u.span).removeClass(k+" "+h+" "+l),u.scheduleAction("cancel"),s.dragLeave(u,w),o.hide();break;case"drop":if(a.inArray(n,v.types)>=0&&(f=v.getData(n),i.info(b.type+": getData('application/x-fancytree-node'): '"+f+"'")),f||(f=v.getData("text"),i.info(b.type+": getData('text'): '"+f+"'")),f)try{d=JSON.parse(f),void 0!==d.title&&(w.otherNodeData=d)}catch(x){}i.debug(b.type+": nodeData: '"+f+"', otherNodeData: ",w.otherNodeData),a(u.span).removeClass(k+" "+h+" "+l),o.hide(),w.hitMode=r,w.dropEffect=v.dropEffect,w.isCancelled="none"===w.dropEffect,s.dragDrop(u,w),b.preventDefault()}if(m)return b.preventDefault(),!1})}}),a.ui.fancytree});
/*! Extension 'jquery.fancytree.edit.min.js' */
-!function(a,b,c,d){"use strict";var e=/Mac/.test(navigator.platform),f=a.ui.fancytree.escapeHtml,g=a.ui.fancytree.unescapeHtml;a.ui.fancytree._FancytreeNodeClass.prototype.editStart=function(){var b,d=this,e=this.tree,f=e.ext.edit,h=e.options.edit,i=a(".fancytree-title",d.span),j={node:d,tree:e,options:e.options,isNew:a(d[e.statusClassPropName]).hasClass("fancytree-edit-new"),orgTitle:d.title,input:null,dirty:!1};return h.beforeEdit.call(d,{type:"beforeEdit"},j)!==!1&&(a.ui.fancytree.assert(!f.currentNode,"recursive edit"),f.currentNode=this,f.eventData=j,e.widget._unbind(),a(c).on("mousedown.fancytree-edit",function(b){a(b.target).hasClass("fancytree-edit-input")||d.editEnd(!0,b)}),b=a("",{"class":"fancytree-edit-input",type:"text",value:e.options.escapeTitles?j.orgTitle:g(j.orgTitle)}),f.eventData.input=b,null!=h.adjustWidthOfs&&b.width(i.width()+h.adjustWidthOfs),null!=h.inputCss&&b.css(h.inputCss),i.html(b),b.focus().change(function(a){b.addClass("fancytree-edit-dirty")}).keydown(function(b){switch(b.which){case a.ui.keyCode.ESCAPE:d.editEnd(!1,b);break;case a.ui.keyCode.ENTER:return d.editEnd(!0,b),!1}b.stopPropagation()}).blur(function(a){return d.editEnd(!0,a)}),void h.edit.call(d,{type:"edit"},j))},a.ui.fancytree._FancytreeNodeClass.prototype.editEnd=function(b,d){var e,g=this,h=this.tree,i=h.ext.edit,j=i.eventData,k=h.options.edit,l=a(".fancytree-title",g.span),m=l.find("input.fancytree-edit-input");return k.trim&&m.val(a.trim(m.val())),e=m.val(),j.dirty=e!==g.title,j.originalEvent=d,b===!1?j.save=!1:j.isNew?j.save=""!==e:j.save=j.dirty&&""!==e,k.beforeClose.call(g,{type:"beforeClose"},j)!==!1&&((!j.save||k.save.call(g,{type:"save"},j)!==!1)&&(m.removeClass("fancytree-edit-dirty").off(),a(c).off(".fancytree-edit"),j.save?(g.setTitle(h.options.escapeTitles?e:f(e)),g.setFocus()):j.isNew?(g.remove(),g=j.node=null,i.relatedNode.setFocus()):(g.renderTitle(),g.setFocus()),i.eventData=null,i.currentNode=null,i.relatedNode=null,h.widget._bind(),a(h.$container).focus(),j.input=null,k.close.call(g,{type:"close"},j),!0))},a.ui.fancytree._FancytreeNodeClass.prototype.editCreateNode=function(b,c){var d,e=this.tree,f=this;return b=b||"child",null==c?c={title:""}:"string"==typeof c?c={title:c}:a.ui.fancytree.assert(a.isPlainObject(c)),"child"!==b||this.isExpanded()||this.hasChildren()===!1?(d=this.addNode(c,b),d.match=!0,a(d[e.statusClassPropName]).removeClass("fancytree-hide").addClass("fancytree-match"),void d.makeVisible().done(function(){a(d[e.statusClassPropName]).addClass("fancytree-edit-new"),f.tree.ext.edit.relatedNode=f,d.editStart()})):void this.setExpanded().done(function(){f.editCreateNode(b,c)})},a.ui.fancytree._FancytreeClass.prototype.isEditing=function(){return this.ext.edit?this.ext.edit.currentNode:null},a.ui.fancytree._FancytreeNodeClass.prototype.isEditing=function(){return!!this.tree.ext.edit&&this.tree.ext.edit.currentNode===this},a.ui.fancytree.registerExtension({name:"edit",version:"2.23.0",options:{adjustWidthOfs:4,allowEmpty:!1,inputCss:{minWidth:"3em"},triggerStart:["f2","shift+click","mac+enter"],trim:!0,beforeClose:a.noop,beforeEdit:a.noop,close:a.noop,edit:a.noop,save:a.noop},currentNode:null,treeInit:function(a){this._superApply(arguments),this.$container.addClass("fancytree-ext-edit")},nodeClick:function(b){return a.inArray("shift+click",b.options.edit.triggerStart)>=0&&b.originalEvent.shiftKey?(b.node.editStart(),!1):this._superApply(arguments)},nodeDblclick:function(b){return a.inArray("dblclick",b.options.edit.triggerStart)>=0?(b.node.editStart(),!1):this._superApply(arguments)},nodeKeydown:function(b){switch(b.originalEvent.which){case 113:if(a.inArray("f2",b.options.edit.triggerStart)>=0)return b.node.editStart(),!1;break;case a.ui.keyCode.ENTER:if(a.inArray("mac+enter",b.options.edit.triggerStart)>=0&&e)return b.node.editStart(),!1}return this._superApply(arguments)}})}(jQuery,window,document);
+!function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],a):"object"==typeof module&&module.exports?(require("jquery.fancytree"),module.exports=a(require("jquery"))):a(jQuery)}(function(a){"use strict";var b=/Mac/.test(navigator.platform),c=a.ui.fancytree.escapeHtml,d=a.ui.fancytree.unescapeHtml;return a.ui.fancytree._FancytreeNodeClass.prototype.editStart=function(){var b,c=this,e=this.tree,f=e.ext.edit,g=e.options.edit,h=a(".fancytree-title",c.span),i={node:c,tree:e,options:e.options,isNew:a(c[e.statusClassPropName]).hasClass("fancytree-edit-new"),orgTitle:c.title,input:null,dirty:!1};return g.beforeEdit.call(c,{type:"beforeEdit"},i)!==!1&&(a.ui.fancytree.assert(!f.currentNode,"recursive edit"),f.currentNode=this,f.eventData=i,e.widget._unbind(),a(document).on("mousedown.fancytree-edit",function(b){a(b.target).hasClass("fancytree-edit-input")||c.editEnd(!0,b)}),b=a("",{"class":"fancytree-edit-input",type:"text",value:e.options.escapeTitles?i.orgTitle:d(i.orgTitle)}),f.eventData.input=b,null!=g.adjustWidthOfs&&b.width(h.width()+g.adjustWidthOfs),null!=g.inputCss&&b.css(g.inputCss),h.html(b),b.focus().change(function(a){b.addClass("fancytree-edit-dirty")}).keydown(function(b){switch(b.which){case a.ui.keyCode.ESCAPE:c.editEnd(!1,b);break;case a.ui.keyCode.ENTER:return c.editEnd(!0,b),!1}b.stopPropagation()}).blur(function(a){return c.editEnd(!0,a)}),void g.edit.call(c,{type:"edit"},i))},a.ui.fancytree._FancytreeNodeClass.prototype.editEnd=function(b,d){var e,f=this,g=this.tree,h=g.ext.edit,i=h.eventData,j=g.options.edit,k=a(".fancytree-title",f.span),l=k.find("input.fancytree-edit-input");return j.trim&&l.val(a.trim(l.val())),e=l.val(),i.dirty=e!==f.title,i.originalEvent=d,b===!1?i.save=!1:i.isNew?i.save=""!==e:i.save=i.dirty&&""!==e,j.beforeClose.call(f,{type:"beforeClose"},i)!==!1&&((!i.save||j.save.call(f,{type:"save"},i)!==!1)&&(l.removeClass("fancytree-edit-dirty").off(),a(document).off(".fancytree-edit"),i.save?(f.setTitle(g.options.escapeTitles?e:c(e)),f.setFocus()):i.isNew?(f.remove(),f=i.node=null,h.relatedNode.setFocus()):(f.renderTitle(),f.setFocus()),h.eventData=null,h.currentNode=null,h.relatedNode=null,g.widget._bind(),a(g.$container).focus(),i.input=null,j.close.call(f,{type:"close"},i),!0))},a.ui.fancytree._FancytreeNodeClass.prototype.editCreateNode=function(b,c){var d,e=this.tree,f=this;return b=b||"child",null==c?c={title:""}:"string"==typeof c?c={title:c}:a.ui.fancytree.assert(a.isPlainObject(c)),"child"!==b||this.isExpanded()||this.hasChildren()===!1?(d=this.addNode(c,b),d.match=!0,a(d[e.statusClassPropName]).removeClass("fancytree-hide").addClass("fancytree-match"),void d.makeVisible().done(function(){a(d[e.statusClassPropName]).addClass("fancytree-edit-new"),f.tree.ext.edit.relatedNode=f,d.editStart()})):void this.setExpanded().done(function(){f.editCreateNode(b,c)})},a.ui.fancytree._FancytreeClass.prototype.isEditing=function(){return this.ext.edit?this.ext.edit.currentNode:null},a.ui.fancytree._FancytreeNodeClass.prototype.isEditing=function(){return!!this.tree.ext.edit&&this.tree.ext.edit.currentNode===this},a.ui.fancytree.registerExtension({name:"edit",version:"2.26.0",options:{adjustWidthOfs:4,allowEmpty:!1,inputCss:{minWidth:"3em"},triggerStart:["f2","shift+click","mac+enter"],trim:!0,beforeClose:a.noop,beforeEdit:a.noop,close:a.noop,edit:a.noop,save:a.noop},currentNode:null,treeInit:function(a){this._superApply(arguments),this.$container.addClass("fancytree-ext-edit")},nodeClick:function(b){return a.inArray("shift+click",b.options.edit.triggerStart)>=0&&b.originalEvent.shiftKey?(b.node.editStart(),!1):this._superApply(arguments)},nodeDblclick:function(b){return a.inArray("dblclick",b.options.edit.triggerStart)>=0?(b.node.editStart(),!1):this._superApply(arguments)},nodeKeydown:function(c){switch(c.originalEvent.which){case 113:if(a.inArray("f2",c.options.edit.triggerStart)>=0)return c.node.editStart(),!1;break;case a.ui.keyCode.ENTER:if(a.inArray("mac+enter",c.options.edit.triggerStart)>=0&&b)return c.node.editStart(),!1}return this._superApply(arguments)}}),a.ui.fancytree});
/*! Extension 'jquery.fancytree.filter.min.js' */
-!function(a,b,c,d){"use strict";function e(a){return(a+"").replace(/([.?*+\^\$\[\]\\(){}|-])/g,"\\$1")}function f(b){return b.indexOf(">")>=0?a("").html(b).text():b}var g="__not_found__",h=a.ui.fancytree.escapeHtml;a.ui.fancytree._FancytreeClass.prototype._applyFilterImpl=function(b,c,d){var i,j,k,l,m=0,n=this.options,o=n.escapeTitles,p=n.autoCollapse,q=a.extend({},n.filter,d),r="hide"===q.mode,s=!!q.leavesOnly&&!c;return"string"==typeof b&&(i=q.fuzzy?b.split("").reduce(function(a,b){return a+"[^"+b+"]*"+b}):e(b),k=new RegExp(".*"+i+".*","i"),l=new RegExp(e(b),"gi"),b=function(a){var b,c=o?a.title:f(a.title),d=!!k.test(c);return d&&q.highlight&&(b=o?h(a.title):c,a.titleWithHighlight=b.replace(l,function(a){return""+a+""})),d}),this.enableFilter=!0,this.lastFilterArgs=arguments,this.$div.addClass("fancytree-ext-filter"),r?this.$div.addClass("fancytree-ext-filter-hide"):this.$div.addClass("fancytree-ext-filter-dimm"),this.$div.toggleClass("fancytree-ext-filter-hide-expanders",!!q.hideExpanders),this.visit(function(a){delete a.match,delete a.titleWithHighlight,a.subMatchCount=0}),j=this.getRootNode()._findDirectChild(g),j&&j.remove(),n.autoCollapse=!1,this.visit(function(a){if(!s||null==a.children){var d=b(a),e=!1;if("skip"===d)return a.visit(function(a){a.match=!1},!0),"skip";d||!c&&"branch"!==d||!a.parent.match||(d=!0,e=!0),d&&(m++,a.match=!0,a.visitParents(function(a){a.subMatchCount+=1,!q.autoExpand||e||a.expanded||(a.setExpanded(!0,{noAnimation:!0,noEvents:!0,scrollIntoView:!1}),a._filterAutoExpanded=!0)}))}}),n.autoCollapse=p,0===m&&q.nodata&&r&&(j=q.nodata,a.isFunction(j)&&(j=j()),j===!0?j={}:"string"==typeof j&&(j={title:j}),j=a.extend({statusNodeType:"nodata",key:g,title:this.options.strings.noData},j),this.getRootNode().addNode(j).match=!0),this.render(),m},a.ui.fancytree._FancytreeClass.prototype.filterNodes=function(a,b){return"boolean"==typeof b&&(b={leavesOnly:b},this.warn("Fancytree.filterNodes() leavesOnly option is deprecated since 2.9.0 / 2015-04-19. Use opts.leavesOnly instead.")),this._applyFilterImpl(a,!1,b)},a.ui.fancytree._FancytreeClass.prototype.applyFilter=function(a){return this.warn("Fancytree.applyFilter() is deprecated since 2.1.0 / 2014-05-29. Use .filterNodes() instead."),this.filterNodes.apply(this,arguments)},a.ui.fancytree._FancytreeClass.prototype.filterBranches=function(a,b){return this._applyFilterImpl(a,!0,b)},a.ui.fancytree._FancytreeClass.prototype.clearFilter=function(){var b,c=this.getRootNode()._findDirectChild(g),d=this.options.escapeTitles,e=this.options.enhanceTitle;c&&c.remove(),this.visit(function(c){c.match&&c.span&&(b=a(c.span).find(">span.fancytree-title"),d?b.text(c.title):b.html(c.title),e&&e({type:"enhanceTitle"},{node:c,$title:b})),delete c.match,delete c.subMatchCount,delete c.titleWithHighlight,c.$subMatchBadge&&(c.$subMatchBadge.remove(),delete c.$subMatchBadge),c._filterAutoExpanded&&c.expanded&&c.setExpanded(!1,{noAnimation:!0,noEvents:!0,scrollIntoView:!1}),delete c._filterAutoExpanded}),this.enableFilter=!1,this.lastFilterArgs=null,this.$div.removeClass("fancytree-ext-filter fancytree-ext-filter-dimm fancytree-ext-filter-hide"),this.render()},a.ui.fancytree._FancytreeClass.prototype.isFilterActive=function(){return!!this.enableFilter},a.ui.fancytree._FancytreeNodeClass.prototype.isMatched=function(){return!(this.tree.enableFilter&&!this.match)},a.ui.fancytree.registerExtension({name:"filter",version:"2.23.0",options:{autoApply:!0,autoExpand:!1,counter:!0,fuzzy:!1,hideExpandedCounter:!0,hideExpanders:!1,highlight:!0,leavesOnly:!1,nodata:!0,mode:"dimm"},nodeLoadChildren:function(a,b){return this._superApply(arguments).done(function(){a.tree.enableFilter&&a.tree.lastFilterArgs&&a.options.filter.autoApply&&a.tree._applyFilterImpl.apply(a.tree,a.tree.lastFilterArgs)})},nodeSetExpanded:function(a,b,c){return delete a.node._filterAutoExpanded,!b&&a.options.filter.hideExpandedCounter&&a.node.$subMatchBadge&&a.node.$subMatchBadge.show(),this._superApply(arguments)},nodeRenderStatus:function(b){var c,d=b.node,e=b.tree,f=b.options.filter,g=a(d.span).find("span.fancytree-title"),h=a(d[e.statusClassPropName]),i=b.options.enhanceTitle,j=b.options.escapeTitles;return c=this._super(b),h.length&&e.enableFilter?(h.toggleClass("fancytree-match",!!d.match).toggleClass("fancytree-submatch",!!d.subMatchCount).toggleClass("fancytree-hide",!(d.match||d.subMatchCount)),!f.counter||!d.subMatchCount||d.isExpanded()&&f.hideExpandedCounter?d.$subMatchBadge&&d.$subMatchBadge.hide():(d.$subMatchBadge||(d.$subMatchBadge=a(""),a("span.fancytree-icon, span.fancytree-custom-icon",d.span).append(d.$subMatchBadge)),d.$subMatchBadge.show().text(d.subMatchCount)),!d.span||d.isEditing&&d.isEditing.call(d)||(d.titleWithHighlight?g.html(d.titleWithHighlight):j?g.text(d.title):g.html(d.title),i&&i({type:"enhanceTitle"},{node:d,$title:g})),c):c}})}(jQuery,window,document);
+!function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],a):"object"==typeof module&&module.exports?(require("jquery.fancytree"),module.exports=a(require("jquery"))):a(jQuery)}(function(a){"use strict";function b(a){return(a+"").replace(/([.?*+\^\$\[\]\\(){}|-])/g,"\\$1")}function c(b){return b.indexOf(">")>=0?a("").html(b).text():b}var d="__not_found__",e=a.ui.fancytree.escapeHtml;return a.ui.fancytree._FancytreeClass.prototype._applyFilterImpl=function(f,g,h){var i,j,k,l,m,n=0,o=this.options,p=o.escapeTitles,q=o.autoCollapse,r=a.extend({},o.filter,h),s="hide"===r.mode,t=!!r.leavesOnly&&!g;if("string"==typeof f){if(""===f)return this.warn("Fancytree passing an empty string as a filter is handled as clearFilter()."),void this.clearFilter();i=r.fuzzy?f.split("").reduce(function(a,b){return a+"[^"+b+"]*"+b}):b(f),k=new RegExp(".*"+i+".*","i"),l=new RegExp(b(f),"gi"),f=function(a){var b=p?a.title:c(a.title),d=!!k.test(b);return d&&r.highlight&&(p?(m=b.replace(l,function(a){return"￷"+a+"￸"}),a.titleWithHighlight=e(m).replace(/\uFFF7/g,"").replace(/\uFFF8/g,"")):a.titleWithHighlight=b.replace(l,function(a){return""+a+""})),d}}return this.enableFilter=!0,this.lastFilterArgs=arguments,this.$div.addClass("fancytree-ext-filter"),s?this.$div.addClass("fancytree-ext-filter-hide"):this.$div.addClass("fancytree-ext-filter-dimm"),this.$div.toggleClass("fancytree-ext-filter-hide-expanders",!!r.hideExpanders),this.visit(function(a){delete a.match,delete a.titleWithHighlight,a.subMatchCount=0}),j=this.getRootNode()._findDirectChild(d),j&&j.remove(),o.autoCollapse=!1,this.visit(function(a){if(!t||null==a.children){var b=f(a),c=!1;if("skip"===b)return a.visit(function(a){a.match=!1},!0),"skip";b||!g&&"branch"!==b||!a.parent.match||(b=!0,c=!0),b&&(n++,a.match=!0,a.visitParents(function(a){a.subMatchCount+=1,!r.autoExpand||c||a.expanded||(a.setExpanded(!0,{noAnimation:!0,noEvents:!0,scrollIntoView:!1}),a._filterAutoExpanded=!0)}))}}),o.autoCollapse=q,0===n&&r.nodata&&s&&(j=r.nodata,a.isFunction(j)&&(j=j()),j===!0?j={}:"string"==typeof j&&(j={title:j}),j=a.extend({statusNodeType:"nodata",key:d,title:this.options.strings.noData},j),this.getRootNode().addNode(j).match=!0),this.render(),n},a.ui.fancytree._FancytreeClass.prototype.filterNodes=function(a,b){return"boolean"==typeof b&&(b={leavesOnly:b},this.warn("Fancytree.filterNodes() leavesOnly option is deprecated since 2.9.0 / 2015-04-19. Use opts.leavesOnly instead.")),this._applyFilterImpl(a,!1,b)},a.ui.fancytree._FancytreeClass.prototype.applyFilter=function(a){return this.warn("Fancytree.applyFilter() is deprecated since 2.1.0 / 2014-05-29. Use .filterNodes() instead."),this.filterNodes.apply(this,arguments)},a.ui.fancytree._FancytreeClass.prototype.filterBranches=function(a,b){return this._applyFilterImpl(a,!0,b)},a.ui.fancytree._FancytreeClass.prototype.clearFilter=function(){var b,c=this.getRootNode()._findDirectChild(d),e=this.options.escapeTitles,f=this.options.enhanceTitle;c&&c.remove(),this.visit(function(c){c.match&&c.span&&(b=a(c.span).find(">span.fancytree-title"),e?b.text(c.title):b.html(c.title),f&&f({type:"enhanceTitle"},{node:c,$title:b})),delete c.match,delete c.subMatchCount,delete c.titleWithHighlight,c.$subMatchBadge&&(c.$subMatchBadge.remove(),delete c.$subMatchBadge),c._filterAutoExpanded&&c.expanded&&c.setExpanded(!1,{noAnimation:!0,noEvents:!0,scrollIntoView:!1}),delete c._filterAutoExpanded}),this.enableFilter=!1,this.lastFilterArgs=null,this.$div.removeClass("fancytree-ext-filter fancytree-ext-filter-dimm fancytree-ext-filter-hide"),this.render()},a.ui.fancytree._FancytreeClass.prototype.isFilterActive=function(){return!!this.enableFilter},a.ui.fancytree._FancytreeNodeClass.prototype.isMatched=function(){return!(this.tree.enableFilter&&!this.match)},a.ui.fancytree.registerExtension({name:"filter",version:"2.26.0",options:{autoApply:!0,autoExpand:!1,counter:!0,fuzzy:!1,hideExpandedCounter:!0,hideExpanders:!1,highlight:!0,leavesOnly:!1,nodata:!0,mode:"dimm"},nodeLoadChildren:function(a,b){return this._superApply(arguments).done(function(){a.tree.enableFilter&&a.tree.lastFilterArgs&&a.options.filter.autoApply&&a.tree._applyFilterImpl.apply(a.tree,a.tree.lastFilterArgs)})},nodeSetExpanded:function(a,b,c){return delete a.node._filterAutoExpanded,!b&&a.options.filter.hideExpandedCounter&&a.node.$subMatchBadge&&a.node.$subMatchBadge.show(),this._superApply(arguments)},nodeRenderStatus:function(b){var c,d=b.node,e=b.tree,f=b.options.filter,g=a(d.span).find("span.fancytree-title"),h=a(d[e.statusClassPropName]),i=b.options.enhanceTitle,j=b.options.escapeTitles;return c=this._super(b),h.length&&e.enableFilter?(h.toggleClass("fancytree-match",!!d.match).toggleClass("fancytree-submatch",!!d.subMatchCount).toggleClass("fancytree-hide",!(d.match||d.subMatchCount)),!f.counter||!d.subMatchCount||d.isExpanded()&&f.hideExpandedCounter?d.$subMatchBadge&&d.$subMatchBadge.hide():(d.$subMatchBadge||(d.$subMatchBadge=a(""),a("span.fancytree-icon, span.fancytree-custom-icon",d.span).append(d.$subMatchBadge)),d.$subMatchBadge.show().text(d.subMatchCount)),!d.span||d.isEditing&&d.isEditing.call(d)||(d.titleWithHighlight?g.html(d.titleWithHighlight):j?g.text(d.title):g.html(d.title),i&&i({type:"enhanceTitle"},{node:d,$title:g})),c):c}}),a.ui.fancytree});
/*! Extension 'jquery.fancytree.glyph.min.js' */
-!function(a,b,c,d){"use strict";function e(a,b){return a.map[b]}a.ui.fancytree.registerExtension({name:"glyph",version:"2.23.0",options:{map:{checkbox:"icon-check-empty",checkboxSelected:"icon-check",checkboxUnknown:"icon-check icon-muted",error:"icon-exclamation-sign",expanderClosed:"icon-caret-right",expanderLazy:"icon-angle-right",expanderOpen:"icon-caret-down",nodata:"icon-meh",noExpander:"",dragHelper:"icon-caret-right",dropMarker:"icon-caret-right",doc:"icon-file-alt",docOpen:"icon-file-alt",loading:"icon-refresh icon-spin",folder:"icon-folder-close-alt",folderOpen:"icon-folder-open-alt"}},treeInit:function(a){var b=a.tree;this._superApply(arguments),b.$container.addClass("fancytree-ext-glyph")},nodeRenderStatus:function(b){var c,d,f,g=b.node,h=a(g.span),i=b.options.glyph,j=i.map;return d=this._super(b),g.isRoot()?d:(f=h.children("span.fancytree-expander").get(0),f&&(c=g.expanded&&g.hasChildren()?"expanderOpen":g.isUndefined()?"expanderLazy":g.hasChildren()?"expanderClosed":"noExpander",f.className="fancytree-expander "+j[c]),f=g.tr?a("td",g.tr).find("span.fancytree-checkbox").get(0):h.children("span.fancytree-checkbox").get(0),f&&(c=g.selected?"checkboxSelected":g.partsel?"checkboxUnknown":"checkbox",f.className="fancytree-checkbox "+j[c]),f=h.children("span.fancytree-icon").get(0),f&&(c=g.statusNodeType?e(i,g.statusNodeType):g.folder?g.expanded&&g.hasChildren()?e(i,"folderOpen"):e(i,"folder"):g.expanded?e(i,"docOpen"):e(i,"doc"),f.className="fancytree-icon "+c),d)},nodeSetStatus:function(b,c,d,f){var g,h,i=b.options.glyph,j=b.node;return g=this._superApply(arguments),"error"!==c&&"loading"!==c&&"nodata"!==c||(j.parent?(h=a("span.fancytree-expander",j.span).get(0),h&&(h.className="fancytree-expander "+e(i,c))):(h=a(".fancytree-statusnode-"+c,j[this.nodeContainerAttrName]).find("span.fancytree-icon").get(0),h&&(h.className="fancytree-icon "+e(i,c)))),g}})}(jQuery,window,document);
+!function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],a):"object"==typeof module&&module.exports?(require("jquery.fancytree"),module.exports=a(require("jquery"))):a(jQuery)}(function(a){"use strict";function b(a,b){return a.map[b]}var c=a.ui.fancytree,d={awesome3:{checkbox:"icon-check-empty",checkboxSelected:"icon-check",checkboxUnknown:"icon-check icon-muted",radio:"icon-circle-blank",radioSelected:"icon-circle",radioUnknown:"icon-circle icon-muted",dragHelper:"icon-caret-right",dropMarker:"icon-caret-right",error:"icon-exclamation-sign",expanderClosed:"icon-caret-right",expanderLazy:"icon-angle-right",expanderOpen:"icon-caret-down",loading:"icon-refresh icon-spin",nodata:"icon-meh",noExpander:"",doc:"icon-file-alt",docOpen:"icon-file-alt",folder:"icon-folder-close-alt",folderOpen:"icon-folder-open-alt"},awesome4:{checkbox:"fa fa-square-o",checkboxSelected:"fa fa-check-square-o",checkboxUnknown:"fa fa-square",radio:"fa fa-circle-o",radioSelected:"fa fa-circle",radioUnknown:"fa fa-dot-circle-o",dragHelper:"fa fa-arrow-right",dropMarker:"fa fa-long-arrow-right",error:"fa fa-warning",expanderClosed:"fa fa-caret-right",expanderLazy:"fa fa-angle-right",expanderOpen:"fa fa-caret-down",loading:"fa fa-spinner fa-pulse",nodata:"fa fa-meh-o",noExpander:"",doc:"fa fa-file-o",docOpen:"fa fa-file-o",folder:"fa fa-folder-o",folderOpen:"fa fa-folder-open-o"},bootstrap3:{checkbox:"glyphicon glyphicon-unchecked",checkboxSelected:"glyphicon glyphicon-check",checkboxUnknown:"glyphicon glyphicon-expand",radio:"glyphicon glyphicon-remove-circle",radioSelected:"glyphicon glyphicon-ok-circle",radioUnknown:"glyphicon glyphicon-ban-circle",dragHelper:"glyphicon glyphicon-play",dropMarker:"glyphicon glyphicon-arrow-right",error:"glyphicon glyphicon-warning-sign",expanderClosed:"glyphicon glyphicon-menu-right",expanderLazy:"glyphicon glyphicon-menu-right",expanderOpen:"glyphicon glyphicon-menu-down",loading:"glyphicon glyphicon-refresh glyphicon-spin",nodata:"glyphicon glyphicon-info-sign",noExpander:"",doc:"glyphicon glyphicon-file",docOpen:"glyphicon glyphicon-file",folder:"glyphicon glyphicon-folder-close",folderOpen:"glyphicon glyphicon-folder-open"}};return a.ui.fancytree.registerExtension({name:"glyph",version:"2.26.0",options:{preset:null,map:{}},treeInit:function(b){var e=b.tree,f=b.options.glyph;f.preset?(c.assert(!!d[f.preset],"Invalid value for `options.glyph.preset`: "+f.preset),f.map=a.extend({},d[f.preset],f.map)):e.warn("ext-glyph: missing `preset` option."),this._superApply(arguments),e.$container.addClass("fancytree-ext-glyph")},nodeRenderStatus:function(d){var e,f,g,h,i,j=d.node,k=a(j.span),l=d.options.glyph,m=l.map;return h=this._super(d),j.isRoot()?h:(i=k.children("span.fancytree-expander").get(0),i&&(g=j.expanded&&j.hasChildren()?"expanderOpen":j.isUndefined()?"expanderLazy":j.hasChildren()?"expanderClosed":"noExpander",i.className="fancytree-expander "+m[g]),i=j.tr?a("td",j.tr).find("span.fancytree-checkbox").get(0):k.children("span.fancytree-checkbox").get(0),i&&(e=c.evalOption("checkbox",j,j,d.options,!1),e&&!j.isStatusNode()&&(f="fancytree-checkbox ","radio"===e||j.parent&&j.parent.radiogroup?(f+="fancytree-radio ",g=j.selected?"radioSelected":j.partsel?"radioUnknown":"radio"):g=j.selected?"checkboxSelected":j.partsel?"checkboxUnknown":"checkbox",i.className=f+m[g])),i=k.children("span.fancytree-icon").get(0),i&&(g=j.statusNodeType?b(l,j.statusNodeType):j.folder?j.expanded&&j.hasChildren()?b(l,"folderOpen"):b(l,"folder"):j.expanded?b(l,"docOpen"):b(l,"doc"),i.className="fancytree-icon "+g),h)},nodeSetStatus:function(c,d,e,f){var g,h,i=c.options.glyph,j=c.node;return g=this._superApply(arguments),"error"!==d&&"loading"!==d&&"nodata"!==d||(j.parent?(h=a("span.fancytree-expander",j.span).get(0),h&&(h.className="fancytree-expander "+b(i,d))):(h=a(".fancytree-statusnode-"+d,j[this.nodeContainerAttrName]).find("span.fancytree-icon").get(0),h&&(h.className="fancytree-icon "+b(i,d)))),g}}),a.ui.fancytree});
/*! Extension 'jquery.fancytree.gridnav.min.js' */
-!function(a,b,c,d){"use strict";function e(b,c){var d,e=c.get(0),f=0;return b.children().each(function(){return this!==e&&(d=a(this).prop("colspan"),void(f+=d?d:1))}),f}function f(b,c){var d,e=null,f=0;return b.children().each(function(){return f>=c?(e=a(this),!1):(d=a(this).prop("colspan"),void(f+=d?d:1))}),e}function g(a,b){var c,d,g=a.closest("td"),i=null;switch(b){case h.LEFT:i=g.prev();break;case h.RIGHT:i=g.next();break;case h.UP:case h.DOWN:for(c=g.parent(),d=e(c,g);;){if(c=b===h.UP?c.prev():c.next(),!c.length)break;if(!c.is(":hidden")&&(i=f(c,d),i&&i.find(":input,a").length))break}}return i}var h=a.ui.keyCode,i={text:[h.UP,h.DOWN],checkbox:[h.UP,h.DOWN,h.LEFT,h.RIGHT],link:[h.UP,h.DOWN,h.LEFT,h.RIGHT],radiobutton:[h.UP,h.DOWN,h.LEFT,h.RIGHT],"select-one":[h.LEFT,h.RIGHT],"select-multiple":[h.LEFT,h.RIGHT]};a.ui.fancytree.registerExtension({name:"gridnav",version:"2.23.0",options:{autofocusInput:!1,handleCursorKeys:!0},treeInit:function(b){this._requireExtension("table",!0,!0),this._superApply(arguments),this.$container.addClass("fancytree-ext-gridnav"),this.$container.on("focusin",function(c){var d,e=a.ui.fancytree.getNode(c.target);e&&!e.isActive()&&(d=b.tree._makeHookContext(e,c),b.tree._callHook("nodeSetActive",d,!0))})},nodeSetActive:function(b,c,d){var e,f=b.options.gridnav,g=b.node,h=b.originalEvent||{},i=a(h.target).is(":input");c=c!==!1,this._superApply(arguments),c&&(b.options.titlesTabbable?(i||(a(g.span).find("span.fancytree-title").focus(),g.setFocus()),b.tree.$container.attr("tabindex","-1")):f.autofocusInput&&!i&&(e=a(g.tr||g.span),e.find(":input:enabled:first").focus()))},nodeKeydown:function(b){var c,d,e,f=b.options.gridnav,h=b.originalEvent,j=a(h.target);return j.is(":input:enabled")?c=j.prop("type"):j.is("a")&&(c="link"),c&&f.handleCursorKeys?(d=i[c],!(d&&a.inArray(h.which,d)>=0&&(e=g(j,h.which),e&&e.length))||(e.find(":input:enabled,a").focus(),!1)):this._superApply(arguments)}})}(jQuery,window,document);
+!function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree","./jquery.fancytree.table"],a):"object"==typeof module&&module.exports?(require("jquery.fancytree.table"),module.exports=a(require("jquery"))):a(jQuery)}(function(a){"use strict";function b(b,c){var d,e=c.get(0),f=0;return b.children().each(function(){return this!==e&&(d=a(this).prop("colspan"),void(f+=d?d:1))}),f}function c(b,c){var d,e=null,f=0;return b.children().each(function(){return f>=c?(e=a(this),!1):(d=a(this).prop("colspan"),void(f+=d?d:1))}),e}function d(a,d){var f,g,h=a.closest("td"),i=null;switch(d){case e.LEFT:i=h.prev();break;case e.RIGHT:i=h.next();break;case e.UP:case e.DOWN:for(f=h.parent(),g=b(f,h);;){if(f=d===e.UP?f.prev():f.next(),!f.length)break;if(!f.is(":hidden")&&(i=c(f,g),i&&i.find(":input,a").length))break}}return i}var e=a.ui.keyCode,f={text:[e.UP,e.DOWN],checkbox:[e.UP,e.DOWN,e.LEFT,e.RIGHT],link:[e.UP,e.DOWN,e.LEFT,e.RIGHT],radiobutton:[e.UP,e.DOWN,e.LEFT,e.RIGHT],"select-one":[e.LEFT,e.RIGHT],"select-multiple":[e.LEFT,e.RIGHT]};return a.ui.fancytree.registerExtension({name:"gridnav",version:"2.26.0",options:{autofocusInput:!1,handleCursorKeys:!0},treeInit:function(b){this._requireExtension("table",!0,!0),this._superApply(arguments),this.$container.addClass("fancytree-ext-gridnav"),this.$container.on("focusin",function(c){var d,e=a.ui.fancytree.getNode(c.target);e&&!e.isActive()&&(d=b.tree._makeHookContext(e,c),b.tree._callHook("nodeSetActive",d,!0))})},nodeSetActive:function(b,c,d){var e,f=b.options.gridnav,g=b.node,h=b.originalEvent||{},i=a(h.target).is(":input");c=c!==!1,this._superApply(arguments),c&&(b.options.titlesTabbable?(i||(a(g.span).find("span.fancytree-title").focus(),g.setFocus()),b.tree.$container.attr("tabindex","-1")):f.autofocusInput&&!i&&(e=a(g.tr||g.span),e.find(":input:enabled:first").focus()))},nodeKeydown:function(b){var c,e,g,h=b.options.gridnav,i=b.originalEvent,j=a(i.target);return j.is(":input:enabled")?c=j.prop("type"):j.is("a")&&(c="link"),c&&h.handleCursorKeys?(e=f[c],!(e&&a.inArray(i.which,e)>=0&&(g=d(j,i.which),g&&g.length))||(g.find(":input:enabled,a").focus(),!1)):this._superApply(arguments)}}),a.ui.fancytree});
/*! Extension 'jquery.fancytree.persist.min.js' */
-!function(a,b,c,d){"use strict";function e(b,c,d,f,g){var h,i,j,l,m=!1,n=b.options.persist.expandOpts,o=[],p=[];for(d=d||[],g=g||a.Deferred(),h=0,j=d.length;h0)e(b,c,p,f,g);else{if(p.length)for(b.warn("_loadLazyNodes: could not load those keys: ",p),h=0,j=p.length;h=0&&b._data(c+j,null),a.indexOf(k)>=0&&b._data(c+k,null),a.indexOf(l)>=0&&b._data(c+l,null),a.indexOf(m)>=0&&b._data(c+m,null)},a.ui.fancytree._FancytreeClass.prototype.getPersistData=function(){var a=this.ext.persist,b=a.cookiePrefix,c=a.cookieDelimiter,d={};return d[j]=a._data(b+j),d[k]=(a._data(b+k)||"").split(c),d[m]=(a._data(b+m)||"").split(c),d[l]=a._data(b+l),d},a.ui.fancytree.registerExtension({name:"persist",version:"2.23.0",options:{cookieDelimiter:"~",cookiePrefix:d,cookie:{raw:!1,expires:"",path:"",domain:"",secure:!1},expandLazy:!1,expandOpts:d,fireActivate:!0,overrideSource:!0,store:"auto",types:"active expanded focus selected"},_data:function(a,b){var c=this._local.localStorage;return b===d?c?c.getItem(a):f(a):void(null===b?c?c.removeItem(a):g(a):c?c.setItem(a,b):h(a,b,this.options.persist.cookie))},_appendKey:function(b,c,d){c=""+c;var e=this._local,f=this.options.persist,g=f.cookieDelimiter,h=e.cookiePrefix+b,i=e._data(h),j=i?i.split(g):[],k=a.inArray(c,j);k>=0&&j.splice(k,1),d&&j.push(c),e._data(h,j.join(g))},treeInit:function(c){var g=c.tree,h=c.options,n=this._local,o=this.options.persist;return i("auto"!==o.store&&"cookie"!==o.store||f,"Missing required plugin for 'persist' extension: js.cookie.js or jquery.cookie.js"),n.cookiePrefix=o.cookiePrefix||"fancytree-"+g._id+"-",n.storeActive=o.types.indexOf(j)>=0,n.storeExpanded=o.types.indexOf(k)>=0,n.storeSelected=o.types.indexOf(m)>=0,n.storeFocus=o.types.indexOf(l)>=0,"cookie"!==o.store&&b.localStorage?n.localStorage="local"===o.store?b.localStorage:b.sessionStorage:n.localStorage=null,g.$div.bind("fancytreeinit",function(b){if(g._triggerTreeEvent("beforeRestore",null,{})!==!1){var c,f,i,p,q,r=n._data(n.cookiePrefix+l),s=o.fireActivate===!1;c=n._data(n.cookiePrefix+k),p=c&&c.split(o.cookieDelimiter),f=n.storeExpanded?e(g,n,p,!!o.expandLazy&&"expand",null):(new a.Deferred).resolve(),f.done(function(){if(n.storeSelected){if(c=n._data(n.cookiePrefix+m))for(p=c.split(o.cookieDelimiter),i=0;i0)b(c,d,p,f,g);else{if(p.length)for(c.warn("_loadLazyNodes: could not load those keys: ",p),i=0,k=p.length;i=0&&b._data(c+g,null),a.indexOf(h)>=0&&b._data(c+h,null),a.indexOf(i)>=0&&b._data(c+i,null),a.indexOf(j)>=0&&b._data(c+j,null)},a.ui.fancytree._FancytreeClass.prototype.getPersistData=function(){var a=this.ext.persist,b=a.cookiePrefix,c=a.cookieDelimiter,d={};return d[g]=a._data(b+g),d[h]=(a._data(b+h)||"").split(c),d[j]=(a._data(b+j)||"").split(c),d[i]=a._data(b+i),d},a.ui.fancytree.registerExtension({name:"persist",version:"2.26.0",options:{cookieDelimiter:"~",cookiePrefix:void 0,cookie:{raw:!1,expires:"",path:"",domain:"",secure:!1},expandLazy:!1,expandOpts:void 0,fireActivate:!0,overrideSource:!0,store:"auto",types:"active expanded focus selected"},_data:function(a,b){var f=this._local.localStorage;return void 0===b?f?f.getItem(a):c(a):void(null===b?f?f.removeItem(a):d(a):f?f.setItem(a,b):e(a,b,this.options.persist.cookie))},_appendKey:function(b,c,d){c=""+c;var e=this._local,f=this.options.persist,g=f.cookieDelimiter,h=e.cookiePrefix+b,i=e._data(h),j=i?i.split(g):[],k=a.inArray(c,j);k>=0&&j.splice(k,1),d&&j.push(c),e._data(h,j.join(g))},treeInit:function(d){var e=d.tree,k=d.options,l=this._local,m=this.options.persist;return f("auto"!==m.store&&"cookie"!==m.store||c,"Missing required plugin for 'persist' extension: js.cookie.js or jquery.cookie.js"),l.cookiePrefix=m.cookiePrefix||"fancytree-"+e._id+"-",l.storeActive=m.types.indexOf(g)>=0,l.storeExpanded=m.types.indexOf(h)>=0,l.storeSelected=m.types.indexOf(j)>=0,l.storeFocus=m.types.indexOf(i)>=0,"cookie"!==m.store&&window.localStorage?l.localStorage="local"===m.store?window.localStorage:window.sessionStorage:l.localStorage=null,e.$div.on("fancytreeinit",function(c){if(e._triggerTreeEvent("beforeRestore",null,{})!==!1){var d,f,n,o,p,q=l._data(l.cookiePrefix+i),r=m.fireActivate===!1;d=l._data(l.cookiePrefix+h),o=d&&d.split(m.cookieDelimiter),f=l.storeExpanded?b(e,l,o,!!m.expandLazy&&"expand",null):(new a.Deferred).resolve(),f.done(function(){if(l.storeSelected){if(d=l._data(l.cookiePrefix+j))for(o=d.split(m.cookieDelimiter),n=0;n1&&h[0]!==b)for(c=a.inArray(b,h),f=h[c-1],e(f.tr);f.children&&f.children.length&&(d=f.children[f.children.length-1],d.tr);)f=d;else f=g;return f}a.ui.fancytree.registerExtension({name:"table",version:"2.23.0",options:{checkboxColumnIdx:null,indentation:16,nodeColumnIdx:0},treeInit:function(b){var d,f,g,h,i,j=b.tree,k=b.options,l=k.table,m=j.widget.element;if(null!=l.customStatus&&(null!=k.renderStatusColumns?a.error("The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' only instead."):(j.warn("The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' instead."),k.renderStatusColumns=l.customStatus)),k.renderStatusColumns&&k.renderStatusColumns===!0&&(k.renderStatusColumns=k.renderColumns),m.addClass("fancytree-container fancytree-ext-table"),j.tbody=m.find(">tbody")[0],i=a(j.tbody),f=a("thead >tr:last >th",m).length,h=i.children("tr:first"),h.length)g=h.children("td").length,f&&g!==f&&(j.warn("Column count mismatch between thead ("+f+") and tbody ("+g+"): using tbody."),f=g),h=h.clone();else for(e(f>=1,"Need either or with
elements to determine column count."),h=a("
"),d=0;d");h.find(">td").eq(l.nodeColumnIdx).html(""),k.aria&&(h.attr("role","row"),h.find("td").attr("role","gridcell")),j.rowFragment=c.createDocumentFragment(),j.rowFragment.appendChild(h.get(0)),i.empty(),j.statusClassPropName="tr",j.ariaPropName="tr",this.nodeContainerAttrName="tr",j.$container=m,this._superApply(arguments),a(j.rootNode.ul).remove(),j.rootNode.ul=null,this.$container.attr("tabindex",k.tabindex),k.aria&&j.$container.attr("role","treegrid").attr("aria-readonly",!0)},nodeRemoveChildMarkup:function(b){var c=b.node;c.visit(function(b){b.tr&&(a(b.tr).remove(),b.tr=null)})},nodeRemoveMarkup:function(b){var c=b.node;c.tr&&(a(c.tr).remove(),c.tr=null),this.nodeRemoveChildMarkup(b)},nodeRender:function(b,c,d,j,k){var l,m,n,o,p,q,r,s,t=b.tree,u=b.node,v=b.options,w=!u.parent;if(t._enableUpdate!==!1){if(k||(b.hasCollapsedParents=u.parent&&!u.parent.expanded),!w)if(u.tr&&c&&this.nodeRemoveMarkup(b),u.tr)c?this.nodeRenderTitle(b):this.nodeRenderStatus(b);else{if(b.hasCollapsedParents&&!d)return;p=t.rowFragment.firstChild.cloneNode(!0),q=i(u),e(q),j===!0&&k?p.style.display="none":d&&b.hasCollapsedParents&&(p.style.display="none"),q.tr?g(q.tr,p):(e(!q.parent,"prev. row must have a tr, or be system root"),f(t.tbody,p)),u.tr=p,u.key&&v.generateIds&&(u.tr.id=v.idPrefix+u.key),u.tr.ftnode=u,u.span=a("span.fancytree-node",u.tr).get(0),this.nodeRenderTitle(b),v.createNode&&v.createNode.call(t,{type:"createNode"},b)}if(v.renderNode&&v.renderNode.call(t,{type:"renderNode"},b),l=u.children,l&&(w||d||u.expanded))for(n=0,o=l.length;n1&&h[0]!==c)for(d=a.inArray(c,h),f=h[d-1],b(f.tr);f.children&&f.children.length&&(e=f.children[f.children.length-1],e.tr);)f=e;else f=g;return f}return a.ui.fancytree.registerExtension({name:"table",version:"2.26.0",options:{checkboxColumnIdx:null,indentation:16,nodeColumnIdx:0},treeInit:function(c){var d,e,f,g,h,i=c.tree,j=c.options,k=j.table,l=i.widget.element;if(null!=k.customStatus&&(null!=j.renderStatusColumns?a.error("The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' only instead."):(i.warn("The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' instead."),j.renderStatusColumns=k.customStatus)),j.renderStatusColumns&&j.renderStatusColumns===!0&&(j.renderStatusColumns=j.renderColumns),l.addClass("fancytree-container fancytree-ext-table"),i.tbody=l.find(">tbody")[0],h=a(i.tbody),e=a("thead >tr:last >th",l).length,g=h.children("tr:first"),g.length)f=g.children("td").length,e&&f!==e&&(i.warn("Column count mismatch between thead ("+e+") and tbody ("+f+"): using tbody."),e=f),g=g.clone();else for(b(e>=1,"Need either or with
elements to determine column count."),g=a("
"),d=0;d");g.find(">td").eq(k.nodeColumnIdx).html(""),j.aria&&(g.attr("role","row"),g.find("td").attr("role","gridcell")),i.rowFragment=document.createDocumentFragment(),i.rowFragment.appendChild(g.get(0)),h.empty(),i.statusClassPropName="tr",i.ariaPropName="tr",this.nodeContainerAttrName="tr",i.$container=l,this._superApply(arguments),a(i.rootNode.ul).remove(),i.rootNode.ul=null,this.$container.attr("tabindex",j.tabindex),j.aria&&i.$container.attr("role","treegrid").attr("aria-readonly",!0)},nodeRemoveChildMarkup:function(b){var c=b.node;c.visit(function(b){b.tr&&(a(b.tr).remove(),b.tr=null)})},nodeRemoveMarkup:function(b){var c=b.node;c.tr&&(a(c.tr).remove(),c.tr=null),this.nodeRemoveChildMarkup(b)},nodeRender:function(g,h,i,j,k){var l,m,n,o,p,q,r,s,t=g.tree,u=g.node,v=g.options,w=!u.parent;if(t._enableUpdate!==!1){if(k||(g.hasCollapsedParents=u.parent&&!u.parent.expanded),!w)if(u.tr&&h&&this.nodeRemoveMarkup(g),u.tr)h?this.nodeRenderTitle(g):this.nodeRenderStatus(g);else{if(g.hasCollapsedParents&&!i)return;p=t.rowFragment.firstChild.cloneNode(!0),q=f(u),b(q),j===!0&&k?p.style.display="none":i&&g.hasCollapsedParents&&(p.style.display="none"),q.tr?d(q.tr,p):(b(!q.parent,"prev. row must have a tr, or be system root"),c(t.tbody,p)),u.tr=p,u.key&&v.generateIds&&(u.tr.id=v.idPrefix+u.key),u.tr.ftnode=u,u.span=a("span.fancytree-node",u.tr).get(0),this.nodeRenderTitle(g),v.createNode&&v.createNode.call(t,{type:"createNode"},g)}if(v.renderNode&&v.renderNode.call(t,{type:"renderNode"},g),l=u.children,l&&(w||i||u.expanded))for(n=0,o=l.length;nthead tr").addClass("ui-widget-header"),c.find(">tbody").addClass("ui-widget-conent")):c.addClass("ui-widget ui-widget-content ui-corner-all"),c.delegate(".fancytree-node","mouseenter mouseleave",function(b){var c=a.ui.fancytree.getNode(b.target),e="mouseenter"===b.type;a(c.tr?c.tr:c.span).toggleClass(d.hoverClass+" "+d.addClass,e)})},treeDestroy:function(a){this._superApply(arguments),a.widget.element.removeClass("ui-widget ui-widget-content ui-corner-all")},nodeRenderStatus:function(b){var c={},d=b.node,e=a(d.tr?d.tr:d.span),f=b.options.themeroller;this._super(b),c[f.activeClass]=!1,c[f.focusClass]=!1,c[f.selectedClass]=!1,d.isActive()&&(c[f.activeClass]=!0),d.hasFocus()&&(c[f.focusClass]=!0),d.isSelected()&&!d.isActive()&&(c[f.selectedClass]=!0),e.toggleClass(f.activeClass,c[f.activeClass]),e.toggleClass(f.focusClass,c[f.focusClass]),e.toggleClass(f.selectedClass,c[f.selectedClass]),e.addClass(f.addClass)}})}(jQuery,window,document);
+!function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],a):"object"==typeof module&&module.exports?(require("jquery.fancytree"),module.exports=a(require("jquery"))):a(jQuery)}(function(a){"use strict";return a.ui.fancytree.registerExtension({name:"themeroller",version:"2.26.0",options:{activeClass:"ui-state-active",addClass:"ui-corner-all",focusClass:"ui-state-focus",hoverClass:"ui-state-hover",selectedClass:"ui-state-highlight"},treeInit:function(b){var c=b.widget.element,d=b.options.themeroller;this._superApply(arguments),"TABLE"===c[0].nodeName?(c.addClass("ui-widget ui-corner-all"),c.find(">thead tr").addClass("ui-widget-header"),c.find(">tbody").addClass("ui-widget-conent")):c.addClass("ui-widget ui-widget-content ui-corner-all"),c.delegate(".fancytree-node","mouseenter mouseleave",function(b){var c=a.ui.fancytree.getNode(b.target),e="mouseenter"===b.type;a(c.tr?c.tr:c.span).toggleClass(d.hoverClass+" "+d.addClass,e)})},treeDestroy:function(a){this._superApply(arguments),a.widget.element.removeClass("ui-widget ui-widget-content ui-corner-all")},nodeRenderStatus:function(b){var c={},d=b.node,e=a(d.tr?d.tr:d.span),f=b.options.themeroller;this._super(b),c[f.activeClass]=!1,c[f.focusClass]=!1,c[f.selectedClass]=!1,d.isActive()&&(c[f.activeClass]=!0),d.hasFocus()&&(c[f.focusClass]=!0),d.isSelected()&&!d.isActive()&&(c[f.selectedClass]=!0),e.toggleClass(f.activeClass,c[f.activeClass]),e.toggleClass(f.focusClass,c[f.focusClass]),e.toggleClass(f.selectedClass,c[f.selectedClass]),e.addClass(f.addClass)}}),a.ui.fancytree});
/*! Extension 'jquery.fancytree.wide.min.js' */
-!function(a,b,c,d){"use strict";function e(b,c){b="fancytree-style-"+b;var d=a("#"+b);if(!c)return d.remove(),null;d.length||(d=a("").attr("id",b).addClass("fancytree-style").prop("type","text/css").appendTo("head"));try{d.html(c)}catch(e){d[0].styleSheet.cssText=c}return d}function f(a,b,c,d,e,f){var g,h="#"+a+" span.fancytree-level-",i=[];for(g=0;g
").appendTo(b.tree.$container),n=m.find(".fancytree-icon"),o=m.find("ul"),p=l.iconSpacing||n.css("margin-left"),q=l.iconWidth||n.css("width"),r=l.labelSpacing||"3px",s=l.levelOfs||o.css("padding-left");m.remove(),h=p.match(g)[2],p=parseFloat(p,10),i=r.match(g)[2],r=parseFloat(r,10),j=q.match(g)[2],q=parseFloat(q,10),k=s.match(g)[2],h===j&&k===j&&i===j||a.error("iconWidth, iconSpacing, and levelOfs must have the same css measure unit"),this._local.measureUnit=j,this._local.levelOfs=parseFloat(s),this._local.lineOfs=(1+(b.options.checkbox?1:0)+(b.options.icon===!1?0:1))*(q+p)+p,this._local.labelOfs=r,this._local.maxDepth=10,c=this.$container.uniqueId().attr("id"),d=f(c,this._local.maxDepth,this._local.levelOfs,this._local.lineOfs,this._local.labelOfs,this._local.measureUnit),e(c,d)},treeDestroy:function(a){return e(this.$container.attr("id"),null),this._superApply(arguments)},nodeRenderStatus:function(b){var c,d,g,h=b.node,i=h.getLevel();return g=this._super(b),i>this._local.maxDepth&&(c=this.$container.attr("id"),this._local.maxDepth*=2,h.debug("Define global ext-wide css up to level "+this._local.maxDepth),d=f(c,this._local.maxDepth,this._local.levelOfs,this._local.lineOfs,this._local.labelSpacing,this._local.measureUnit),e(c,d)),a(h.span).addClass("fancytree-level-"+i),g}})}(jQuery,window,document);
-}));
+!function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],a):"object"==typeof module&&module.exports?(require("jquery.fancytree"),module.exports=a(require("jquery"))):a(jQuery)}(function(a){"use strict";function b(b,c){b="fancytree-style-"+b;var d=a("#"+b);if(!c)return d.remove(),null;d.length||(d=a("").attr("id",b).addClass("fancytree-style").prop("type","text/css").appendTo("head"));try{d.html(c)}catch(e){d[0].styleSheet.cssText=c}return d}function c(a,b,c,d,e,f){var g,h="#"+a+" span.fancytree-level-",i=[];for(g=0;g
").appendTo(e.tree.$container),n=m.find(".fancytree-icon"),o=m.find("ul"),p=l.iconSpacing||n.css("margin-left"),q=l.iconWidth||n.css("width"),r=l.labelSpacing||"3px",s=l.levelOfs||o.css("padding-left");m.remove(),h=p.match(d)[2],p=parseFloat(p,10),i=r.match(d)[2],r=parseFloat(r,10),j=q.match(d)[2],q=parseFloat(q,10),k=s.match(d)[2],h===j&&k===j&&i===j||a.error("iconWidth, iconSpacing, and levelOfs must have the same css measure unit"),this._local.measureUnit=j,this._local.levelOfs=parseFloat(s),this._local.lineOfs=(1+(e.options.checkbox?1:0)+(e.options.icon===!1?0:1))*(q+p)+p,this._local.labelOfs=r,this._local.maxDepth=10,f=this.$container.uniqueId().attr("id"),g=c(f,this._local.maxDepth,this._local.levelOfs,this._local.lineOfs,this._local.labelOfs,this._local.measureUnit),b(f,g)},treeDestroy:function(a){return b(this.$container.attr("id"),null),this._superApply(arguments)},nodeRenderStatus:function(d){var e,f,g,h=d.node,i=h.getLevel();return g=this._super(d),i>this._local.maxDepth&&(e=this.$container.attr("id"),this._local.maxDepth*=2,h.debug("Define global ext-wide css up to level "+this._local.maxDepth),f=c(e,this._local.maxDepth,this._local.levelOfs,this._local.lineOfs,this._local.labelSpacing,this._local.measureUnit),b(e,f)),a(h.span).addClass("fancytree-level-"+i),g}}),a.ui.fancytree});
+// Value returned by `require('jquery.fancytree')`
+return $.ui.fancytree;
+})); // End of closure
diff --git a/public/libraries/fancytree/jquery.fancytree.js b/public/libraries/fancytree/jquery.fancytree.js
deleted file mode 100644
index b2c14c930..000000000
--- a/public/libraries/fancytree/jquery.fancytree.js
+++ /dev/null
@@ -1,5246 +0,0 @@
-/*!
- * jquery.fancytree.js
- * Tree view control with support for lazy loading and much more.
- * https://github.com/mar10/fancytree/
- *
- * Copyright (c) 2008-2017, Martin Wendt (http://wwWendt.de)
- * Released under the MIT license
- * https://github.com/mar10/fancytree/wiki/LicenseInfo
- *
- * @version 2.23.0
- * @date 2017-05-27T20:09:38Z
- */
-
-/** Core Fancytree module.
- */
-
-
-// Start of local namespace
-;(function($, window, document, undefined) {
-"use strict";
-
-// prevent duplicate loading
-if ( $.ui && $.ui.fancytree ) {
- $.ui.fancytree.warn("Fancytree: ignored duplicate include");
- return;
-}
-
-
-/* *****************************************************************************
- * Private functions and variables
- */
-
-var i, attr,
- FT = null, // initialized below
- TEST_IMG = new RegExp(/\.|\//), // strings are considered image urls if they contain '.' or '/'
- REX_HTML = /[&<>"'\/]/g,
- REX_TOOLTIP = /[<>"'\/]/g,
- RECURSIVE_REQUEST_ERROR = "$recursive_request",
- ENTITY_MAP = {"&": "&", "<": "<", ">": ">", "\"": """, "'": "'", "/": "/"},
- IGNORE_KEYCODES = { 16: true, 17: true, 18: true },
- SPECIAL_KEYCODES = {
- 8: "backspace", 9: "tab", 10: "return", 13: "return",
- // 16: null, 17: null, 18: null, // ignore shift, ctrl, alt
- 19: "pause", 20: "capslock", 27: "esc", 32: "space", 33: "pageup",
- 34: "pagedown", 35: "end", 36: "home", 37: "left", 38: "up",
- 39: "right", 40: "down", 45: "insert", 46: "del", 59: ";", 61: "=",
- 96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6",
- 103: "7", 104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".",
- 111: "/", 112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5",
- 117: "f6", 118: "f7", 119: "f8", 120: "f9", 121: "f10", 122: "f11",
- 123: "f12", 144: "numlock", 145: "scroll", 173: "-", 186: ";", 187: "=",
- 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
- 221: "]", 222: "'"},
- MOUSE_BUTTONS = { 0: "", 1: "left", 2: "middle", 3: "right" },
- // Boolean attributes that can be set with equivalent class names in the LI tags
- // Note: v2.23: checkbox and hideCheckbox are *not* in this list
- CLASS_ATTRS = "active expanded focus folder lazy radiogroup selected unselectable unselectableIgnore".split(" "),
- CLASS_ATTR_MAP = {},
- // Top-level Fancytree node attributes, that can be set by dict
- NODE_ATTRS = "checkbox expanded extraClasses folder icon key lazy radiogroup refKey selected statusNodeType title tooltip unselectable unselectableIgnore unselectableStatus".split(" "),
- NODE_ATTR_MAP = {},
- // Mapping of lowercase -> real name (because HTML5 data-... attribute only supports lowercase)
- NODE_ATTR_LOWERCASE_MAP = {},
- // Attribute names that should NOT be added to node.data
- NONE_NODE_DATA_MAP = {"active": true, "children": true, "data": true, "focus": true};
-
-for(i=0; i t );
- }
- }
- return true;
-}
-
-/** Return a wrapper that calls sub.methodName() and exposes
- * this : tree
- * this._local : tree.ext.EXTNAME
- * this._super : base.methodName.call()
- * this._superApply : base.methodName.apply()
- */
-function _makeVirtualFunction(methodName, tree, base, extension, extName){
- // $.ui.fancytree.debug("_makeVirtualFunction", methodName, tree, base, extension, extName);
- // if(rexTestSuper && !rexTestSuper.test(func)){
- // // extension.methodName() doesn't call _super(), so no wrapper required
- // return func;
- // }
- // Use an immediate function as closure
- var proxy = (function(){
- var prevFunc = tree[methodName], // org. tree method or prev. proxy
- baseFunc = extension[methodName], //
- _local = tree.ext[extName],
- _super = function(){
- return prevFunc.apply(tree, arguments);
- },
- _superApply = function(args){
- return prevFunc.apply(tree, args);
- };
-
- // Return the wrapper function
- return function(){
- var prevLocal = tree._local,
- prevSuper = tree._super,
- prevSuperApply = tree._superApply;
-
- try{
- tree._local = _local;
- tree._super = _super;
- tree._superApply = _superApply;
- return baseFunc.apply(tree, arguments);
- }finally{
- tree._local = prevLocal;
- tree._super = prevSuper;
- tree._superApply = prevSuperApply;
- }
- };
- })(); // end of Immediate Function
- return proxy;
-}
-
-/**
- * Subclass `base` by creating proxy functions
- */
-function _subclassObject(tree, base, extension, extName){
- // $.ui.fancytree.debug("_subclassObject", tree, base, extension, extName);
- for(var attrName in extension){
- if(typeof extension[attrName] === "function"){
- if(typeof tree[attrName] === "function"){
- // override existing method
- tree[attrName] = _makeVirtualFunction(attrName, tree, base, extension, extName);
- }else if(attrName.charAt(0) === "_"){
- // Create private methods in tree.ext.EXTENSION namespace
- tree.ext[extName][attrName] = _makeVirtualFunction(attrName, tree, base, extension, extName);
- }else{
- $.error("Could not override tree." + attrName + ". Use prefix '_' to create tree." + extName + "._" + attrName);
- }
- }else{
- // Create member variables in tree.ext.EXTENSION namespace
- if(attrName !== "options"){
- tree.ext[extName][attrName] = extension[attrName];
- }
- }
- }
-}
-
-
-function _getResolvedPromise(context, argArray){
- if(context === undefined){
- return $.Deferred(function(){this.resolve();}).promise();
- }else{
- return $.Deferred(function(){this.resolveWith(context, argArray);}).promise();
- }
-}
-
-
-function _getRejectedPromise(context, argArray){
- if(context === undefined){
- return $.Deferred(function(){this.reject();}).promise();
- }else{
- return $.Deferred(function(){this.rejectWith(context, argArray);}).promise();
- }
-}
-
-
-function _makeResolveFunc(deferred, context){
- return function(){
- deferred.resolveWith(context);
- };
-}
-
-
-function _getElementDataAsDict($el){
- // Evaluate 'data-NAME' attributes with special treatment for 'data-json'.
- var d = $.extend({}, $el.data()),
- json = d.json;
-
- delete d.fancytree; // added to container by widget factory (old jQuery UI)
- delete d.uiFancytree; // added to container by widget factory
-
- if( json ) {
- delete d.json;
- //
is already returned as object (http://api.jquery.com/data/#data-html5)
- d = $.extend(d, json);
- }
- return d;
-}
-
-
-function _escapeHtml(s){
- return ("" + s).replace(REX_HTML, function(s) {
- return ENTITY_MAP[s];
- });
-}
-
-
-function _escapeTooltip(s){
- return ("" + s).replace(REX_TOOLTIP, function(s) {
- return ENTITY_MAP[s];
- });
-}
-
-
-// TODO: use currying
-function _makeNodeTitleMatcher(s){
- s = s.toLowerCase();
- return function(node){
- return node.title.toLowerCase().indexOf(s) >= 0;
- };
-}
-
-
-function _makeNodeTitleStartMatcher(s){
- var reMatch = new RegExp("^" + s, "i");
- return function(node){
- return reMatch.test(node.title);
- };
-}
-
-
-/* *****************************************************************************
- * FancytreeNode
- */
-
-
-/**
- * Creates a new FancytreeNode
- *
- * @class FancytreeNode
- * @classdesc A FancytreeNode represents the hierarchical data model and operations.
- *
- * @param {FancytreeNode} parent
- * @param {NodeData} obj
- *
- * @property {Fancytree} tree The tree instance
- * @property {FancytreeNode} parent The parent node
- * @property {string} key Node id (must be unique inside the tree)
- * @property {string} title Display name (may contain HTML)
- * @property {object} data Contains all extra data that was passed on node creation
- * @property {FancytreeNode[] | null | undefined} children Array of child nodes.
- * For lazy nodes, null or undefined means 'not yet loaded'. Use an empty array
- * to define a node that has no children.
- * @property {boolean} expanded Use isExpanded(), setExpanded() to access this property.
- * @property {string} extraClasses Additional CSS classes, added to the node's `<span>`.
- * Note: use `node.add/remove/toggleClass()` to modify.
- * @property {boolean} folder Folder nodes have different default icons and click behavior.
- * Note: Also non-folders may have children.
- * @property {string} statusNodeType null for standard nodes. Otherwise type of special system node: 'error', 'loading', 'nodata', or 'paging'.
- * @property {boolean} lazy True if this node is loaded on demand, i.e. on first expansion.
- * @property {boolean} selected Use isSelected(), setSelected() to access this property.
- * @property {string} tooltip Alternative description used as hover popup
- */
-function FancytreeNode(parent, obj){
- var i, l, name, cl;
-
- this.parent = parent;
- this.tree = parent.tree;
- this.ul = null;
- this.li = null; //
tag
- this.statusNodeType = null; // if this is a temp. node to display the status of its parent
- this._isLoading = false; // if this node itself is loading
- this._error = null; // {message: '...'} if a load error occurred
- this.data = {};
-
- // TODO: merge this code with node.toDict()
- // copy attributes from obj object
- for(i=0, l=NODE_ATTRS.length; i= 0, "insertBefore must be an existing child");
- // insert nodeList after children[pos]
- this.children.splice.apply(this.children, [pos, 0].concat(nodeList));
- }
- if ( origFirstChild && !insertBefore ) {
- // #708: Fast path -- don't render every child of root, just the new ones!
- // #723, #729: but only if it's appended to an existing child list
- for(i=0, l=nodeList.length; i= 0; i--) {
- n = this.children[i];
- if( n.statusNodeType === "paging" ) {
- this.removeChild(n);
- }
- }
- this.partload = false;
- return;
- }
- node = $.extend({
- title: this.tree.options.strings.moreData,
- statusNodeType: "paging",
- icon: false
- }, node);
- this.partload = true;
- return this.addNode(node, mode);
- },
- /**
- * Append new node after this.
- *
- * This a convenience function that calls addNode(node, 'after')
- *
- * @param {NodeData} node node definition
- * @returns {FancytreeNode} new node
- */
- appendSibling: function(node){
- return this.addNode(node, "after");
- },
- /**
- * Modify existing child nodes.
- *
- * @param {NodePatch} patch
- * @returns {$.Promise}
- * @see FancytreeNode#addChildren
- */
- applyPatch: function(patch) {
- // patch [key, null] means 'remove'
- if(patch === null){
- this.remove();
- return _getResolvedPromise(this);
- }
- // TODO: make sure that root node is not collapsed or modified
- // copy (most) attributes to node.ATTR or node.data.ATTR
- var name, promise, v,
- IGNORE_MAP = { children: true, expanded: true, parent: true }; // TODO: should be global
-
- for(name in patch){
- v = patch[name];
- if( !IGNORE_MAP[name] && !$.isFunction(v)){
- if(NODE_ATTR_MAP[name]){
- this[name] = v;
- }else{
- this.data[name] = v;
- }
- }
- }
- // Remove and/or create children
- if(patch.hasOwnProperty("children")){
- this.removeChildren();
- if(patch.children){ // only if not null and not empty list
- // TODO: addChildren instead?
- this._setChildren(patch.children);
- }
- // TODO: how can we APPEND or INSERT child nodes?
- }
- if(this.isVisible()){
- this.renderTitle();
- this.renderStatus();
- }
- // Expand collapse (final step, since this may be async)
- if(patch.hasOwnProperty("expanded")){
- promise = this.setExpanded(patch.expanded);
- }else{
- promise = _getResolvedPromise(this);
- }
- return promise;
- },
- /** Collapse all sibling nodes.
- * @returns {$.Promise}
- */
- collapseSiblings: function() {
- return this.tree._callHook("nodeCollapseSiblings", this);
- },
- /** Copy this node as sibling or child of `node`.
- *
- * @param {FancytreeNode} node source node
- * @param {string} [mode=child] 'before' | 'after' | 'child'
- * @param {Function} [map] callback function(NodeData) that could modify the new node
- * @returns {FancytreeNode} new
- */
- copyTo: function(node, mode, map) {
- return node.addNode(this.toDict(true, map), mode);
- },
- /** Count direct and indirect children.
- *
- * @param {boolean} [deep=true] pass 'false' to only count direct children
- * @returns {int} number of child nodes
- */
- countChildren: function(deep) {
- var cl = this.children, i, l, n;
- if( !cl ){
- return 0;
- }
- n = cl.length;
- if(deep !== false){
- for(i=0, l=n; i= 2 (prepending node info)
- *
- * @param {*} msg string or object or array of such
- */
- debug: function(msg){
- if( this.tree.options.debugLevel >= 2 ) {
- Array.prototype.unshift.call(arguments, this.toString());
- consoleApply("log", arguments);
- }
- },
- /** Deprecated.
- * @deprecated since 2014-02-16. Use resetLazy() instead.
- */
- discard: function(){
- this.warn("FancytreeNode.discard() is deprecated since 2014-02-16. Use .resetLazy() instead.");
- return this.resetLazy();
- },
- /** Remove DOM elements for all descendents. May be called on .collapse event
- * to keep the DOM small.
- * @param {boolean} [includeSelf=false]
- */
- discardMarkup: function(includeSelf){
- var fn = includeSelf ? "nodeRemoveMarkup" : "nodeRemoveChildMarkup";
- this.tree._callHook(fn, this);
- },
- /**Find all nodes that match condition (excluding self).
- *
- * @param {string | function(node)} match title string to search for, or a
- * callback function that returns `true` if a node is matched.
- * @returns {FancytreeNode[]} array of nodes (may be empty)
- */
- findAll: function(match) {
- match = $.isFunction(match) ? match : _makeNodeTitleMatcher(match);
- var res = [];
- this.visit(function(n){
- if(match(n)){
- res.push(n);
- }
- });
- return res;
- },
- /**Find first node that matches condition (excluding self).
- *
- * @param {string | function(node)} match title string to search for, or a
- * callback function that returns `true` if a node is matched.
- * @returns {FancytreeNode} matching node or null
- * @see FancytreeNode#findAll
- */
- findFirst: function(match) {
- match = $.isFunction(match) ? match : _makeNodeTitleMatcher(match);
- var res = null;
- this.visit(function(n){
- if(match(n)){
- res = n;
- return false;
- }
- });
- return res;
- },
- /* Apply selection state (internal use only) */
- _changeSelectStatusAttrs: function(state) {
- var changed = false,
- opts = this.tree.options,
- unselectable = FT.evalOption("unselectable", this, this, opts, false),
- unselectableStatus = FT.evalOption("unselectableStatus", this, this, opts, undefined);
-
- if( unselectable && unselectableStatus != null ) {
- state = unselectableStatus;
- }
- switch(state){
- case false:
- changed = ( this.selected || this.partsel );
- this.selected = false;
- this.partsel = false;
- break;
- case true:
- changed = ( !this.selected || !this.partsel );
- this.selected = true;
- this.partsel = true;
- break;
- case undefined:
- changed = ( this.selected || !this.partsel );
- this.selected = false;
- this.partsel = true;
- break;
- default:
- _assert(false, "invalid state: " + state);
- }
- // this.debug("fixSelection3AfterLoad() _changeSelectStatusAttrs()", state, changed);
- if( changed ){
- this.renderStatus();
- }
- return changed;
- },
- /**
- * Fix selection status, after this node was (de)selected in multi-hier mode.
- * This includes (de)selecting all children.
- */
- fixSelection3AfterClick: function(callOpts) {
- var flag = this.isSelected();
-
-// this.debug("fixSelection3AfterClick()");
-
- this.visit(function(node){
- node._changeSelectStatusAttrs(flag);
- });
- this.fixSelection3FromEndNodes(callOpts);
- },
- /**
- * Fix selection status for multi-hier mode.
- * Only end-nodes are considered to update the descendants branch and parents.
- * Should be called after this node has loaded new children or after
- * children have been modified using the API.
- */
- fixSelection3FromEndNodes: function(callOpts) {
- var opts = this.tree.options;
-
-// this.debug("fixSelection3FromEndNodes()");
- _assert(opts.selectMode === 3, "expected selectMode 3");
-
- // Visit all end nodes and adjust their parent's `selected` and `partsel`
- // attributes. Return selection state true, false, or undefined.
- function _walk(node){
- var i, l, child, s, state, allSelected, someSelected, unselIgnore, unselState,
- children = node.children;
-
- if( children && children.length ){
- // check all children recursively
- allSelected = true;
- someSelected = false;
-
- for( i=0, l=children.length; i= 1 (prepending node info)
- *
- * @param {*} msg string or object or array of such
- */
- info: function(msg){
- if( this.tree.options.debugLevel >= 1 ) {
- Array.prototype.unshift.call(arguments, this.toString());
- consoleApply("info", arguments);
- }
- },
- /** Return true if node is active (see also FancytreeNode#isSelected).
- * @returns {boolean}
- */
- isActive: function() {
- return (this.tree.activeNode === this);
- },
- /** Return true if node is a direct child of otherNode.
- * @param {FancytreeNode} otherNode
- * @returns {boolean}
- */
- isChildOf: function(otherNode) {
- return (this.parent && this.parent === otherNode);
- },
- /** Return true, if node is a direct or indirect sub node of otherNode.
- * @param {FancytreeNode} otherNode
- * @returns {boolean}
- */
- isDescendantOf: function(otherNode) {
- if(!otherNode || otherNode.tree !== this.tree){
- return false;
- }
- var p = this.parent;
- while( p ) {
- if( p === otherNode ){
- return true;
- }
- p = p.parent;
- }
- return false;
- },
- /** Return true if node is expanded.
- * @returns {boolean}
- */
- isExpanded: function() {
- return !!this.expanded;
- },
- /** Return true if node is the first node of its parent's children.
- * @returns {boolean}
- */
- isFirstSibling: function() {
- var p = this.parent;
- return !p || p.children[0] === this;
- },
- /** Return true if node is a folder, i.e. has the node.folder attribute set.
- * @returns {boolean}
- */
- isFolder: function() {
- return !!this.folder;
- },
- /** Return true if node is the last node of its parent's children.
- * @returns {boolean}
- */
- isLastSibling: function() {
- var p = this.parent;
- return !p || p.children[p.children.length-1] === this;
- },
- /** Return true if node is lazy (even if data was already loaded)
- * @returns {boolean}
- */
- isLazy: function() {
- return !!this.lazy;
- },
- /** Return true if node is lazy and loaded. For non-lazy nodes always return true.
- * @returns {boolean}
- */
- isLoaded: function() {
- return !this.lazy || this.hasChildren() !== undefined; // Also checks if the only child is a status node
- },
- /** Return true if children are currently beeing loaded, i.e. a Ajax request is pending.
- * @returns {boolean}
- */
- isLoading: function() {
- return !!this._isLoading;
- },
- /*
- * @deprecated since v2.4.0: Use isRootNode() instead
- */
- isRoot: function() {
- return this.isRootNode();
- },
- /** Return true if node is partially selected (tri-state).
- * @returns {boolean}
- * @since 2.23
- */
- isPartsel: function() {
- return !this.selected && !!this.partsel;
- },
- /** (experimental) Return true if this is partially loaded.
- * @returns {boolean}
- * @since 2.15
- */
- isPartload: function() {
- return !!this.partload;
- },
- /** Return true if this is the (invisible) system root node.
- * @returns {boolean}
- * @since 2.4
- */
- isRootNode: function() {
- return (this.tree.rootNode === this);
- },
- /** Return true if node is selected, i.e. has a checkmark set (see also FancytreeNode#isActive).
- * @returns {boolean}
- */
- isSelected: function() {
- return !!this.selected;
- },
- /** Return true if this node is a temporarily generated system node like
- * 'loading', 'paging', or 'error' (node.statusNodeType contains the type).
- * @returns {boolean}
- */
- isStatusNode: function() {
- return !!this.statusNodeType;
- },
- /** Return true if this node is a status node of type 'paging'.
- * @returns {boolean}
- * @since 2.15
- */
- isPagingNode: function() {
- return this.statusNodeType === "paging";
- },
- /** Return true if this a top level node, i.e. a direct child of the (invisible) system root node.
- * @returns {boolean}
- * @since 2.4
- */
- isTopLevel: function() {
- return (this.tree.rootNode === this.parent);
- },
- /** Return true if node is lazy and not yet loaded. For non-lazy nodes always return false.
- * @returns {boolean}
- */
- isUndefined: function() {
- return this.hasChildren() === undefined; // also checks if the only child is a status node
- },
- /** Return true if all parent nodes are expanded. Note: this does not check
- * whether the node is scrolled into the visible part of the screen.
- * @returns {boolean}
- */
- isVisible: function() {
- var i, l,
- parents = this.getParentList(false, false);
-
- for(i=0, l=parents.length; iexpanded state is maintained.
- * @param {boolean} [forceReload=false] Pass true to discard any existing nodes before. Otherwise this method does nothing if the node was already loaded.
- * @returns {$.Promise}
- */
- load: function(forceReload) {
- var res, source,
- that = this,
- wasExpanded = this.isExpanded();
-
- _assert( this.isLazy(), "load() requires a lazy node" );
- // _assert( forceReload || this.isUndefined(), "Pass forceReload=true to re-load a lazy node" );
- if( !forceReload && !this.isUndefined() ) {
- return _getResolvedPromise(this);
- }
- if( this.isLoaded() ){
- this.resetLazy(); // also collapses
- }
- // This method is also called by setExpanded() and loadKeyPath(), so we
- // have to avoid recursion.
- source = this.tree._triggerNodeEvent("lazyLoad", this);
- if( source === false ) { // #69
- return _getResolvedPromise(this);
- }
- _assert(typeof source !== "boolean", "lazyLoad event must return source in data.result");
- res = this.tree._callHook("nodeLoadChildren", this, source);
- if( wasExpanded ) {
- this.expanded = true;
- res.always(function(){
- that.render();
- });
- } else {
- res.always(function(){
- that.renderStatus(); // fix expander icon to 'loaded'
- });
- }
- return res;
- },
- /** Expand all parents and optionally scroll into visible area as neccessary.
- * Promise is resolved, when lazy loading and animations are done.
- * @param {object} [opts] passed to `setExpanded()`.
- * Defaults to {noAnimation: false, noEvents: false, scrollIntoView: true}
- * @returns {$.Promise}
- */
- makeVisible: function(opts) {
- var i,
- that = this,
- deferreds = [],
- dfd = new $.Deferred(),
- parents = this.getParentList(false, false),
- len = parents.length,
- effects = !(opts && opts.noAnimation === true),
- scroll = !(opts && opts.scrollIntoView === false);
-
- // Expand bottom-up, so only the top node is animated
- for(i = len - 1; i >= 0; i--){
- // that.debug("pushexpand" + parents[i]);
- deferreds.push(parents[i].setExpanded(true, opts));
- }
- $.when.apply($, deferreds).done(function(){
- // All expands have finished
- // that.debug("expand DONE", scroll);
- if( scroll ){
- that.scrollIntoView(effects).done(function(){
- // that.debug("scroll DONE");
- dfd.resolve();
- });
- } else {
- dfd.resolve();
- }
- });
- return dfd.promise();
- },
- /** Move this node to targetNode.
- * @param {FancytreeNode} targetNode
- * @param {string} mode
- * 'child': append this node as last child of targetNode.
- * This is the default. To be compatble with the D'n'd
- * hitMode, we also accept 'over'.
- * 'firstChild': add this node as first child of targetNode.
- * 'before': add this node as sibling before targetNode.
- * 'after': add this node as sibling after targetNode.
tag yet:
-// if( !targetParent.ul ) {
-// // This is the parent's first child: create UL tag
-// // (Hidden, because it will be
-// targetParent.ul = document.createElement("ul");
-// targetParent.ul.style.display = "none";
-// targetParent.li.appendChild(targetParent.ul);
-// }
-// // Issue 319: Add to target DOM parent (only if node was already rendered(expanded))
-// if(this.li){
-// targetParent.ul.appendChild(this.li);
-// }^
-
- // Let caller modify the nodes
- if( map ){
- targetNode.visit(map, true);
- }
- if( targetParent === prevParent ) {
- targetParent.triggerModifyChild("move", this);
- } else {
- // prevParent.triggerModifyChild("remove", this);
- targetParent.triggerModifyChild("add", this);
- }
- // Handle cross-tree moves
- if( this.tree !== targetNode.tree ) {
- // Fix node.tree for all source nodes
-// _assert(false, "Cross-tree move is not yet implemented.");
- this.warn("Cross-tree moveTo is experimantal!");
- this.visit(function(n){
- // TODO: fix selection state and activation, ...
- n.tree = targetNode.tree;
- }, true);
- }
-
- // A collaposed node won't re-render children, so we have to remove it manually
- // if( !targetParent.expanded ){
- // prevParent.ul.removeChild(this.li);
- // }
-
- // Update HTML markup
- if( !prevParent.isDescendantOf(targetParent)) {
- prevParent.render();
- }
- if( !targetParent.isDescendantOf(prevParent) && targetParent !== prevParent) {
- targetParent.render();
- }
- // TODO: fix selection state
- // TODO: fix active state
-
-/*
- var tree = this.tree;
- var opts = tree.options;
- var pers = tree.persistence;
-
-
- // Always expand, if it's below minExpandLevel
-// tree.logDebug ("%s._addChildNode(%o), l=%o", this, ftnode, ftnode.getLevel());
- if ( opts.minExpandLevel >= ftnode.getLevel() ) {
-// tree.logDebug ("Force expand for %o", ftnode);
- this.bExpanded = true;
- }
-
- // In multi-hier mode, update the parents selection state
- // DT issue #82: only if not initializing, because the children may not exist yet
-// if( !ftnode.data.isStatusNode() && opts.selectMode==3 && !isInitializing )
-// ftnode._fixSelectionState();
-
- // In multi-hier mode, update the parents selection state
- if( ftnode.bSelected && opts.selectMode==3 ) {
- var p = this;
- while( p ) {
- if( !p.hasSubSel )
- p._setSubSel(true);
- p = p.parent;
- }
- }
- // render this node and the new child
- if ( tree.bEnableUpdate )
- this.render();
-
- return ftnode;
-
-*/
- },
- /** Set focus relative to this node and optionally activate.
- *
- * @param {number} where The keyCode that would normally trigger this move,
- * e.g. `$.ui.keyCode.LEFT` would collapse the node if it
- * is expanded or move to the parent oterwise.
- * @param {boolean} [activate=true]
- * @returns {$.Promise}
- */
- navigate: function(where, activate) {
- var i, parents, res,
- handled = true,
- KC = $.ui.keyCode,
- sib = null;
-
- // Navigate to node
- function _goto(n){
- if( n ){
- // setFocus/setActive will scroll later (if autoScroll is specified)
- try { n.makeVisible({scrollIntoView: false}); } catch(e) {} // #272
- // Node may still be hidden by a filter
- if( ! $(n.span).is(":visible") ) {
- n.debug("Navigate: skipping hidden node");
- n.navigate(where, activate);
- return;
- }
- return activate === false ? n.setFocus() : n.setActive();
- }
- }
-
- switch( where ) {
- case KC.BACKSPACE:
- if( this.parent && this.parent.parent ) {
- res = _goto(this.parent);
- }
- break;
- case KC.HOME:
- this.tree.visit(function(n){ // goto first visible node
- if( $(n.span).is(":visible") ) {
- res = _goto(n);
- return false;
- }
- });
- break;
- case KC.END:
- this.tree.visit(function(n){ // goto last visible node
- if( $(n.span).is(":visible") ) {
- res = n;
- }
- });
- if( res ) {
- res = _goto(res);
- }
- break;
- case KC.LEFT:
- if( this.expanded ) {
- this.setExpanded(false);
- res = _goto(this);
- } else if( this.parent && this.parent.parent ) {
- res = _goto(this.parent);
- }
- break;
- case KC.RIGHT:
- if( !this.expanded && (this.children || this.lazy) ) {
- this.setExpanded();
- res = _goto(this);
- } else if( this.children && this.children.length ) {
- res = _goto(this.children[0]);
- }
- break;
- case KC.UP:
- sib = this.getPrevSibling();
- // #359: skip hidden sibling nodes, preventing a _goto() recursion
- while( sib && !$(sib.span).is(":visible") ) {
- sib = sib.getPrevSibling();
- }
- while( sib && sib.expanded && sib.children && sib.children.length ) {
- sib = sib.children[sib.children.length - 1];
- }
- if( !sib && this.parent && this.parent.parent ){
- sib = this.parent;
- }
- res = _goto(sib);
- break;
- case KC.DOWN:
- if( this.expanded && this.children && this.children.length ) {
- sib = this.children[0];
- } else {
- parents = this.getParentList(false, true);
- for(i=parents.length-1; i>=0; i--) {
- sib = parents[i].getNextSibling();
- // #359: skip hidden sibling nodes, preventing a _goto() recursion
- while( sib && !$(sib.span).is(":visible") ) {
- sib = sib.getNextSibling();
- }
- if( sib ){ break; }
- }
- }
- res = _goto(sib);
- break;
- default:
- handled = false;
- }
- return res || _getResolvedPromise();
- },
- /**
- * Remove this node (not allowed for system root).
- */
- remove: function() {
- return this.parent.removeChild(this);
- },
- /**
- * Remove childNode from list of direct children.
- * @param {FancytreeNode} childNode
- */
- removeChild: function(childNode) {
- return this.tree._callHook("nodeRemoveChild", this, childNode);
- },
- /**
- * Remove all child nodes and descendents. This converts the node into a leaf.
- * If this was a lazy node, it is still considered 'loaded'; call node.resetLazy()
- * in order to trigger lazyLoad on next expand.
- */
- removeChildren: function() {
- return this.tree._callHook("nodeRemoveChildren", this);
- },
- /**
- * Remove class from node's span tag and .extraClasses.
- *
- * @param {string} className class name
- *
- * @since 2.17
- */
- removeClass: function(className){
- return this.toggleClass(className, false);
- },
- /**
- * This method renders and updates all HTML markup that is required
- * to display this node in its current state.
- * Note:
- *
- *
It should only be neccessary to call this method after the node object
- * was modified by direct access to its properties, because the common
- * API methods (node.setTitle(), moveTo(), addChildren(), remove(), ...)
- * already handle this.
- *
{@link FancytreeNode#renderTitle} and {@link FancytreeNode#renderStatus}
- * are implied. If changes are more local, calling only renderTitle() or
- * renderStatus() may be sufficient and faster.
- *
- *
- * @param {boolean} [force=false] re-render, even if html markup was already created
- * @param {boolean} [deep=false] also render all descendants, even if parent is collapsed
- */
- render: function(force, deep) {
- return this.tree._callHook("nodeRender", this, force, deep);
- },
- /** Create HTML markup for the node's outer <span> (expander, checkbox, icon, and title).
- * Implies {@link FancytreeNode#renderStatus}.
- * @see Fancytree_Hooks#nodeRenderTitle
- */
- renderTitle: function() {
- return this.tree._callHook("nodeRenderTitle", this);
- },
- /** Update element's CSS classes according to node state.
- * @see Fancytree_Hooks#nodeRenderStatus
- */
- renderStatus: function() {
- return this.tree._callHook("nodeRenderStatus", this);
- },
- /**
- * (experimental) Replace this node with `source`.
- * (Currently only available for paging nodes.)
- * @param {NodeData[]} source List of child node definitions
- * @since 2.15
- */
- replaceWith: function(source) {
- var res,
- parent = this.parent,
- pos = $.inArray(this, parent.children),
- that = this;
-
- _assert( this.isPagingNode(), "replaceWith() currently requires a paging status node" );
-
- res = this.tree._callHook("nodeLoadChildren", this, source);
- res.done(function(data){
- // New nodes are currently children of `this`.
- var children = that.children;
- // Prepend newly loaded child nodes to `this`
- // Move new children after self
- for( i=0; i y ? 1 : -1;
- };
- cl.sort(cmp);
- if( deep ){
- for(i=0, l=cl.length; i= 0;
- flag = (flag === undefined) ? (!hasClass) : !!flag;
- if ( flag ) {
- if( !hasClass ) {
- curClasses += className + " ";
- wasAdded = true;
- }
- } else {
- while ( curClasses.indexOf( " " + className + " " ) > -1 ) {
- curClasses = curClasses.replace( " " + className + " ", " " );
- }
- }
- }
- this.extraClasses = $.trim(curClasses);
- // this.info("-> toggleClass('" + value + "', " + flag + "): '" + this.extraClasses + "'");
- return wasAdded;
- },
- /** Flip expanded status. */
- toggleExpanded: function(){
- return this.tree._callHook("nodeToggleExpanded", this);
- },
- /** Flip selection status. */
- toggleSelected: function(){
- return this.tree._callHook("nodeToggleSelected", this);
- },
- toString: function() {
- return "";
- },
- /**
- * Trigger `modifyChild` event on a parent to signal that a child was modified.
- * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ...
- * @param {FancytreeNode} [childNode]
- * @param {object} [extra]
- */
- triggerModifyChild: function(operation, childNode, extra){
- var data,
- modifyChild = this.tree.options.modifyChild;
-
- if ( modifyChild ){
- if( childNode && childNode.parent !== this ) {
- $.error("childNode " + childNode + " is not a child of " + this);
- }
- data = {
- node: this,
- tree: this.tree,
- operation: operation,
- childNode: childNode || null
- };
- if( extra ) {
- $.extend(data, extra);
- }
- modifyChild({type: "modifyChild"}, data);
- }
- },
- /**
- * Trigger `modifyChild` event on node.parent(!).
- * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ...
- * @param {object} [extra]
- */
- triggerModify: function(operation, extra){
- this.parent.triggerModifyChild(operation, this, extra);
- },
- /** Call fn(node) for all child nodes.
- * Stop iteration, if fn() returns false. Skip current branch, if fn() returns "skip".
- * Return false if iteration was stopped.
- *
- * @param {function} fn the callback function.
- * Return false to stop iteration, return "skip" to skip this node and
- * its children only.
- * @param {boolean} [includeSelf=false]
- * @returns {boolean}
- */
- visit: function(fn, includeSelf) {
- var i, l,
- res = true,
- children = this.children;
-
- if( includeSelf === true ) {
- res = fn(this);
- if( res === false || res === "skip" ){
- return res;
- }
- }
- if(children){
- for(i=0, l=children.length; i
- * Note: If you need this method, you probably should consider to review
- * your architecture! Recursivley loading nodes is a perfect way for lazy
- * programmers to flood the server with requests ;-)
- *
- * @param {function} [fn] optional callback function.
- * Return false to stop iteration, return "skip" to skip this node and
- * its children only.
- * @param {boolean} [includeSelf=false]
- * @returns {$.Promise}
- * @since 2.4
- */
- visitAndLoad: function(fn, includeSelf, _recursion) {
- var dfd, res, loaders,
- node = this;
-
- // node.debug("visitAndLoad");
- if( fn && includeSelf === true ) {
- res = fn(node);
- if( res === false || res === "skip" ) {
- return _recursion ? res : _getResolvedPromise();
- }
- }
- if( !node.children && !node.lazy ) {
- return _getResolvedPromise();
- }
- dfd = new $.Deferred();
- loaders = [];
- // node.debug("load()...");
- node.load().done(function(){
- // node.debug("load()... done.");
- for(var i=0, l=node.children.length; i
- * Stop iteration, if fn() returns false.
- * Return false if iteration was stopped.
- *
- * @param {function} fn the callback function.
- * Return false to stop iteration, return "skip" to skip this node and children only.
- * @param {boolean} [includeSelf=false]
- * @returns {boolean}
- */
- visitParents: function(fn, includeSelf) {
- // Visit parent nodes (bottom up)
- if(includeSelf && fn(this) === false){
- return false;
- }
- var p = this.parent;
- while( p ) {
- if(fn(p) === false){
- return false;
- }
- p = p.parent;
- }
- return true;
- },
- /** Call fn(node) for all sibling nodes.
- * Stop iteration, if fn() returns false.
- * Return false if iteration was stopped.
- *
- * @param {function} fn the callback function.
- * Return false to stop iteration.
- * @param {boolean} [includeSelf=false]
- * @returns {boolean}
- */
- visitSiblings: function(fn, includeSelf) {
- var i, l, n,
- ac = this.parent.children;
-
- for (i=0, l=ac.length; i element (or <table> element for ext-table).
- * @property {jQueryObject} $div A jQuery object containing the element used to instantiate the tree widget (`widget.element`)
- * @property {object} data Metadata, i.e. properties that may be passed to `source` in addition to a children array.
- * @property {object} ext Hash of all active plugin instances.
- * @property {FancytreeNode} focusNode Currently focused node or null.
- * @property {FancytreeNode} lastSelectedNode Used to implement selectMode 1 (single select)
- * @property {string} nodeContainerAttrName Property name of FancytreeNode that contains the outer element of single nodes.
- * Typically "li", but "tr" for table extension.
- * @property {FancytreeOptions} options Current options, i.e. default options + options passed to constructor.
- * @property {FancytreeNode} rootNode Invisible system root node.
- * @property {string} statusClassPropName Property name of FancytreeNode that contains the element which will receive the status classes.
- * Typically "span", but "tr" for table extension.
- * @property {object} widget Base widget instance.
- */
-function Fancytree(widget) {
- this.widget = widget;
- this.$div = widget.element;
- this.options = widget.options;
- if( this.options ) {
- if( $.isFunction(this.options.lazyload ) && !$.isFunction(this.options.lazyLoad) ) {
- this.options.lazyLoad = function() {
- FT.warn("The 'lazyload' event is deprecated since 2014-02-25. Use 'lazyLoad' (with uppercase L) instead.");
- return widget.options.lazyload.apply(this, arguments);
- };
- }
- if( $.isFunction(this.options.loaderror) ) {
- $.error("The 'loaderror' event was renamed since 2014-07-03. Use 'loadError' (with uppercase E) instead.");
- }
- if( this.options.fx !== undefined ) {
- FT.warn("The 'fx' option was replaced by 'toggleEffect' since 2014-11-30.");
- }
- if( this.options.removeNode !== undefined ) {
- $.error("The 'removeNode' event was replaced by 'modifyChild' since 2.20 (2016-09-10).");
- }
- }
- this.ext = {}; // Active extension instances
- // allow to init tree.data.foo from
is already returned as object (http://api.jquery.com/data/#data-html5)
- d = $.extend(d, json);
- }
- return d;
-}
-
-
-function _escapeHtml(s){
- return ("" + s).replace(REX_HTML, function(s) {
- return ENTITY_MAP[s];
- });
-}
-
-
-function _escapeTooltip(s){
- return ("" + s).replace(REX_TOOLTIP, function(s) {
- return ENTITY_MAP[s];
- });
-}
-
-
-// TODO: use currying
-function _makeNodeTitleMatcher(s){
- s = s.toLowerCase();
- return function(node){
- return node.title.toLowerCase().indexOf(s) >= 0;
- };
-}
-
-
-function _makeNodeTitleStartMatcher(s){
- var reMatch = new RegExp("^" + s, "i");
- return function(node){
- return reMatch.test(node.title);
- };
-}
-
-
-/* *****************************************************************************
- * FancytreeNode
- */
-
-
-/**
- * Creates a new FancytreeNode
- *
- * @class FancytreeNode
- * @classdesc A FancytreeNode represents the hierarchical data model and operations.
- *
- * @param {FancytreeNode} parent
- * @param {NodeData} obj
- *
- * @property {Fancytree} tree The tree instance
- * @property {FancytreeNode} parent The parent node
- * @property {string} key Node id (must be unique inside the tree)
- * @property {string} title Display name (may contain HTML)
- * @property {object} data Contains all extra data that was passed on node creation
- * @property {FancytreeNode[] | null | undefined} children Array of child nodes.
- * For lazy nodes, null or undefined means 'not yet loaded'. Use an empty array
- * to define a node that has no children.
- * @property {boolean} expanded Use isExpanded(), setExpanded() to access this property.
- * @property {string} extraClasses Additional CSS classes, added to the node's `<span>`.
- * Note: use `node.add/remove/toggleClass()` to modify.
- * @property {boolean} folder Folder nodes have different default icons and click behavior.
- * Note: Also non-folders may have children.
- * @property {string} statusNodeType null for standard nodes. Otherwise type of special system node: 'error', 'loading', 'nodata', or 'paging'.
- * @property {boolean} lazy True if this node is loaded on demand, i.e. on first expansion.
- * @property {boolean} selected Use isSelected(), setSelected() to access this property.
- * @property {string} tooltip Alternative description used as hover popup
- */
-function FancytreeNode(parent, obj){
- var i, l, name, cl;
-
- this.parent = parent;
- this.tree = parent.tree;
- this.ul = null;
- this.li = null; //
tag
- this.statusNodeType = null; // if this is a temp. node to display the status of its parent
- this._isLoading = false; // if this node itself is loading
- this._error = null; // {message: '...'} if a load error occurred
- this.data = {};
-
- // TODO: merge this code with node.toDict()
- // copy attributes from obj object
- for(i=0, l=NODE_ATTRS.length; i= 0, "insertBefore must be an existing child");
- // insert nodeList after children[pos]
- this.children.splice.apply(this.children, [pos, 0].concat(nodeList));
- }
- if ( origFirstChild && !insertBefore ) {
- // #708: Fast path -- don't render every child of root, just the new ones!
- // #723, #729: but only if it's appended to an existing child list
- for(i=0, l=nodeList.length; i= 0; i--) {
- n = this.children[i];
- if( n.statusNodeType === "paging" ) {
- this.removeChild(n);
- }
- }
- this.partload = false;
- return;
- }
- node = $.extend({
- title: this.tree.options.strings.moreData,
- statusNodeType: "paging",
- icon: false
- }, node);
- this.partload = true;
- return this.addNode(node, mode);
- },
- /**
- * Append new node after this.
- *
- * This a convenience function that calls addNode(node, 'after')
- *
- * @param {NodeData} node node definition
- * @returns {FancytreeNode} new node
- */
- appendSibling: function(node){
- return this.addNode(node, "after");
- },
- /**
- * Modify existing child nodes.
- *
- * @param {NodePatch} patch
- * @returns {$.Promise}
- * @see FancytreeNode#addChildren
- */
- applyPatch: function(patch) {
- // patch [key, null] means 'remove'
- if(patch === null){
- this.remove();
- return _getResolvedPromise(this);
- }
- // TODO: make sure that root node is not collapsed or modified
- // copy (most) attributes to node.ATTR or node.data.ATTR
- var name, promise, v,
- IGNORE_MAP = { children: true, expanded: true, parent: true }; // TODO: should be global
-
- for(name in patch){
- v = patch[name];
- if( !IGNORE_MAP[name] && !$.isFunction(v)){
- if(NODE_ATTR_MAP[name]){
- this[name] = v;
- }else{
- this.data[name] = v;
- }
- }
- }
- // Remove and/or create children
- if(patch.hasOwnProperty("children")){
- this.removeChildren();
- if(patch.children){ // only if not null and not empty list
- // TODO: addChildren instead?
- this._setChildren(patch.children);
- }
- // TODO: how can we APPEND or INSERT child nodes?
- }
- if(this.isVisible()){
- this.renderTitle();
- this.renderStatus();
- }
- // Expand collapse (final step, since this may be async)
- if(patch.hasOwnProperty("expanded")){
- promise = this.setExpanded(patch.expanded);
- }else{
- promise = _getResolvedPromise(this);
- }
- return promise;
- },
- /** Collapse all sibling nodes.
- * @returns {$.Promise}
- */
- collapseSiblings: function() {
- return this.tree._callHook("nodeCollapseSiblings", this);
- },
- /** Copy this node as sibling or child of `node`.
- *
- * @param {FancytreeNode} node source node
- * @param {string} [mode=child] 'before' | 'after' | 'child'
- * @param {Function} [map] callback function(NodeData) that could modify the new node
- * @returns {FancytreeNode} new
- */
- copyTo: function(node, mode, map) {
- return node.addNode(this.toDict(true, map), mode);
- },
- /** Count direct and indirect children.
- *
- * @param {boolean} [deep=true] pass 'false' to only count direct children
- * @returns {int} number of child nodes
- */
- countChildren: function(deep) {
- var cl = this.children, i, l, n;
- if( !cl ){
- return 0;
- }
- n = cl.length;
- if(deep !== false){
- for(i=0, l=n; i= 2 (prepending node info)
- *
- * @param {*} msg string or object or array of such
- */
- debug: function(msg){
- if( this.tree.options.debugLevel >= 2 ) {
- Array.prototype.unshift.call(arguments, this.toString());
- consoleApply("log", arguments);
- }
- },
- /** Deprecated.
- * @deprecated since 2014-02-16. Use resetLazy() instead.
- */
- discard: function(){
- this.warn("FancytreeNode.discard() is deprecated since 2014-02-16. Use .resetLazy() instead.");
- return this.resetLazy();
- },
- /** Remove DOM elements for all descendents. May be called on .collapse event
- * to keep the DOM small.
- * @param {boolean} [includeSelf=false]
- */
- discardMarkup: function(includeSelf){
- var fn = includeSelf ? "nodeRemoveMarkup" : "nodeRemoveChildMarkup";
- this.tree._callHook(fn, this);
- },
- /**Find all nodes that match condition (excluding self).
- *
- * @param {string | function(node)} match title string to search for, or a
- * callback function that returns `true` if a node is matched.
- * @returns {FancytreeNode[]} array of nodes (may be empty)
- */
- findAll: function(match) {
- match = $.isFunction(match) ? match : _makeNodeTitleMatcher(match);
- var res = [];
- this.visit(function(n){
- if(match(n)){
- res.push(n);
- }
- });
- return res;
- },
- /**Find first node that matches condition (excluding self).
- *
- * @param {string | function(node)} match title string to search for, or a
- * callback function that returns `true` if a node is matched.
- * @returns {FancytreeNode} matching node or null
- * @see FancytreeNode#findAll
- */
- findFirst: function(match) {
- match = $.isFunction(match) ? match : _makeNodeTitleMatcher(match);
- var res = null;
- this.visit(function(n){
- if(match(n)){
- res = n;
- return false;
- }
- });
- return res;
- },
- /* Apply selection state (internal use only) */
- _changeSelectStatusAttrs: function(state) {
- var changed = false,
- opts = this.tree.options,
- unselectable = FT.evalOption("unselectable", this, this, opts, false),
- unselectableStatus = FT.evalOption("unselectableStatus", this, this, opts, undefined);
-
- if( unselectable && unselectableStatus != null ) {
- state = unselectableStatus;
- }
- switch(state){
- case false:
- changed = ( this.selected || this.partsel );
- this.selected = false;
- this.partsel = false;
- break;
- case true:
- changed = ( !this.selected || !this.partsel );
- this.selected = true;
- this.partsel = true;
- break;
- case undefined:
- changed = ( this.selected || !this.partsel );
- this.selected = false;
- this.partsel = true;
- break;
- default:
- _assert(false, "invalid state: " + state);
- }
- // this.debug("fixSelection3AfterLoad() _changeSelectStatusAttrs()", state, changed);
- if( changed ){
- this.renderStatus();
- }
- return changed;
- },
- /**
- * Fix selection status, after this node was (de)selected in multi-hier mode.
- * This includes (de)selecting all children.
- */
- fixSelection3AfterClick: function(callOpts) {
- var flag = this.isSelected();
-
-// this.debug("fixSelection3AfterClick()");
-
- this.visit(function(node){
- node._changeSelectStatusAttrs(flag);
- });
- this.fixSelection3FromEndNodes(callOpts);
- },
- /**
- * Fix selection status for multi-hier mode.
- * Only end-nodes are considered to update the descendants branch and parents.
- * Should be called after this node has loaded new children or after
- * children have been modified using the API.
- */
- fixSelection3FromEndNodes: function(callOpts) {
- var opts = this.tree.options;
-
-// this.debug("fixSelection3FromEndNodes()");
- _assert(opts.selectMode === 3, "expected selectMode 3");
-
- // Visit all end nodes and adjust their parent's `selected` and `partsel`
- // attributes. Return selection state true, false, or undefined.
- function _walk(node){
- var i, l, child, s, state, allSelected, someSelected, unselIgnore, unselState,
- children = node.children;
-
- if( children && children.length ){
- // check all children recursively
- allSelected = true;
- someSelected = false;
-
- for( i=0, l=children.length; i= 1 (prepending node info)
- *
- * @param {*} msg string or object or array of such
- */
- info: function(msg){
- if( this.tree.options.debugLevel >= 1 ) {
- Array.prototype.unshift.call(arguments, this.toString());
- consoleApply("info", arguments);
- }
- },
- /** Return true if node is active (see also FancytreeNode#isSelected).
- * @returns {boolean}
- */
- isActive: function() {
- return (this.tree.activeNode === this);
- },
- /** Return true if node is a direct child of otherNode.
- * @param {FancytreeNode} otherNode
- * @returns {boolean}
- */
- isChildOf: function(otherNode) {
- return (this.parent && this.parent === otherNode);
- },
- /** Return true, if node is a direct or indirect sub node of otherNode.
- * @param {FancytreeNode} otherNode
- * @returns {boolean}
- */
- isDescendantOf: function(otherNode) {
- if(!otherNode || otherNode.tree !== this.tree){
- return false;
- }
- var p = this.parent;
- while( p ) {
- if( p === otherNode ){
- return true;
- }
- p = p.parent;
- }
- return false;
- },
- /** Return true if node is expanded.
- * @returns {boolean}
- */
- isExpanded: function() {
- return !!this.expanded;
- },
- /** Return true if node is the first node of its parent's children.
- * @returns {boolean}
- */
- isFirstSibling: function() {
- var p = this.parent;
- return !p || p.children[0] === this;
- },
- /** Return true if node is a folder, i.e. has the node.folder attribute set.
- * @returns {boolean}
- */
- isFolder: function() {
- return !!this.folder;
- },
- /** Return true if node is the last node of its parent's children.
- * @returns {boolean}
- */
- isLastSibling: function() {
- var p = this.parent;
- return !p || p.children[p.children.length-1] === this;
- },
- /** Return true if node is lazy (even if data was already loaded)
- * @returns {boolean}
- */
- isLazy: function() {
- return !!this.lazy;
- },
- /** Return true if node is lazy and loaded. For non-lazy nodes always return true.
- * @returns {boolean}
- */
- isLoaded: function() {
- return !this.lazy || this.hasChildren() !== undefined; // Also checks if the only child is a status node
- },
- /** Return true if children are currently beeing loaded, i.e. a Ajax request is pending.
- * @returns {boolean}
- */
- isLoading: function() {
- return !!this._isLoading;
- },
- /*
- * @deprecated since v2.4.0: Use isRootNode() instead
- */
- isRoot: function() {
- return this.isRootNode();
- },
- /** Return true if node is partially selected (tri-state).
- * @returns {boolean}
- * @since 2.23
- */
- isPartsel: function() {
- return !this.selected && !!this.partsel;
- },
- /** (experimental) Return true if this is partially loaded.
- * @returns {boolean}
- * @since 2.15
- */
- isPartload: function() {
- return !!this.partload;
- },
- /** Return true if this is the (invisible) system root node.
- * @returns {boolean}
- * @since 2.4
- */
- isRootNode: function() {
- return (this.tree.rootNode === this);
- },
- /** Return true if node is selected, i.e. has a checkmark set (see also FancytreeNode#isActive).
- * @returns {boolean}
- */
- isSelected: function() {
- return !!this.selected;
- },
- /** Return true if this node is a temporarily generated system node like
- * 'loading', 'paging', or 'error' (node.statusNodeType contains the type).
- * @returns {boolean}
- */
- isStatusNode: function() {
- return !!this.statusNodeType;
- },
- /** Return true if this node is a status node of type 'paging'.
- * @returns {boolean}
- * @since 2.15
- */
- isPagingNode: function() {
- return this.statusNodeType === "paging";
- },
- /** Return true if this a top level node, i.e. a direct child of the (invisible) system root node.
- * @returns {boolean}
- * @since 2.4
- */
- isTopLevel: function() {
- return (this.tree.rootNode === this.parent);
- },
- /** Return true if node is lazy and not yet loaded. For non-lazy nodes always return false.
- * @returns {boolean}
- */
- isUndefined: function() {
- return this.hasChildren() === undefined; // also checks if the only child is a status node
- },
- /** Return true if all parent nodes are expanded. Note: this does not check
- * whether the node is scrolled into the visible part of the screen.
- * @returns {boolean}
- */
- isVisible: function() {
- var i, l,
- parents = this.getParentList(false, false);
-
- for(i=0, l=parents.length; iexpanded state is maintained.
- * @param {boolean} [forceReload=false] Pass true to discard any existing nodes before. Otherwise this method does nothing if the node was already loaded.
- * @returns {$.Promise}
- */
- load: function(forceReload) {
- var res, source,
- that = this,
- wasExpanded = this.isExpanded();
-
- _assert( this.isLazy(), "load() requires a lazy node" );
- // _assert( forceReload || this.isUndefined(), "Pass forceReload=true to re-load a lazy node" );
- if( !forceReload && !this.isUndefined() ) {
- return _getResolvedPromise(this);
- }
- if( this.isLoaded() ){
- this.resetLazy(); // also collapses
- }
- // This method is also called by setExpanded() and loadKeyPath(), so we
- // have to avoid recursion.
- source = this.tree._triggerNodeEvent("lazyLoad", this);
- if( source === false ) { // #69
- return _getResolvedPromise(this);
- }
- _assert(typeof source !== "boolean", "lazyLoad event must return source in data.result");
- res = this.tree._callHook("nodeLoadChildren", this, source);
- if( wasExpanded ) {
- this.expanded = true;
- res.always(function(){
- that.render();
- });
- } else {
- res.always(function(){
- that.renderStatus(); // fix expander icon to 'loaded'
- });
- }
- return res;
- },
- /** Expand all parents and optionally scroll into visible area as neccessary.
- * Promise is resolved, when lazy loading and animations are done.
- * @param {object} [opts] passed to `setExpanded()`.
- * Defaults to {noAnimation: false, noEvents: false, scrollIntoView: true}
- * @returns {$.Promise}
- */
- makeVisible: function(opts) {
- var i,
- that = this,
- deferreds = [],
- dfd = new $.Deferred(),
- parents = this.getParentList(false, false),
- len = parents.length,
- effects = !(opts && opts.noAnimation === true),
- scroll = !(opts && opts.scrollIntoView === false);
-
- // Expand bottom-up, so only the top node is animated
- for(i = len - 1; i >= 0; i--){
- // that.debug("pushexpand" + parents[i]);
- deferreds.push(parents[i].setExpanded(true, opts));
- }
- $.when.apply($, deferreds).done(function(){
- // All expands have finished
- // that.debug("expand DONE", scroll);
- if( scroll ){
- that.scrollIntoView(effects).done(function(){
- // that.debug("scroll DONE");
- dfd.resolve();
- });
- } else {
- dfd.resolve();
- }
- });
- return dfd.promise();
- },
- /** Move this node to targetNode.
- * @param {FancytreeNode} targetNode
- * @param {string} mode
- * 'child': append this node as last child of targetNode.
- * This is the default. To be compatble with the D'n'd
- * hitMode, we also accept 'over'.
- * 'firstChild': add this node as first child of targetNode.
- * 'before': add this node as sibling before targetNode.
- * 'after': add this node as sibling after targetNode.
tag yet:
-// if( !targetParent.ul ) {
-// // This is the parent's first child: create UL tag
-// // (Hidden, because it will be
-// targetParent.ul = document.createElement("ul");
-// targetParent.ul.style.display = "none";
-// targetParent.li.appendChild(targetParent.ul);
-// }
-// // Issue 319: Add to target DOM parent (only if node was already rendered(expanded))
-// if(this.li){
-// targetParent.ul.appendChild(this.li);
-// }^
-
- // Let caller modify the nodes
- if( map ){
- targetNode.visit(map, true);
- }
- if( targetParent === prevParent ) {
- targetParent.triggerModifyChild("move", this);
- } else {
- // prevParent.triggerModifyChild("remove", this);
- targetParent.triggerModifyChild("add", this);
- }
- // Handle cross-tree moves
- if( this.tree !== targetNode.tree ) {
- // Fix node.tree for all source nodes
-// _assert(false, "Cross-tree move is not yet implemented.");
- this.warn("Cross-tree moveTo is experimantal!");
- this.visit(function(n){
- // TODO: fix selection state and activation, ...
- n.tree = targetNode.tree;
- }, true);
- }
-
- // A collaposed node won't re-render children, so we have to remove it manually
- // if( !targetParent.expanded ){
- // prevParent.ul.removeChild(this.li);
- // }
-
- // Update HTML markup
- if( !prevParent.isDescendantOf(targetParent)) {
- prevParent.render();
- }
- if( !targetParent.isDescendantOf(prevParent) && targetParent !== prevParent) {
- targetParent.render();
- }
- // TODO: fix selection state
- // TODO: fix active state
-
-/*
- var tree = this.tree;
- var opts = tree.options;
- var pers = tree.persistence;
-
-
- // Always expand, if it's below minExpandLevel
-// tree.logDebug ("%s._addChildNode(%o), l=%o", this, ftnode, ftnode.getLevel());
- if ( opts.minExpandLevel >= ftnode.getLevel() ) {
-// tree.logDebug ("Force expand for %o", ftnode);
- this.bExpanded = true;
- }
-
- // In multi-hier mode, update the parents selection state
- // DT issue #82: only if not initializing, because the children may not exist yet
-// if( !ftnode.data.isStatusNode() && opts.selectMode==3 && !isInitializing )
-// ftnode._fixSelectionState();
-
- // In multi-hier mode, update the parents selection state
- if( ftnode.bSelected && opts.selectMode==3 ) {
- var p = this;
- while( p ) {
- if( !p.hasSubSel )
- p._setSubSel(true);
- p = p.parent;
- }
- }
- // render this node and the new child
- if ( tree.bEnableUpdate )
- this.render();
-
- return ftnode;
-
-*/
- },
- /** Set focus relative to this node and optionally activate.
- *
- * @param {number} where The keyCode that would normally trigger this move,
- * e.g. `$.ui.keyCode.LEFT` would collapse the node if it
- * is expanded or move to the parent oterwise.
- * @param {boolean} [activate=true]
- * @returns {$.Promise}
- */
- navigate: function(where, activate) {
- var i, parents, res,
- handled = true,
- KC = $.ui.keyCode,
- sib = null;
-
- // Navigate to node
- function _goto(n){
- if( n ){
- // setFocus/setActive will scroll later (if autoScroll is specified)
- try { n.makeVisible({scrollIntoView: false}); } catch(e) {} // #272
- // Node may still be hidden by a filter
- if( ! $(n.span).is(":visible") ) {
- n.debug("Navigate: skipping hidden node");
- n.navigate(where, activate);
- return;
- }
- return activate === false ? n.setFocus() : n.setActive();
- }
- }
-
- switch( where ) {
- case KC.BACKSPACE:
- if( this.parent && this.parent.parent ) {
- res = _goto(this.parent);
- }
- break;
- case KC.HOME:
- this.tree.visit(function(n){ // goto first visible node
- if( $(n.span).is(":visible") ) {
- res = _goto(n);
- return false;
- }
- });
- break;
- case KC.END:
- this.tree.visit(function(n){ // goto last visible node
- if( $(n.span).is(":visible") ) {
- res = n;
- }
- });
- if( res ) {
- res = _goto(res);
- }
- break;
- case KC.LEFT:
- if( this.expanded ) {
- this.setExpanded(false);
- res = _goto(this);
- } else if( this.parent && this.parent.parent ) {
- res = _goto(this.parent);
- }
- break;
- case KC.RIGHT:
- if( !this.expanded && (this.children || this.lazy) ) {
- this.setExpanded();
- res = _goto(this);
- } else if( this.children && this.children.length ) {
- res = _goto(this.children[0]);
- }
- break;
- case KC.UP:
- sib = this.getPrevSibling();
- // #359: skip hidden sibling nodes, preventing a _goto() recursion
- while( sib && !$(sib.span).is(":visible") ) {
- sib = sib.getPrevSibling();
- }
- while( sib && sib.expanded && sib.children && sib.children.length ) {
- sib = sib.children[sib.children.length - 1];
- }
- if( !sib && this.parent && this.parent.parent ){
- sib = this.parent;
- }
- res = _goto(sib);
- break;
- case KC.DOWN:
- if( this.expanded && this.children && this.children.length ) {
- sib = this.children[0];
- } else {
- parents = this.getParentList(false, true);
- for(i=parents.length-1; i>=0; i--) {
- sib = parents[i].getNextSibling();
- // #359: skip hidden sibling nodes, preventing a _goto() recursion
- while( sib && !$(sib.span).is(":visible") ) {
- sib = sib.getNextSibling();
- }
- if( sib ){ break; }
- }
- }
- res = _goto(sib);
- break;
- default:
- handled = false;
- }
- return res || _getResolvedPromise();
- },
- /**
- * Remove this node (not allowed for system root).
- */
- remove: function() {
- return this.parent.removeChild(this);
- },
- /**
- * Remove childNode from list of direct children.
- * @param {FancytreeNode} childNode
- */
- removeChild: function(childNode) {
- return this.tree._callHook("nodeRemoveChild", this, childNode);
- },
- /**
- * Remove all child nodes and descendents. This converts the node into a leaf.
- * If this was a lazy node, it is still considered 'loaded'; call node.resetLazy()
- * in order to trigger lazyLoad on next expand.
- */
- removeChildren: function() {
- return this.tree._callHook("nodeRemoveChildren", this);
- },
- /**
- * Remove class from node's span tag and .extraClasses.
- *
- * @param {string} className class name
- *
- * @since 2.17
- */
- removeClass: function(className){
- return this.toggleClass(className, false);
- },
- /**
- * This method renders and updates all HTML markup that is required
- * to display this node in its current state.
- * Note:
- *
- *
It should only be neccessary to call this method after the node object
- * was modified by direct access to its properties, because the common
- * API methods (node.setTitle(), moveTo(), addChildren(), remove(), ...)
- * already handle this.
- *
{@link FancytreeNode#renderTitle} and {@link FancytreeNode#renderStatus}
- * are implied. If changes are more local, calling only renderTitle() or
- * renderStatus() may be sufficient and faster.
- *
- *
- * @param {boolean} [force=false] re-render, even if html markup was already created
- * @param {boolean} [deep=false] also render all descendants, even if parent is collapsed
- */
- render: function(force, deep) {
- return this.tree._callHook("nodeRender", this, force, deep);
- },
- /** Create HTML markup for the node's outer <span> (expander, checkbox, icon, and title).
- * Implies {@link FancytreeNode#renderStatus}.
- * @see Fancytree_Hooks#nodeRenderTitle
- */
- renderTitle: function() {
- return this.tree._callHook("nodeRenderTitle", this);
- },
- /** Update element's CSS classes according to node state.
- * @see Fancytree_Hooks#nodeRenderStatus
- */
- renderStatus: function() {
- return this.tree._callHook("nodeRenderStatus", this);
- },
- /**
- * (experimental) Replace this node with `source`.
- * (Currently only available for paging nodes.)
- * @param {NodeData[]} source List of child node definitions
- * @since 2.15
- */
- replaceWith: function(source) {
- var res,
- parent = this.parent,
- pos = $.inArray(this, parent.children),
- that = this;
-
- _assert( this.isPagingNode(), "replaceWith() currently requires a paging status node" );
-
- res = this.tree._callHook("nodeLoadChildren", this, source);
- res.done(function(data){
- // New nodes are currently children of `this`.
- var children = that.children;
- // Prepend newly loaded child nodes to `this`
- // Move new children after self
- for( i=0; i y ? 1 : -1;
- };
- cl.sort(cmp);
- if( deep ){
- for(i=0, l=cl.length; i= 0;
- flag = (flag === undefined) ? (!hasClass) : !!flag;
- if ( flag ) {
- if( !hasClass ) {
- curClasses += className + " ";
- wasAdded = true;
- }
- } else {
- while ( curClasses.indexOf( " " + className + " " ) > -1 ) {
- curClasses = curClasses.replace( " " + className + " ", " " );
- }
- }
- }
- this.extraClasses = $.trim(curClasses);
- // this.info("-> toggleClass('" + value + "', " + flag + "): '" + this.extraClasses + "'");
- return wasAdded;
- },
- /** Flip expanded status. */
- toggleExpanded: function(){
- return this.tree._callHook("nodeToggleExpanded", this);
- },
- /** Flip selection status. */
- toggleSelected: function(){
- return this.tree._callHook("nodeToggleSelected", this);
- },
- toString: function() {
- return "";
- },
- /**
- * Trigger `modifyChild` event on a parent to signal that a child was modified.
- * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ...
- * @param {FancytreeNode} [childNode]
- * @param {object} [extra]
- */
- triggerModifyChild: function(operation, childNode, extra){
- var data,
- modifyChild = this.tree.options.modifyChild;
-
- if ( modifyChild ){
- if( childNode && childNode.parent !== this ) {
- $.error("childNode " + childNode + " is not a child of " + this);
- }
- data = {
- node: this,
- tree: this.tree,
- operation: operation,
- childNode: childNode || null
- };
- if( extra ) {
- $.extend(data, extra);
- }
- modifyChild({type: "modifyChild"}, data);
- }
- },
- /**
- * Trigger `modifyChild` event on node.parent(!).
- * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ...
- * @param {object} [extra]
- */
- triggerModify: function(operation, extra){
- this.parent.triggerModifyChild(operation, this, extra);
- },
- /** Call fn(node) for all child nodes.
- * Stop iteration, if fn() returns false. Skip current branch, if fn() returns "skip".
- * Return false if iteration was stopped.
- *
- * @param {function} fn the callback function.
- * Return false to stop iteration, return "skip" to skip this node and
- * its children only.
- * @param {boolean} [includeSelf=false]
- * @returns {boolean}
- */
- visit: function(fn, includeSelf) {
- var i, l,
- res = true,
- children = this.children;
-
- if( includeSelf === true ) {
- res = fn(this);
- if( res === false || res === "skip" ){
- return res;
- }
- }
- if(children){
- for(i=0, l=children.length; i
- * Note: If you need this method, you probably should consider to review
- * your architecture! Recursivley loading nodes is a perfect way for lazy
- * programmers to flood the server with requests ;-)
- *
- * @param {function} [fn] optional callback function.
- * Return false to stop iteration, return "skip" to skip this node and
- * its children only.
- * @param {boolean} [includeSelf=false]
- * @returns {$.Promise}
- * @since 2.4
- */
- visitAndLoad: function(fn, includeSelf, _recursion) {
- var dfd, res, loaders,
- node = this;
-
- // node.debug("visitAndLoad");
- if( fn && includeSelf === true ) {
- res = fn(node);
- if( res === false || res === "skip" ) {
- return _recursion ? res : _getResolvedPromise();
- }
- }
- if( !node.children && !node.lazy ) {
- return _getResolvedPromise();
- }
- dfd = new $.Deferred();
- loaders = [];
- // node.debug("load()...");
- node.load().done(function(){
- // node.debug("load()... done.");
- for(var i=0, l=node.children.length; i
- * Stop iteration, if fn() returns false.