text: /*!
   * 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-2020, Martin Wendt (https://wwWendt.de)
   *
   * Released under the MIT license
   * https://github.com/mar10/fancytree/wiki/LicenseInfo
   *
   * @version 2.35.0
   * @date 2020-03-27T22:41:58Z
   */
  
  (function(factory) {
  	if (typeof define === "function" && define.amd) {
  		// AMD. Register as an anonymous module.
  		define(["jquery", "./jquery.fancytree"], factory);
  	} else if (typeof module === "object" && module.exports) {
  		// Node/CommonJS
  		require("./jquery.fancytree");
  		module.exports = factory(require("jquery"));
  	} else {
  		// Browser globals
  		factory(jQuery);
  	}
  })(function($) {
  	"use strict";
  	/* global Cookies:false */
  
  	/*******************************************************************************
  	 * Private functions and variables
  	 */
  	var cookieStore = null,
  		localStorageStore = window.localStorage
  			? {
  					get: function(key) {
  						return window.localStorage.getItem(key);
  					},
  					set: function(key, value) {
  						window.localStorage.setItem(key, value);
  					},
  					remove: function(key) {
  						window.localStorage.removeItem(key);
  					},
  			  }
  			: null,
  		sessionStorageStore = window.sessionStorage
  			? {
  					get: function(key) {
  						return window.sessionStorage.getItem(key);
  					},
  					set: function(key, value) {
  						window.sessionStorage.setItem(key, value);
  					},
  					remove: function(key) {
  						window.sessionStorage.removeItem(key);
  					},
  			  }
  			: null,
  		_assert = $.ui.fancytree.assert,
  		ACTIVE = "active",
  		EXPANDED = "expanded",
  		FOCUS = "focus",
  		SELECTED = "selected";
  
  	if (typeof Cookies === "function") {
  		// Assume https://github.com/js-cookie/js-cookie
  		cookieStore = {
  			get: Cookies.get,
  			set: function(key, value) {
  				Cookies.set(key, value, this.options.persist.cookie);
  			},
  			remove: Cookies.remove,
  		};
  	} else if ($ && typeof $.cookie === "function") {
  		// Fall back to https://github.com/carhartl/jquery-cookie
  		cookieStore = {
  			get: $.cookie,
  			set: function(key, value) {
  				$.cookie.set(key, value, this.options.persist.cookie);
  			},
  			remove: $.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 < l; i++) {
  			key = keyList[i];
  			node = tree.getNodeByKey(key);
  			if (node) {
  				if (mode && node.isUndefined()) {
  					foundOne = true;
  					tree.debug(
  						"_loadLazyNodes: " + node + " is lazy: loading..."
  					);
  					if (mode === "expand") {
  						deferredList.push(node.setExpanded(true, expandOpts));
  					} else {
  						deferredList.push(node.load());
  					}
  				} else {
  					tree.debug("_loadLazyNodes: " + node + " already loaded.");
  					node.setExpanded(true, expandOpts);
  				}
  			} else {
  				missingKeyList.push(key);
  				tree.debug("_loadLazyNodes: " + node + " was not yet found.");
  			}
  		}
  
  		$.when.apply($, deferredList).always(function() {
  			// All lazy-expands have finished
  			if (foundOne && missingKeyList.length > 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 < l; i++) {
  						key = keyList[i];
  						local._appendKey(EXPANDED, keyList[i], false);
  					}
  				}
  				dfd.resolve();
  			}
  		});
  		return dfd;
  	}
  
  	/**
  	 * [ext-persist] Remove persistence data of the given type(s).
  	 * Called like
  	 *     $.ui.fancytree.getTree("#tree").clearCookies("active expanded focus selected");
  	 *
  	 * @alias Fancytree#clearPersistData
  	 * @requires jquery.fancytree.persist.js
  	 */
  	$.ui.fancytree._FancytreeClass.prototype.clearPersistData = function(
  		types
  	) {
  		var local = this.ext.persist,
  			prefix = local.cookiePrefix;
  
  		types = types || "active expanded focus selected";
  		if (types.indexOf(ACTIVE) >= 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);
  		}
  	};
  
  	$.ui.fancytree._FancytreeClass.prototype.clearCookies = function(types) {
  		this.warn(
  			"'tree.clearCookies()' is deprecated since v2.27.0: use 'clearPersistData()' instead."
  		);
  		return this.clearPersistData(types);
  	};
  
  	/**
  	 * [ext-persist] Return persistence information from cookies
  	 *
  	 * Called like
  	 *     $.ui.fancytree.getTree("#tree").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.35.0",
  		// Default options for this extension.
  		options: {
  			cookieDelimiter: "~",
  			cookiePrefix: undefined, // 'fancytree-<treeId>-' 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 store = this._local.store;
  
  			if (value === undefined) {
  				return store.get.call(this, key);
  			} else if (value === null) {
  				store.remove.call(this, key);
  			} else {
  				store.set.call(this, key, value);
  			}
  		},
  
  		/* 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") || cookieStore,
  			// 	"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;
  			local.store = null;
  
  			if (instOpts.store === "auto") {
  				instOpts.store = localStorageStore ? "local" : "cookie";
  			}
  			if ($.isPlainObject(instOpts.store)) {
  				local.store = instOpts.store;
  			} else if (instOpts.store === "cookie") {
  				local.store = cookieStore;
  			} else if (instOpts.store === "local") {
  				local.store =
  					instOpts.store === "local"
  						? localStorageStore
  						: sessionStorageStore;
  			} else if (instOpts.store === "session") {
  				local.store =
  					instOpts.store === "local"
  						? localStorageStore
  						: sessionStorageStore;
  			}
  			_assert(local.store, "Need a valid store.");
  
  			// Bind init-handler to apply cookie state
  			tree.$div.on("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 < keyList.length; i++) {
  								node = tree.getNodeByKey(keyList[i]);
  								if (node) {
  									if (
  										node.selected === undefined ||
  										(instOpts.overrideSource &&
  											node.selected === false)
  									) {
  										//									node.setSelected();
  										node.selected = true;
  										node.renderStatus();
  									}
  								} else {
  									// node is no longer member of the tree: remove from cookie also
  									local._appendKey(
  										SELECTED,
  										keyList[i],
  										false
  									);
  								}
  							}
  						}
  						// In selectMode 3 we have to fix the child nodes, since we
  						// only stored the selected *top* nodes
  						if (tree.options.selectMode === 3) {
  							tree.visit(function(n) {
  								if (n.selected) {
  									n.fixSelection3AfterClick();
  									return "skip";
  								}
  							});
  						}
  					}
  					if (local.storeActive) {
  						cookie = local._data(local.cookiePrefix + ACTIVE);
  						if (
  							cookie &&
  							(opts.persist.overrideSource || !tree.activeNode)
  						) {
  							node = tree.getNodeByKey(cookie);
  							if (node) {
  								node.debug("persist: set active", cookie);
  								// We only want to set the focus if the container
  								// had the keyboard focus before
  								node.setActive(true, {
  									noFocus: true,
  									noEvents: noEvents,
  								});
  							}
  						}
  					}
  					if (local.storeFocus && prevFocus) {
  						node = tree.getNodeByKey(prevFocus);
  						if (node) {
  							// node.debug("persist: set focus", cookie);
  							if (tree.options.titlesTabbable) {
  								$(node.span)
  									.find(".fancytree-title")
  									.focus();
  							} else {
  								$(tree.$container).focus();
  							}
  							// node.setFocus();
  						}
  					}
  					tree._triggerTreeEvent("restore", null, {});
  				});
  			});
  			// Init the tree
  			return this._superApply(arguments);
  		},
  		nodeSetActive: function(ctx, flag, callOpts) {
  			var res,
  				local = this._local;
  
  			flag = flag !== false;
  			res = this._superApply(arguments);
  
  			if (local.storeActive) {
  				local._data(
  					local.cookiePrefix + ACTIVE,
  					this.activeNode ? this.activeNode.key : null
  				);
  			}
  			return res;
  		},
  		nodeSetExpanded: function(ctx, flag, callOpts) {
  			var res,
  				node = ctx.node,
  				local = this._local;
  
  			flag = flag !== false;
  			res = this._superApply(arguments);
  
  			if (local.storeExpanded) {
  				local._appendKey(EXPANDED, node.key, flag);
  			}
  			return res;
  		},
  		nodeSetFocus: function(ctx, flag) {
  			var res,
  				local = this._local;
  
  			flag = flag !== false;
  			res = this._superApply(arguments);
  
  			if (local.storeFocus) {
  				local._data(
  					local.cookiePrefix + FOCUS,
  					this.focusNode ? this.focusNode.key : null
  				);
  			}
  			return res;
  		},
  		nodeSetSelected: function(ctx, flag, callOpts) {
  			var res,
  				selNodes,
  				tree = ctx.tree,
  				node = ctx.node,
  				local = this._local;
  
  			flag = flag !== false;
  			res = this._superApply(arguments);
  
  			if (local.storeSelected) {
  				if (tree.options.selectMode === 3) {
  					// In selectMode 3 we only store the the selected *top* nodes.
  					// De-selecting a node may also de-select some parents, so we
  					// calculate the current status again
  					selNodes = $.map(tree.getSelectedNodes(true), function(n) {
  						return n.key;
  					});
  					selNodes = selNodes.join(
  						ctx.options.persist.cookieDelimiter
  					);
  					local._data(local.cookiePrefix + SELECTED, selNodes);
  				} else {
  					// beforeSelect can prevent the change - flag doesn't reflect the node.selected state
  					local._appendKey(SELECTED, node.key, node.selected);
  				}
  			}
  			return res;
  		},
  	});
  	// Value returned by `require('jquery.fancytree..')`
  	return $.ui.fancytree;
  }); // End of closure
  