Fixed FELIX-2254 User Admin Plugin
https://issues.apache.org/jira/browse/FELIX-2254

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1375745 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole-plugins/useradmin/pom.xml b/webconsole-plugins/useradmin/pom.xml
new file mode 100644
index 0000000..f1e5644
--- /dev/null
+++ b/webconsole-plugins/useradmin/pom.xml
@@ -0,0 +1,109 @@
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
+    license agreements. See the NOTICE file distributed with this work for additional 
+    information regarding copyright ownership. The ASF licenses this file to 
+    you under the Apache License, Version 2.0 (the "License"); you may not use 
+    this file except in compliance with the License. You may obtain a copy of 
+    the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required 
+    by applicable law or agreed to in writing, software distributed under the 
+    License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
+    OF ANY KIND, either express or implied. See the License for the specific 
+    language governing permissions and limitations under the License. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>felix-parent</artifactId>
+        <version>2.1</version>
+        <relativePath>../../../pom/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.felix.webconsole.plugins.useradmin</artifactId>
+    <packaging>bundle</packaging>
+    <version>0.0.1-SNAPSHOT</version>
+
+    <name>Apache Felix Web Console User Admin Plugin</name>
+    <description>
+        This is a plugin for the Apache Felix OSGi web console for displaying/managing OSGi Users and Groups.
+    </description>
+
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/felix/trunk/webconsole-plugins/useradmin</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/felix/trunk/webconsole-plugins/useradmin</developerConnection>
+        <url>http://svn.apache.org/viewvc/felix/trunk/webconsole-plugins/useradmin</url>
+    </scm>
+
+    <build>
+        <plugins>
+            <!-- translate UTF-8 encoded properties files to ISO-8859-1 -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>native2ascii-maven-plugin</artifactId>
+                <version>1.0-beta-1</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>native2ascii</goal>
+                        </goals>
+                        <configuration>
+                            <encoding>UTF-8</encoding>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <version>2.3.4</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Bundle-SymbolicName>
+                            ${project.artifactId}
+                        </Bundle-SymbolicName>
+                        <Bundle-Activator>
+                            org.apache.felix.webconsole.plugins.useradmin.internal.Activator
+                        </Bundle-Activator>
+                        <Include-Resource>
+                            {maven-resources},OSGI-INF=target/classes/OSGI-INF
+                        </Include-Resource>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.4</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <version>4.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <version>4.1.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.webconsole</artifactId>
+            <version>4.0.1-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+            <version>20070829</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/webconsole-plugins/useradmin/src/main/appended-resources/META-INF/DEPENDENCIES b/webconsole-plugins/useradmin/src/main/appended-resources/META-INF/DEPENDENCIES
new file mode 100644
index 0000000..7173c8d
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/appended-resources/META-INF/DEPENDENCIES
@@ -0,0 +1,29 @@
+
+I. Included Software
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+
+II. Used Software
+
+This product uses software developed at
+jsTree (http://jstree.com/).
+Copyright (c) 2009 Ivan Bozhanov (vakata.com)
+Licensed under The MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+This product uses software developed at
+CryptoJS (http://code.google.com/p/crypto-js/).
+Copyright © 2009–2012 by Jeff Mott. All rights reserved.
+Licensed under New BSD License
+
+This product uses software developed at
+JSON.js (https://github.com/douglascrockford/JSON-js).
+Available as Public Domain code
+
+III. License Summary
+- Apache License 2.0
+- The MIT License
+- New BSD License
+- Public Domain
diff --git a/webconsole-plugins/useradmin/src/main/java/org/apache/felix/webconsole/plugins/useradmin/internal/Activator.java b/webconsole-plugins/useradmin/src/main/java/org/apache/felix/webconsole/plugins/useradmin/internal/Activator.java
new file mode 100644
index 0000000..4428428
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/java/org/apache/felix/webconsole/plugins/useradmin/internal/Activator.java
@@ -0,0 +1,111 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one or more

+ * contributor license agreements.  See the NOTICE file distributed with

+ * this work for additional information regarding copyright ownership.

+ * The ASF licenses this file to You under the Apache License, Version 2.0

+ * (the "License"); you may not use this file except in compliance with

+ * the License.  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+package org.apache.felix.webconsole.plugins.useradmin.internal;

+

+import org.apache.felix.webconsole.SimpleWebConsolePlugin;

+import org.osgi.framework.BundleActivator;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.ServiceReference;

+import org.osgi.framework.ServiceRegistration;

+import org.osgi.service.useradmin.UserAdmin;

+import org.osgi.util.tracker.ServiceTracker;

+import org.osgi.util.tracker.ServiceTrackerCustomizer;

+

+/**

+ * Activator is the main starting class.

+ */

+public class Activator implements BundleActivator, ServiceTrackerCustomizer

+{

+

+    private ServiceTracker tracker;

+    private BundleContext context;

+

+    private SimpleWebConsolePlugin plugin;

+    private ServiceRegistration printerRegistration;

+

+    /**

+     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)

+     */

+    public final void start(BundleContext context) throws Exception

+    {

+        this.context = context;

+        this.tracker = new ServiceTracker(context, UserAdmin.class.getName(), this);

+        this.tracker.open();

+    }

+

+    /**

+     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)

+     */

+    public final void stop(BundleContext context) throws Exception

+    {

+        if (tracker != null)

+        {

+            tracker.close();

+            tracker = null;

+        }

+    }

+

+    // - begin tracker

+    /**

+     * @see org.osgi.util.tracker.ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference,

+     *      java.lang.Object)

+     */

+    public final void modifiedService(ServiceReference reference, Object service)

+    {/* unused */

+    }

+

+    /**

+     * @see org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference)

+     */

+    public final Object addingService(ServiceReference reference)

+    {

+        SimpleWebConsolePlugin plugin = this.plugin;

+        if (plugin == null)

+        {

+            final UserAdmin service = (UserAdmin) context.getService(reference);

+            this.plugin = new WebConsolePlugin(service).register(context);

+            //            printerRegistration = context.registerService(ConfigurationPrinter.SERVICE,

+            //                new ComponentConfigurationPrinter(service), null);

+        }

+

+        return context.getService(reference);

+    }

+

+    /**

+     * @see org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference,

+     *      java.lang.Object)

+     */

+    public final void removedService(ServiceReference reference, Object service)

+    {

+        SimpleWebConsolePlugin plugin = this.plugin;

+

+        if (tracker.size() <= 1 && plugin != null)

+        {

+            // remove service

+            plugin.unregister();

+            this.plugin = null;

+            // unregister configuration printer too

+            ServiceRegistration reg = printerRegistration;

+            if (reg != null)

+            {

+                reg.unregister();

+                printerRegistration = null;

+            }

+        }

+

+    }

+}

diff --git a/webconsole-plugins/useradmin/src/main/java/org/apache/felix/webconsole/plugins/useradmin/internal/WebConsolePlugin.java b/webconsole-plugins/useradmin/src/main/java/org/apache/felix/webconsole/plugins/useradmin/internal/WebConsolePlugin.java
new file mode 100644
index 0000000..1e4bc2d
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/java/org/apache/felix/webconsole/plugins/useradmin/internal/WebConsolePlugin.java
@@ -0,0 +1,263 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one or more

+ * contributor license agreements.  See the NOTICE file distributed with

+ * this work for additional information regarding copyright ownership.

+ * The ASF licenses this file to You under the Apache License, Version 2.0

+ * (the "License"); you may not use this file except in compliance with

+ * the License.  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+package org.apache.felix.webconsole.plugins.useradmin.internal;

+

+import java.io.IOException;

+import java.io.PrintWriter;

+import java.util.Dictionary;

+import java.util.Enumeration;

+import java.util.Iterator;

+

+import javax.servlet.ServletException;

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.apache.felix.webconsole.SimpleWebConsolePlugin;

+import org.json.JSONArray;

+import org.json.JSONException;

+import org.json.JSONObject;

+import org.json.JSONWriter;

+import org.osgi.service.useradmin.Group;

+import org.osgi.service.useradmin.Role;

+import org.osgi.service.useradmin.User;

+import org.osgi.service.useradmin.UserAdmin;

+

+class WebConsolePlugin extends SimpleWebConsolePlugin

+{

+    private static final long serialVersionUID = -3551087958597824593L;

+

+    private static final String LABEL = "users"; //$NON-NLS-1$

+    private static final String TITLE = "%role.pluginTitle"; //$NON-NLS-1$

+    private static final String CSS[] = { "/" + LABEL + "/res/plugin.css" }; //$NON-NLS-1$ //$NON-NLS-2$

+

+    private final UserAdmin userAdmin;

+

+    // templates

+    private final String TEMPLATE;

+

+    /** Default constructor */

+    WebConsolePlugin(UserAdmin userAdmin)

+    {

+        super(LABEL, TITLE, CSS);

+        this.userAdmin = userAdmin;

+

+        // load templates

+        TEMPLATE = readTemplateFile("/res/plugin.html"); //$NON-NLS-1$

+    }

+

+    /**

+     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#renderContent(HttpServletRequest, HttpServletResponse)

+     */

+    protected final void renderContent(HttpServletRequest req,

+        HttpServletResponse response) throws ServletException, IOException

+    {

+        response.getWriter().print(TEMPLATE);

+    }

+

+    protected void doPost(HttpServletRequest req, HttpServletResponse resp)

+        throws ServletException, IOException

+    {

+

+        resp.setContentType("application/json"); //$NON-NLS-1$

+        resp.setCharacterEncoding("UTF-8"); //$NON-NLS-1$

+        final PrintWriter out = resp.getWriter();

+        final JSONWriter jw = new JSONWriter(out);

+        final String action = req.getParameter("action"); //$NON-NLS-1$

+

+        final String role = req.getParameter("role"); //$NON-NLS-1$

+        final String group = req.getParameter("group"); //$NON-NLS-1$

+

+        try

+        {

+            if ("addMember".equals(action)) { //$NON-NLS-1$

+                final Role xrole = userAdmin.getRole(role);

+                final Group xgroup = (Group) userAdmin.getRole(group);

+                xgroup.addMember(xrole);

+                toJSON(jw, xgroup, false);

+            }

+            else if ("addRequiredMember".equals(action)) { //$NON-NLS-1$

+                final Role xrole = userAdmin.getRole(role);

+                final Group xgroup = (Group) userAdmin.getRole(group);

+                xgroup.addRequiredMember(xrole);

+                toJSON(jw, xgroup, false);

+            }

+            else if ("removeMember".equals(action)) { //$NON-NLS-1$

+                final Role xrole = userAdmin.getRole(role);

+                final Group xgroup = (Group) userAdmin.getRole(group);

+                xgroup.removeMember(xrole);

+                toJSON(jw, xgroup, false);

+            }

+            else if ("del".equals(action)) { //$NON-NLS-1$

+                out.print(userAdmin.removeRole(role));

+            }

+            else if ("get".equals(action)) { //$NON-NLS-1$

+                final Role xrole = userAdmin.getRole(role);

+                toJSON(jw, xrole, true);

+            }

+            else if ("set".equals(action)) { //$NON-NLS-1$

+                final String dataRaw = req.getParameter("data"); //$NON-NLS-1$

+                final JSONObject data = new JSONObject(dataRaw);

+                Role xrole = userAdmin.getRole(data.getString("name")); //$NON-NLS-1$

+                if (null == xrole)

+                {

+                    xrole = userAdmin.createRole(//

+                        data.getString("name"), //$NON-NLS-1$

+                        data.getInt("type")); //$NON-NLS-1$

+                }

+                doSetData(xrole, data);

+                out.print(true);

+            }

+            else

+            // list all roles without details

+            {

+

+                Role[] roles = userAdmin.getRoles(null);

+                toJSON(jw, roles, false);

+            }

+        }

+        catch (Exception e)

+        {

+            throw new ServletException(e);

+        }

+    }

+

+    private static final void doSetData(Role role, JSONObject data) throws JSONException

+    {

+        putProps(role.getProperties(), data.optJSONObject("properties")); //$NON-NLS-1$

+        if (role instanceof User)

+        {

+            putProps(((User) role).getCredentials(), data.optJSONObject("credentials")); //$NON-NLS-1$

+        }

+    }

+

+    private static final void putProps(Dictionary dest, JSONObject props)

+        throws JSONException

+    {

+        // clear the old properties

+        if (!dest.isEmpty())

+        {

+            for (Enumeration e = dest.keys(); e.hasMoreElements();)

+            {

+                dest.remove(e.nextElement());

+            }

+        }

+        // it's empty - don't process it at all

+        if (props == null || props.length() == 0)

+        {

+            return;

+        }

+        // append the new one

+        for (Iterator i = props.keys(); i.hasNext();)

+        {

+            Object key = i.next();

+            Object val = props.get((String) key);

+

+            if (val instanceof JSONArray)

+            {

+                val = toArray((JSONArray) val);

+            }

+            dest.put(key, val);

+        }

+    }

+

+    private static final byte[] toArray(JSONArray array) throws JSONException

+    {

+        final byte[] ret = new byte[array.length()];

+        for (int i = 0; i < ret.length; i++)

+        {

+            ret[i] = (byte) (array.getInt(i) & 0xff);

+        }

+        return ret;

+    }

+

+    private static final void toJSON(JSONWriter jw, Role role, boolean details)

+        throws JSONException

+    {

+        jw.object();

+        jw.key("type"); //$NON-NLS-1$

+        jw.value(role.getType());

+        jw.key("name"); //$NON-NLS-1$

+        jw.value(role.getName());

+

+        if (role instanceof Group)

+        {

+            final Group group = (Group) role;

+            Role[] roles;

+

+            roles = group.getMembers();

+            if (null != roles && roles.length > 0)

+            {

+                jw.key("members"); //$NON-NLS-1$

+                toJSON(jw, roles, details);

+            }

+

+            roles = group.getRequiredMembers();

+            if (null != roles && roles.length > 0)

+            {

+                jw.key("rmembers"); //$NON-NLS-1$

+                toJSON(jw, roles, details);

+            }

+        }

+

+        if (details)

+        {

+            Dictionary p;

+            p = role.getProperties();

+            if (null != p && !p.isEmpty())

+            {

+                jw.key("properties"); //$NON-NLS-1$

+                toJSON(jw, p);

+            }

+            if (role instanceof User)

+            {

+                p = ((User) role).getCredentials();

+                if (null != p && !p.isEmpty())

+                {

+                    jw.key("credentials"); //$NON-NLS-1$

+                    toJSON(jw, p);

+                }

+            }

+        }

+

+        jw.endObject();

+    }

+

+    private static final void toJSON(JSONWriter jw, Dictionary props)

+        throws JSONException

+    {

+        jw.object();

+        for (Enumeration e = props.keys(); e.hasMoreElements();)

+        {

+            final Object key = e.nextElement();

+            final Object val = props.get(key);

+            jw.key((String) key);

+            jw.value(val);

+        }

+        jw.endObject();

+    }

+

+    private static final void toJSON(JSONWriter jw, Role[] roles, boolean details)

+        throws JSONException

+    {

+        jw.array();

+        for (int i = 0; roles != null && i < roles.length; i++)

+        {

+            toJSON(jw, roles[i], details);

+        }

+        jw.endArray();

+    }

+}

diff --git a/webconsole-plugins/useradmin/src/main/resources/OSGI-INF/l10n/bundle.properties b/webconsole-plugins/useradmin/src/main/resources/OSGI-INF/l10n/bundle.properties
new file mode 100644
index 0000000..62fe008
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/OSGI-INF/l10n/bundle.properties
@@ -0,0 +1,54 @@
+#Licensed to the Apache Software Foundation (ASF) under one or more

+# contributor license agreements.  See the NOTICE file distributed with

+# this work for additional information regarding copyright ownership.

+# The ASF licenses this file to You under the Apache License, Version 2.0

+# (the "License"); you may not use this file except in compliance with

+# the License.  You may obtain a copy of the License at

+#

+#      http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing, software

+# distributed under the License is distributed on an "AS IS" BASIS,

+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+# See the License for the specific language governing permissions and

+# limitations under the License.

+

+#

+# Web Console strings for reference all strings here are commented.

+# This file may be used to produce a translation of the strings

+#

+# Note that properties files are ISO-8859-1 encoded. To provide translations

+# for languages requiring different character encodings, you may use the

+# native2ascii Maven Plugin from http://mojo.codehaus.org/native2ascii-maven-plugin/

+# to translate the natively encoded files to ISO-8859-1 during bundle build

+#

+# Translations requiring non-ISO-8859-1 encoding are placed in the

+# src/main/native2ascii/OSGI-INF/l10n folder and are converted using said

+# plugin while building the bundle

+#

+role.pluginTitle=Users

+role.tree.root=Users and Groups

+role.new=New Role

+role.key=Key

+role.value=Value

+role.properties=Properties

+role.credentials=Credentials

+role.new.title=New role

+role.name=Name

+role.type.1=User

+role.type.2=Group

+type.string=String

+type.bytes=Byte[]

+type.password-MD5=Password Hash (MD5)

+type.password-SHA1=Password Hash (SHA-1)

+type.password-SHA256=Password Hash (SHA256)

+type.password-SHA512=Password Hash (SHA512)

+role.statline=There are {1} user(s) and {2} role(s) arranged in {0} groups.

+role.help.initial=\

+- Select a role on the left side to open it and edit it's properties and credentials<br/>\

+- You can drag groups, roles and users in the tree to arrange them and declare membership<br/>\

+- While dragging, hold Ctrl button to copy, instead of move<br/>\

+- To remove a role from a group - drag it to the root node<br/>\

+- The roles which are in <i>italic</i> are 'required' members of the current group<br/>\

+- To toggle a role from required to basic membership (and vice-versa), double click on it

+

diff --git a/webconsole-plugins/useradmin/src/main/resources/OSGI-INF/l10n/bundle_bg.properties b/webconsole-plugins/useradmin/src/main/resources/OSGI-INF/l10n/bundle_bg.properties
new file mode 100644
index 0000000..746887b
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/OSGI-INF/l10n/bundle_bg.properties
@@ -0,0 +1,54 @@
+#Licensed to the Apache Software Foundation (ASF) under one or more

+# contributor license agreements.  See the NOTICE file distributed with

+# this work for additional information regarding copyright ownership.

+# The ASF licenses this file to You under the Apache License, Version 2.0

+# (the "License"); you may not use this file except in compliance with

+# the License.  You may obtain a copy of the License at

+#

+#      http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing, software

+# distributed under the License is distributed on an "AS IS" BASIS,

+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+# See the License for the specific language governing permissions and

+# limitations under the License.

+

+#

+# Web Console strings for reference all strings here are commented.

+# This file may be used to produce a translation of the strings

+#

+# Note that properties files are ISO-8859-1 encoded. To provide translations

+# for languages requiring different character encodings, you may use the

+# native2ascii Maven Plugin from http://mojo.codehaus.org/native2ascii-maven-plugin/

+# to translate the natively encoded files to ISO-8859-1 during bundle build

+#

+# Translations requiring non-ISO-8859-1 encoding are placed in the

+# src/main/native2ascii/OSGI-INF/l10n folder and are converted using said

+# plugin while building the bundle

+#

+role.pluginTitle=Потребители

+role.tree.root=Групи и потребители

+role.new=Нова роля

+role.key=Ключ

+role.value=Стойност

+role.properties=Атрибути

+role.credentials=Акредитиви

+role.new.title=Създаване на нова роля

+role.name=Име

+role.type.1=Потребител

+role.type.2=Група

+type.string=Низ

+type.bytes=Данни

+type.password-MD5=Парола (MD5)

+type.password-SHA1=Парола (SHA-1)

+type.password-SHA256=Парола (SHA256)

+type.password-SHA512=Парола (SHA512)

+role.statline=Има {1} потребител(я) и {2} роли организирани в {0} групи.

+role.help.initial=\

+- Изберете роля от ляво, за да я отворите и промените нейните атрибути<br/>\

+- Можете да завлачвате с мишката ролите за да ги аранжирате. По този начин декларирате тяхното членство в определена група<br/>\

+- Ако при завлачването натиснете клавиша Ctrl, ще копирате избраната роля, вместо да я преместите<br/>\

+- За да премахнете роля от група - завлачете я в основата на дървото<br/>\

+- Ролите, които са в <i>курсив</i> са задължителни членове на групата<br/>\

+- За да направите роля задължителна за групата, (или обикновена) кликнете двойно върху нея

+

diff --git a/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/core-min.js b/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/core-min.js
new file mode 100644
index 0000000..65e57cc
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/core-min.js
@@ -0,0 +1,12 @@
+/*
+CryptoJS v3.0.2
+code.google.com/p/crypto-js
+(c) 2009-2012 by Jeff Mott. All rights reserved.
+code.google.com/p/crypto-js/wiki/License
+*/
+var CryptoJS=CryptoJS||function(h,o){var f={},j=f.lib={},k=j.Base=function(){function a(){}return{extend:function(b){a.prototype=this;var c=new a;b&&c.mixIn(b);c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.$super.extend(this)}}}(),i=j.WordArray=k.extend({init:function(a,b){a=
+this.words=a||[];this.sigBytes=b!=o?b:4*a.length},toString:function(a){return(a||p).stringify(this)},concat:function(a){var b=this.words,c=a.words,d=this.sigBytes,a=a.sigBytes;this.clamp();if(d%4)for(var e=0;e<a;e++)b[d+e>>>2]|=(c[e>>>2]>>>24-8*(e%4)&255)<<24-8*((d+e)%4);else if(65535<c.length)for(e=0;e<a;e+=4)b[d+e>>>2]=c[e>>>2];else b.push.apply(b,c);this.sigBytes+=a;return this},clamp:function(){var a=this.words,b=this.sigBytes;a[b>>>2]&=4294967295<<32-8*(b%4);a.length=h.ceil(b/4)},clone:function(){var a=
+k.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var b=[],c=0;c<a;c+=4)b.push(4294967296*h.random()|0);return i.create(b,a)}}),l=f.enc={},p=l.Hex={stringify:function(a){for(var b=a.words,a=a.sigBytes,c=[],d=0;d<a;d++){var e=b[d>>>2]>>>24-8*(d%4)&255;c.push((e>>>4).toString(16));c.push((e&15).toString(16))}return c.join("")},parse:function(a){for(var b=a.length,c=[],d=0;d<b;d+=2)c[d>>>3]|=parseInt(a.substr(d,2),16)<<24-4*(d%8);return i.create(c,b/2)}},n=l.Latin1={stringify:function(a){for(var b=
+a.words,a=a.sigBytes,c=[],d=0;d<a;d++)c.push(String.fromCharCode(b[d>>>2]>>>24-8*(d%4)&255));return c.join("")},parse:function(a){for(var b=a.length,c=[],d=0;d<b;d++)c[d>>>2]|=(a.charCodeAt(d)&255)<<24-8*(d%4);return i.create(c,b)}},q=l.Utf8={stringify:function(a){try{return decodeURIComponent(escape(n.stringify(a)))}catch(b){throw Error("Malformed UTF-8 data");}},parse:function(a){return n.parse(unescape(encodeURIComponent(a)))}},m=j.BufferedBlockAlgorithm=k.extend({reset:function(){this._data=i.create();
+this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=q.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var b=this._data,c=b.words,d=b.sigBytes,e=this.blockSize,f=d/(4*e),f=a?h.ceil(f):h.max((f|0)-this._minBufferSize,0),a=f*e,d=h.min(4*a,d);if(a){for(var g=0;g<a;g+=e)this._doProcessBlock(c,g);g=c.splice(0,a);b.sigBytes-=d}return i.create(g,d)},clone:function(){var a=k.clone.call(this);a._data=this._data.clone();return a},_minBufferSize:0});j.Hasher=m.extend({init:function(){this.reset()},
+reset:function(){m.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);this._doFinalize();return this._hash},clone:function(){var a=m.clone.call(this);a._hash=this._hash.clone();return a},blockSize:16,_createHelper:function(a){return function(b,c){return a.create(c).finalize(b)}},_createHmacHelper:function(a){return function(b,c){return r.HMAC.create(a,c).finalize(b)}}});var r=f.algo={};return f}(Math);
diff --git a/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/license.txt b/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/license.txt
new file mode 100644
index 0000000..6f4eaa6
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/license.txt
@@ -0,0 +1,9 @@
+© 2009–2012 by Jeff Mott. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+    Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer.
+    Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation or other materials provided with the distribution.
+    Neither the name CryptoJS nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS," AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/md5-min.js b/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/md5-min.js
new file mode 100644
index 0000000..59ba77c
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/md5-min.js
@@ -0,0 +1,10 @@
+/*
+CryptoJS v3.0.2
+code.google.com/p/crypto-js
+(c) 2009-2012 by Jeff Mott. All rights reserved.
+code.google.com/p/crypto-js/wiki/License
+*/
+(function(q){function k(b,c,a,f,d,e,g){b=b+(c&a|~c&f)+d+g;return(b<<e|b>>>32-e)+c}function l(b,c,a,f,d,e,g){b=b+(c&f|a&~f)+d+g;return(b<<e|b>>>32-e)+c}function m(b,c,a,f,d,e,g){b=b+(c^a^f)+d+g;return(b<<e|b>>>32-e)+c}function n(b,c,a,f,d,e,g){b=b+(a^(c|~f))+d+g;return(b<<e|b>>>32-e)+c}var o=CryptoJS,j=o.lib,r=j.WordArray,j=j.Hasher,p=o.algo,i=[];(function(){for(var b=0;64>b;b++)i[b]=4294967296*q.abs(q.sin(b+1))|0})();p=p.MD5=j.extend({_doReset:function(){this._hash=r.create([1732584193,4023233417,
+2562383102,271733878])},_doProcessBlock:function(b,c){for(var a=0;16>a;a++){var f=c+a,d=b[f];b[f]=(d<<8|d>>>24)&16711935|(d<<24|d>>>8)&4278255360}for(var f=this._hash.words,d=f[0],e=f[1],g=f[2],h=f[3],a=0;64>a;a+=4)16>a?(d=k(d,e,g,h,b[c+a],7,i[a]),h=k(h,d,e,g,b[c+a+1],12,i[a+1]),g=k(g,h,d,e,b[c+a+2],17,i[a+2]),e=k(e,g,h,d,b[c+a+3],22,i[a+3])):32>a?(d=l(d,e,g,h,b[c+(a+1)%16],5,i[a]),h=l(h,d,e,g,b[c+(a+6)%16],9,i[a+1]),g=l(g,h,d,e,b[c+(a+11)%16],14,i[a+2]),e=l(e,g,h,d,b[c+a%16],20,i[a+3])):48>a?(d=
+m(d,e,g,h,b[c+(3*a+5)%16],4,i[a]),h=m(h,d,e,g,b[c+(3*a+8)%16],11,i[a+1]),g=m(g,h,d,e,b[c+(3*a+11)%16],16,i[a+2]),e=m(e,g,h,d,b[c+(3*a+14)%16],23,i[a+3])):(d=n(d,e,g,h,b[c+3*a%16],6,i[a]),h=n(h,d,e,g,b[c+(3*a+7)%16],10,i[a+1]),g=n(g,h,d,e,b[c+(3*a+14)%16],15,i[a+2]),e=n(e,g,h,d,b[c+(3*a+5)%16],21,i[a+3]));f[0]=f[0]+d|0;f[1]=f[1]+e|0;f[2]=f[2]+g|0;f[3]=f[3]+h|0},_doFinalize:function(){var b=this._data,c=b.words,a=8*this._nDataBytes,f=8*b.sigBytes;c[f>>>5]|=128<<24-f%32;c[(f+64>>>9<<4)+14]=(a<<8|a>>>
+24)&16711935|(a<<24|a>>>8)&4278255360;b.sigBytes=4*(c.length+1);this._process();b=this._hash.words;for(c=0;4>c;c++)a=b[c],b[c]=(a<<8|a>>>24)&16711935|(a<<24|a>>>8)&4278255360}});o.MD5=j._createHelper(p);o.HmacMD5=j._createHmacHelper(p)})(Math);
diff --git a/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/sha1-min.js b/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/sha1-min.js
new file mode 100644
index 0000000..21ac562
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/sha1-min.js
@@ -0,0 +1,8 @@
+/*
+CryptoJS v3.0.2
+code.google.com/p/crypto-js
+(c) 2009-2012 by Jeff Mott. All rights reserved.
+code.google.com/p/crypto-js/wiki/License
+*/
+(function(){var d=CryptoJS,c=d.lib,l=c.WordArray,c=c.Hasher,j=[],k=d.algo.SHA1=c.extend({_doReset:function(){this._hash=l.create([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(c,m){for(var a=this._hash.words,e=a[0],f=a[1],h=a[2],i=a[3],d=a[4],b=0;80>b;b++){if(16>b)j[b]=c[m+b]|0;else{var g=j[b-3]^j[b-8]^j[b-14]^j[b-16];j[b]=g<<1|g>>>31}g=(e<<5|e>>>27)+d+j[b];g=20>b?g+((f&h|~f&i)+1518500249):40>b?g+((f^h^i)+1859775393):60>b?g+((f&h|f&i|h&i)-1894007588):g+((f^h^i)-
+899497514);d=i;i=h;h=f<<30|f>>>2;f=e;e=g}a[0]=a[0]+e|0;a[1]=a[1]+f|0;a[2]=a[2]+h|0;a[3]=a[3]+i|0;a[4]=a[4]+d|0},_doFinalize:function(){var d=this._data,c=d.words,a=8*this._nDataBytes,e=8*d.sigBytes;c[e>>>5]|=128<<24-e%32;c[(e+64>>>9<<4)+15]=a;d.sigBytes=4*c.length;this._process()}});d.SHA1=c._createHelper(k);d.HmacSHA1=c._createHmacHelper(k)})();
diff --git a/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/sha256-min.js b/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/sha256-min.js
new file mode 100644
index 0000000..fd9dc42
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/sha256-min.js
@@ -0,0 +1,9 @@
+/*
+CryptoJS v3.0.2
+code.google.com/p/crypto-js
+(c) 2009-2012 by Jeff Mott. All rights reserved.
+code.google.com/p/crypto-js/wiki/License
+*/
+(function(k){var h=CryptoJS,i=h.lib,r=i.WordArray,i=i.Hasher,c=h.algo,p=[],q=[];(function(){function g(a){for(var b=k.sqrt(a),d=2;d<=b;d++)if(!(a%d))return!1;return!0}function d(a){return 4294967296*(a-(a|0))|0}for(var a=2,b=0;64>b;)g(a)&&(8>b&&(p[b]=d(k.pow(a,0.5))),q[b]=d(k.pow(a,1/3)),b++),a++})();var g=[],c=c.SHA256=i.extend({_doReset:function(){this._hash=r.create(p.slice(0))},_doProcessBlock:function(i,d){for(var a=this._hash.words,b=a[0],m=a[1],n=a[2],h=a[3],f=a[4],c=a[5],o=a[6],k=a[7],e=0;64>
+e;e++){if(16>e)g[e]=i[d+e]|0;else{var j=g[e-15],l=g[e-2];g[e]=((j<<25|j>>>7)^(j<<14|j>>>18)^j>>>3)+g[e-7]+((l<<15|l>>>17)^(l<<13|l>>>19)^l>>>10)+g[e-16]}j=k+((f<<26|f>>>6)^(f<<21|f>>>11)^(f<<7|f>>>25))+(f&c^~f&o)+q[e]+g[e];l=((b<<30|b>>>2)^(b<<19|b>>>13)^(b<<10|b>>>22))+(b&m^b&n^m&n);k=o;o=c;c=f;f=h+j|0;h=n;n=m;m=b;b=j+l|0}a[0]=a[0]+b|0;a[1]=a[1]+m|0;a[2]=a[2]+n|0;a[3]=a[3]+h|0;a[4]=a[4]+f|0;a[5]=a[5]+c|0;a[6]=a[6]+o|0;a[7]=a[7]+k|0},_doFinalize:function(){var c=this._data,d=c.words,a=8*this._nDataBytes,
+b=8*c.sigBytes;d[b>>>5]|=128<<24-b%32;d[(b+64>>>9<<4)+15]=a;c.sigBytes=4*d.length;this._process()}});h.SHA256=i._createHelper(c);h.HmacSHA256=i._createHmacHelper(c)})(Math);
diff --git a/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/sha512-min.js b/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/sha512-min.js
new file mode 100644
index 0000000..dcb8ad8
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/sha512-min.js
@@ -0,0 +1,15 @@
+/*
+CryptoJS v3.0.2
+code.google.com/p/crypto-js
+(c) 2009-2012 by Jeff Mott. All rights reserved.
+code.google.com/p/crypto-js/wiki/License
+*/
+(function(){function a(){return v.create.apply(v,arguments)}var d=CryptoJS,r=d.lib.Hasher,e=d.x64,v=e.Word,S=e.WordArray,e=d.algo,da=[a(1116352408,3609767458),a(1899447441,602891725),a(3049323471,3964484399),a(3921009573,2173295548),a(961987163,4081628472),a(1508970993,3053834265),a(2453635748,2937671579),a(2870763221,3664609560),a(3624381080,2734883394),a(310598401,1164996542),a(607225278,1323610764),a(1426881987,3590304994),a(1925078388,4068182383),a(2162078206,991336113),a(2614888103,633803317),
+a(3248222580,3479774868),a(3835390401,2666613458),a(4022224774,944711139),a(264347078,2341262773),a(604807628,2007800933),a(770255983,1495990901),a(1249150122,1856431235),a(1555081692,3175218132),a(1996064986,2198950837),a(2554220882,3999719339),a(2821834349,766784016),a(2952996808,2566594879),a(3210313671,3203337956),a(3336571891,1034457026),a(3584528711,2466948901),a(113926993,3758326383),a(338241895,168717936),a(666307205,1188179964),a(773529912,1546045734),a(1294757372,1522805485),a(1396182291,
+2643833823),a(1695183700,2343527390),a(1986661051,1014477480),a(2177026350,1206759142),a(2456956037,344077627),a(2730485921,1290863460),a(2820302411,3158454273),a(3259730800,3505952657),a(3345764771,106217008),a(3516065817,3606008344),a(3600352804,1432725776),a(4094571909,1467031594),a(275423344,851169720),a(430227734,3100823752),a(506948616,1363258195),a(659060556,3750685593),a(883997877,3785050280),a(958139571,3318307427),a(1322822218,3812723403),a(1537002063,2003034995),a(1747873779,3602036899),
+a(1955562222,1575990012),a(2024104815,1125592928),a(2227730452,2716904306),a(2361852424,442776044),a(2428436474,593698344),a(2756734187,3733110249),a(3204031479,2999351573),a(3329325298,3815920427),a(3391569614,3928383900),a(3515267271,566280711),a(3940187606,3454069534),a(4118630271,4000239992),a(116418474,1914138554),a(174292421,2731055270),a(289380356,3203993006),a(460393269,320620315),a(685471733,587496836),a(852142971,1086792851),a(1017036298,365543100),a(1126000580,2618297676),a(1288033470,
+3409855158),a(1501505948,4234509866),a(1607167915,987167468),a(1816402316,1246189591)],s=[];(function(){for(var T=0;80>T;T++)s[T]=a()})();e=e.SHA512=r.extend({_doReset:function(){this._hash=S.create([a(1779033703,4089235720),a(3144134277,2227873595),a(1013904242,4271175723),a(2773480762,1595750129),a(1359893119,2917565137),a(2600822924,725511199),a(528734635,4215389547),a(1541459225,327033209)])},_doProcessBlock:function(a,e){for(var f=this._hash.words,C=f[0],d=f[1],D=f[2],E=f[3],F=f[4],G=f[5],H=
+f[6],f=f[7],r=C.high,I=C.low,v=d.high,J=d.low,X=D.high,K=D.low,Y=E.high,L=E.low,Z=F.high,M=F.low,$=G.high,N=G.low,aa=H.high,O=H.low,ba=f.high,P=f.low,j=r,g=I,w=v,t=J,x=X,u=K,U=Y,y=L,k=Z,h=M,Q=$,z=N,R=aa,A=O,V=ba,B=P,l=0;80>l;l++){var o=s[l];if(16>l)var i=o.high=a[e+2*l]|0,b=o.low=a[e+2*l+1]|0;else{var i=s[l-15],b=i.high,m=i.low,i=(m<<31|b>>>1)^(m<<24|b>>>8)^b>>>7,m=(b<<31|m>>>1)^(b<<24|m>>>8)^(b<<25|m>>>7),q=s[l-2],b=q.high,c=q.low,q=(c<<13|b>>>19)^(b<<3|c>>>29)^b>>>6,c=(b<<13|c>>>19)^(c<<3|b>>>29)^
+(b<<26|c>>>6),b=s[l-7],W=b.high,p=s[l-16],n=p.high,p=p.low,b=m+b.low,i=i+W+(b>>>0<m>>>0?1:0),b=b+c,i=i+q+(b>>>0<c>>>0?1:0),b=b+p,i=i+n+(b>>>0<p>>>0?1:0);o.high=i;o.low=b}var W=k&Q^~k&R,p=h&z^~h&A,o=j&w^j&x^w&x,S=g&t^g&u^t&u,m=(g<<4|j>>>28)^(j<<30|g>>>2)^(j<<25|g>>>7),q=(j<<4|g>>>28)^(g<<30|j>>>2)^(g<<25|j>>>7),c=da[l],ea=c.high,ca=c.low,c=B+((k<<18|h>>>14)^(k<<14|h>>>18)^(h<<23|k>>>9)),n=V+((h<<18|k>>>14)^(h<<14|k>>>18)^(k<<23|h>>>9))+(c>>>0<B>>>0?1:0),c=c+p,n=n+W+(c>>>0<p>>>0?1:0),c=c+ca,n=n+ea+
+(c>>>0<ca>>>0?1:0),c=c+b,n=n+i+(c>>>0<b>>>0?1:0),b=q+S,o=m+o+(b>>>0<q>>>0?1:0),V=R,B=A,R=Q,A=z,Q=k,z=h,h=y+c|0,k=U+n+(h>>>0<y>>>0?1:0)|0,U=x,y=u,x=w,u=t,w=j,t=g,g=c+b|0,j=n+o+(g>>>0<c>>>0?1:0)|0}I=C.low=I+g|0;C.high=r+j+(I>>>0<g>>>0?1:0)|0;J=d.low=J+t|0;d.high=v+w+(J>>>0<t>>>0?1:0)|0;K=D.low=K+u|0;D.high=X+x+(K>>>0<u>>>0?1:0)|0;L=E.low=L+y|0;E.high=Y+U+(L>>>0<y>>>0?1:0)|0;M=F.low=M+h|0;F.high=Z+k+(M>>>0<h>>>0?1:0)|0;N=G.low=N+z|0;G.high=$+Q+(N>>>0<z>>>0?1:0)|0;O=H.low=O+A|0;H.high=aa+R+(O>>>0<A>>>
+0?1:0)|0;P=f.low=P+B|0;f.high=ba+V+(P>>>0<B>>>0?1:0)|0},_doFinalize:function(){var a=this._data,d=a.words,f=8*this._nDataBytes,e=8*a.sigBytes;d[e>>>5]|=128<<24-e%32;d[(e+128>>>10<<5)+31]=f;a.sigBytes=4*d.length;this._process();this._hash=this._hash.toX32()},blockSize:32});d.SHA512=r._createHelper(e);d.HmacSHA512=r._createHmacHelper(e)})();
diff --git a/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/x64-core-min.js b/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/x64-core-min.js
new file mode 100644
index 0000000..d754bfe
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/res/crypto-js-3.0.2/x64-core-min.js
@@ -0,0 +1,7 @@
+/*
+CryptoJS v3.0.2
+code.google.com/p/crypto-js
+(c) 2009-2012 by Jeff Mott. All rights reserved.
+code.google.com/p/crypto-js/wiki/License
+*/
+(function(g){var a=CryptoJS,f=a.lib,e=f.Base,h=f.WordArray,a=a.x64={};a.Word=e.extend({init:function(b,c){this.high=b;this.low=c}});a.WordArray=e.extend({init:function(b,c){b=this.words=b||[];this.sigBytes=c!=g?c:8*b.length},toX32:function(){for(var b=this.words,c=b.length,a=[],d=0;d<c;d++){var e=b[d];a.push(e.high);a.push(e.low)}return h.create(a,this.sigBytes)},clone:function(){for(var b=e.clone.call(this),c=b.words=this.words.slice(0),a=c.length,d=0;d<a;d++)c[d]=c[d].clone();return b}})})();
diff --git a/webconsole-plugins/useradmin/src/main/resources/res/jsTree.v.0.9.9a/jquery.tree.min.js b/webconsole-plugins/useradmin/src/main/resources/res/jsTree.v.0.9.9a/jquery.tree.min.js
new file mode 100644
index 0000000..e58291b
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/res/jsTree.v.0.9.9a/jquery.tree.min.js
@@ -0,0 +1 @@
+(function($){$.tree={datastores:{},plugins:{},defaults:{data:{async:false,type:"html",opts:{method:"GET",url:false}},selected:false,opened:[],languages:[],ui:{dots:true,animation:0,scroll_spd:4,theme_path:false,theme_name:"default",selected_parent_close:"select_parent",selected_delete:"select_previous"},types:{"default":{clickable:true,renameable:true,deletable:true,creatable:true,draggable:true,max_children:-1,max_depth:-1,valid_children:"all",icon:{image:false,position:false}}},rules:{multiple:false,multitree:"none",type_attr:"rel",createat:"bottom",drag_copy:"ctrl",drag_button:"left",use_max_children:true,use_max_depth:true,max_children:-1,max_depth:-1,valid_children:"all"},lang:{new_node:"New folder",loading:"Loading ..."},callback:{beforechange:function(NODE,TREE_OBJ){return true},beforeopen:function(NODE,TREE_OBJ){return true},beforeclose:function(NODE,TREE_OBJ){return true},beforemove:function(NODE,REF_NODE,TYPE,TREE_OBJ){return true},beforecreate:function(NODE,REF_NODE,TYPE,TREE_OBJ){return true},beforerename:function(NODE,LANG,TREE_OBJ){return true},beforedelete:function(NODE,TREE_OBJ){return true},beforedata:function(NODE,TREE_OBJ){return{id:$(NODE).attr("id")||0}},ondata:function(DATA,TREE_OBJ){return DATA},onparse:function(STR,TREE_OBJ){return STR},onhover:function(NODE,TREE_OBJ){},onselect:function(NODE,TREE_OBJ){},ondeselect:function(NODE,TREE_OBJ){},onchange:function(NODE,TREE_OBJ){},onrename:function(NODE,TREE_OBJ,RB){},onmove:function(NODE,REF_NODE,TYPE,TREE_OBJ,RB){},oncopy:function(NODE,REF_NODE,TYPE,TREE_OBJ,RB){},oncreate:function(NODE,REF_NODE,TYPE,TREE_OBJ,RB){},ondelete:function(NODE,TREE_OBJ,RB){},onopen:function(NODE,TREE_OBJ){},onopen_all:function(TREE_OBJ){},onclose_all:function(TREE_OBJ){},onclose:function(NODE,TREE_OBJ){},error:function(TEXT,TREE_OBJ){},ondblclk:function(NODE,TREE_OBJ){TREE_OBJ.toggle_branch.call(TREE_OBJ,NODE);TREE_OBJ.select_branch.call(TREE_OBJ,NODE)},onrgtclk:function(NODE,TREE_OBJ,EV){},onload:function(TREE_OBJ){},oninit:function(TREE_OBJ){},onfocus:function(TREE_OBJ){},ondestroy:function(TREE_OBJ){},onsearch:function(NODES,TREE_OBJ){NODES.addClass("search")},ondrop:function(NODE,REF_NODE,TYPE,TREE_OBJ){},check:function(RULE,NODE,VALUE,TREE_OBJ){return VALUE},check_move:function(NODE,REF_NODE,TYPE,TREE_OBJ){return true}},plugins:{}},create:function(){return new tree_component()},focused:function(){return tree_component.inst[tree_component.focused]},reference:function(obj){var o=$(obj);if(!o.size())o=$("#"+obj);if(!o.size())return null;o=(o.is(".tree"))?o.attr("id"):o.parents(".tree:eq(0)").attr("id");return tree_component.inst[o]||null},rollback:function(data){for(var i in data){if(!data.hasOwnProperty(i))continue;var tmp=tree_component.inst[i];var lock=!tmp.locked;if(lock)tmp.lock(true);tmp.inp=false;tmp.container.html(data[i].html).find(".dragged").removeClass("dragged").end().find(".hover").removeClass("hover");if(data[i].selected){tmp.selected=$("#"+data[i].selected);tmp.selected_arr=[];tmp.container.find("a.clicked").each(function(){tmp.selected_arr.push(tmp.get_node(this))})}if(lock)tmp.lock(false);delete lock;delete tmp}},drop_mode:function(opts){opts=$.extend(opts,{show:false,type:"default",str:"Foreign node"});tree_component.drag_drop.foreign=true;tree_component.drag_drop.isdown=true;tree_component.drag_drop.moving=true;tree_component.drag_drop.appended=false;tree_component.drag_drop.f_type=opts.type;tree_component.drag_drop.f_data=opts;if(!opts.show){tree_component.drag_drop.drag_help=false;tree_component.drag_drop.drag_node=false}else{tree_component.drag_drop.drag_help=$("<div id='jstree-dragged' class='tree tree-default'><ul><li class='last dragged foreign'><a href='#'><ins>&nbsp;</ins>"+opts.str+"</a></li></ul></div>");tree_component.drag_drop.drag_node=tree_component.drag_drop.drag_help.find("li:eq(0)")}if($.tree.drag_start!==false)$.tree.drag_start.call(null,false)},drag_start:false,drag:false,drag_end:false};$.fn.tree=function(opts){return this.each(function(){var conf=$.extend({},opts);if(tree_component.inst&&tree_component.inst[$(this).attr('id')])tree_component.inst[$(this).attr('id')].destroy();if(conf!==false)new tree_component().init(this,conf)})};function tree_component(){return{cntr:++tree_component.cntr,settings:$.extend({},$.tree.defaults),init:function(elem,conf){var _this=this;this.container=$(elem);if(this.container.size==0)return false;tree_component.inst[this.cntr]=this;if(!this.container.attr("id"))this.container.attr("id","jstree_"+this.cntr);tree_component.inst[this.container.attr("id")]=tree_component.inst[this.cntr];tree_component.focused=this.cntr;this.settings=$.extend(true,{},this.settings,conf);if(this.settings.languages&&this.settings.languages.length){this.current_lang=this.settings.languages[0];var st=false;var id="#"+this.container.attr("id");for(var ln=0;ln<this.settings.languages.length;ln++){st=tree_component.add_css(id+" ."+this.settings.languages[ln]);if(st!==false)st.style.display=(this.settings.languages[ln]==this.current_lang)?"":"none"}}else this.current_lang=false;this.container.addClass("tree");if(this.settings.ui.theme_name!==false){if(this.settings.ui.theme_path===false){$("script").each(function(){if(this.src.toString().match(/jquery\.tree.*?js$/)){_this.settings.ui.theme_path=this.src.toString().replace(/jquery\.tree.*?js$/,"")+"themes/"+_this.settings.ui.theme_name+"/style.css";return false}})}if(this.settings.ui.theme_path!=""&&$.inArray(this.settings.ui.theme_path,tree_component.themes)==-1){tree_component.add_sheet({url:this.settings.ui.theme_path});tree_component.themes.push(this.settings.ui.theme_path)}this.container.addClass("tree-"+this.settings.ui.theme_name)}var type_icons="";for(var t in this.settings.types){if(!this.settings.types.hasOwnProperty(t))continue;if(!this.settings.types[t].icon)continue;if(this.settings.types[t].icon.image||this.settings.types[t].icon.position){if(t=="default")type_icons+="#"+this.container.attr("id")+" li > a ins { ";else type_icons+="#"+this.container.attr("id")+" li[rel="+t+"] > a ins { ";if(this.settings.types[t].icon.image)type_icons+=" background-image:url("+this.settings.types[t].icon.image+"); ";if(this.settings.types[t].icon.position)type_icons+=" background-position:"+this.settings.types[t].icon.position+"; ";type_icons+="} "}}if(type_icons!="")tree_component.add_sheet({str:type_icons});if(this.settings.rules.multiple)this.selected_arr=[];this.offset=false;this.hovered=false;this.locked=false;if(tree_component.drag_drop.marker===false)tree_component.drag_drop.marker=$("<div>").attr({id:"jstree-marker"}).hide().appendTo("body");this.callback("oninit",[this]);this.refresh();this.attach_events();this.focus()},refresh:function(obj){if(this.locked)return this.error("LOCKED");var _this=this;if(obj&&!this.settings.data.async)obj=false;this.is_partial_refresh=obj?true:false;this.opened=Array();if(this.settings.opened!=false){$.each(this.settings.opened,function(i,item){if(this.replace(/^#/,"").length>0){_this.opened.push("#"+this.replace(/^#/,""))}});this.settings.opened=false}else{this.container.find("li.open").each(function(i){if(this.id){_this.opened.push("#"+this.id)}})}if(this.selected){this.settings.selected=Array();if(obj){$(obj).find("li:has(a.clicked)").each(function(){if(this.id)_this.settings.selected.push("#"+this.id)})}else{if(this.selected_arr){$.each(this.selected_arr,function(){if(this.attr("id"))_this.settings.selected.push("#"+this.attr("id"))})}else{if(this.selected.attr("id"))this.settings.selected.push("#"+this.selected.attr("id"))}}}else if(this.settings.selected!==false){var tmp=Array();if((typeof this.settings.selected).toLowerCase()=="object"){$.each(this.settings.selected,function(){if(this.replace(/^#/,"").length>0)tmp.push("#"+this.replace(/^#/,""))})}else{if(this.settings.selected.replace(/^#/,"").length>0)tmp.push("#"+this.settings.selected.replace(/^#/,""))}this.settings.selected=tmp}if(obj&&this.settings.data.async){this.opened=Array();obj=this.get_node(obj);obj.find("li.open").each(function(i){_this.opened.push("#"+this.id)});if(obj.hasClass("open"))obj.removeClass("open").addClass("closed");if(obj.hasClass("leaf"))obj.removeClass("leaf");obj.children("ul:eq(0)").html("");return this.open_branch(obj,true,function(){_this.reselect.apply(_this)})}var _this=this;var _datastore=new $.tree.datastores[this.settings.data.type]();if(this.container.children("ul").size()==0){this.container.html("<ul class='ltr' style='direction:ltr;'><li class='last'><a class='loading' href='#'><ins>&nbsp;</ins>"+(this.settings.lang.loading||"Loading ...")+"</a></li></ul>")}_datastore.load(this.callback("beforedata",[false,this]),this,this.settings.data.opts,function(data){data=_this.callback("ondata",[data,_this]);_datastore.parse(data,_this,_this.settings.data.opts,function(str){str=_this.callback("onparse",[str,_this]);_this.container.empty().append($("<ul class='ltr'>").html(str));_this.container.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed");_this.container.find("li").not(".open").not(".closed").addClass("leaf");_this.reselect()})})},reselect:function(is_callback){var _this=this;if(!is_callback)this.cl_count=0;else this.cl_count--;if(this.opened&&this.opened.length){var opn=false;for(var j=0;this.opened&&j<this.opened.length;j++){if(this.settings.data.async){var tmp=this.get_node(this.opened[j]);if(tmp.size()&&tmp.hasClass("closed")>0){opn=true;var tmp=this.opened[j].toString().replace('/','\\/');delete this.opened[j];this.open_branch(tmp,true,function(){_this.reselect.apply(_this,[true])});this.cl_count++}}else this.open_branch(this.opened[j],true)}if(this.settings.data.async&&opn)return;if(this.cl_count>0)return;delete this.opened}if(this.cl_count>0)return;this.container.css("direction","ltr").children("ul:eq(0)").addClass("ltr");if(this.settings.ui.dots==false)this.container.children("ul:eq(0)").addClass("no_dots");if(this.scrtop){this.container.scrollTop(_this.scrtop);delete this.scrtop}if(this.settings.selected!==false){$.each(this.settings.selected,function(i){if(_this.is_partial_refresh)_this.select_branch($(_this.settings.selected[i].toString().replace('/','\\/'),_this.container),(_this.settings.rules.multiple!==false));else _this.select_branch($(_this.settings.selected[i].toString().replace('/','\\/'),_this.container),(_this.settings.rules.multiple!==false&&i>0))});this.settings.selected=false}this.callback("onload",[_this])},get:function(obj,format,opts){if(!format)format=this.settings.data.type;if(!opts)opts=this.settings.data.opts;return new $.tree.datastores[format]().get(obj,this,opts)},attach_events:function(){var _this=this;this.container.bind("mousedown.jstree",function(event){if(tree_component.drag_drop.isdown){tree_component.drag_drop.move_type=false;event.preventDefault();event.stopPropagation();event.stopImmediatePropagation();return false}}).bind("mouseup.jstree",function(event){setTimeout(function(){_this.focus.apply(_this)},5)}).bind("click.jstree",function(event){return true});$("#"+this.container.attr("id")+" li").live("click",function(event){if(event.target.tagName!="LI")return true;_this.off_height();if(event.pageY-$(event.target).offset().top>_this.li_height)return true;_this.toggle_branch.apply(_this,[event.target]);event.stopPropagation();return false});$("#"+this.container.attr("id")+" li a").live("click.jstree",function(event){if(event.which&&event.which==3)return true;if(_this.locked){event.preventDefault();event.target.blur();return _this.error("LOCKED")}_this.select_branch.apply(_this,[event.target,event.ctrlKey||_this.settings.rules.multiple=="on"]);if(_this.inp){_this.inp.blur()}event.preventDefault();event.target.blur();return false}).live("dblclick.jstree",function(event){if(_this.locked){event.preventDefault();event.stopPropagation();event.target.blur();return _this.error("LOCKED")}_this.callback("ondblclk",[_this.get_node(event.target).get(0),_this]);event.preventDefault();event.stopPropagation();event.target.blur()}).live("contextmenu.jstree",function(event){if(_this.locked){event.target.blur();return _this.error("LOCKED")}return _this.callback("onrgtclk",[_this.get_node(event.target).get(0),_this,event])}).live("mouseover.jstree",function(event){if(_this.locked){event.preventDefault();event.stopPropagation();return _this.error("LOCKED")}if(_this.hovered!==false&&(event.target.tagName=="A"||event.target.tagName=="INS")){_this.hovered.children("a").removeClass("hover");_this.hovered=false}_this.callback("onhover",[_this.get_node(event.target).get(0),_this])}).live("mousedown.jstree",function(event){if(_this.settings.rules.drag_button=="left"&&event.which&&event.which!=1)return true;if(_this.settings.rules.drag_button=="right"&&event.which&&event.which!=3)return true;_this.focus.apply(_this);if(_this.locked)return _this.error("LOCKED");var obj=_this.get_node(event.target);if(_this.settings.rules.multiple!=false&&_this.selected_arr.length>1&&obj.children("a:eq(0)").hasClass("clicked")){var counter=0;for(var i in _this.selected_arr){if(!_this.selected_arr.hasOwnProperty(i))continue;if(_this.check("draggable",_this.selected_arr[i])){_this.selected_arr[i].addClass("dragged");tree_component.drag_drop.origin_tree=_this;counter++}}if(counter>0){if(_this.check("draggable",obj))tree_component.drag_drop.drag_node=obj;else tree_component.drag_drop.drag_node=_this.container.find("li.dragged:eq(0)");tree_component.drag_drop.isdown=true;tree_component.drag_drop.drag_help=$("<div id='jstree-dragged' class='tree "+(_this.settings.ui.theme_name!=""?" tree-"+_this.settings.ui.theme_name:"")+"' />").append("<ul class='"+_this.container.children("ul:eq(0)").get(0).className+"' />");var tmp=tree_component.drag_drop.drag_node.clone();if(_this.settings.languages.length>0)tmp.find("a").not("."+_this.current_lang).hide();tree_component.drag_drop.drag_help.children("ul:eq(0)").append(tmp);tree_component.drag_drop.drag_help.find("li:eq(0)").removeClass("last").addClass("last").children("a").html("<ins>&nbsp;</ins>Multiple selection").end().children("ul").remove();tree_component.drag_drop.dragged=_this.container.find("li.dragged")}}else{if(_this.check("draggable",obj)){tree_component.drag_drop.drag_node=obj;tree_component.drag_drop.drag_help=$("<div id='jstree-dragged' class='tree "+(_this.settings.ui.theme_name!=""?" tree-"+_this.settings.ui.theme_name:"")+"' />").append("<ul class='"+_this.container.children("ul:eq(0)").get(0).className+"' />");var tmp=obj.clone();if(_this.settings.languages.length>0)tmp.find("a").not("."+_this.current_lang).hide();tree_component.drag_drop.drag_help.children("ul:eq(0)").append(tmp);tree_component.drag_drop.drag_help.find("li:eq(0)").removeClass("last").addClass("last");tree_component.drag_drop.isdown=true;tree_component.drag_drop.foreign=false;tree_component.drag_drop.origin_tree=_this;obj.addClass("dragged");tree_component.drag_drop.dragged=_this.container.find("li.dragged")}}tree_component.drag_drop.init_x=event.pageX;tree_component.drag_drop.init_y=event.pageY;obj.blur();event.preventDefault();event.stopPropagation();return false})},focus:function(){if(this.locked)return false;if(tree_component.focused!=this.cntr){tree_component.focused=this.cntr;this.callback("onfocus",[this])}},off_height:function(){if(this.offset===false){this.container.css({position:"relative"});this.offset=this.container.offset();var tmp=0;tmp=parseInt($.curCSS(this.container.get(0),"paddingTop",true),10);if(tmp)this.offset.top+=tmp;tmp=parseInt($.curCSS(this.container.get(0),"borderTopWidth",true),10);if(tmp)this.offset.top+=tmp;this.container.css({position:""})}if(!this.li_height){var tmp=this.container.find("ul li.closed, ul li.leaf").eq(0);this.li_height=tmp.height();if(tmp.children("ul:eq(0)").size())this.li_height-=tmp.children("ul:eq(0)").height();if(!this.li_height)this.li_height=18}},scroll_check:function(x,y){var _this=this;var cnt=_this.container;var off=_this.container.offset();var st=cnt.scrollTop();var sl=cnt.scrollLeft();var h_cor=(cnt.get(0).scrollWidth>cnt.width())?40:20;if(y-off.top<20)cnt.scrollTop(Math.max((st-_this.settings.ui.scroll_spd),0));if(cnt.height()-(y-off.top)<h_cor)cnt.scrollTop(st+_this.settings.ui.scroll_spd);if(x-off.left<20)cnt.scrollLeft(Math.max((sl-_this.settings.ui.scroll_spd),0));if(cnt.width()-(x-off.left)<40)cnt.scrollLeft(sl+_this.settings.ui.scroll_spd);if(cnt.scrollLeft()!=sl||cnt.scrollTop()!=st){tree_component.drag_drop.move_type=false;tree_component.drag_drop.ref_node=false;tree_component.drag_drop.marker.hide()}tree_component.drag_drop.scroll_time=setTimeout(function(){_this.scroll_check(x,y)},50)},scroll_into_view:function(obj){obj=obj?this.get_node(obj):this.selected;if(!obj)return false;var off_t=obj.offset().top;var beg_t=this.container.offset().top;var end_t=beg_t+this.container.height();var h_cor=(this.container.get(0).scrollWidth>this.container.width())?40:20;if(off_t+5<beg_t)this.container.scrollTop(this.container.scrollTop()-(beg_t-off_t+5));if(off_t+h_cor>end_t)this.container.scrollTop(this.container.scrollTop()+(off_t+h_cor-end_t))},get_node:function(obj){return $(obj).closest("li")},get_type:function(obj){obj=!obj?this.selected:this.get_node(obj);if(!obj)return;var tmp=obj.attr(this.settings.rules.type_attr);return tmp||"default"},set_type:function(str,obj){obj=!obj?this.selected:this.get_node(obj);if(!obj||!str)return;obj.attr(this.settings.rules.type_attr,str)},get_text:function(obj,lang){obj=this.get_node(obj);if(!obj||obj.size()==0)return"";if(this.settings.languages&&this.settings.languages.length){lang=lang?lang:this.current_lang;obj=obj.children("a."+lang)}else obj=obj.children("a:visible");var val="";obj.contents().each(function(){if(this.nodeType==3){val=this.data;return false}});return val},check:function(rule,obj){if(this.locked)return false;var v=false;if(obj===-1){if(typeof this.settings.rules[rule]!="undefined")v=this.settings.rules[rule]}else{obj=!obj?this.selected:this.get_node(obj);if(!obj)return;var t=this.get_type(obj);if(typeof this.settings.types[t]!="undefined"&&typeof this.settings.types[t][rule]!="undefined")v=this.settings.types[t][rule];else if(typeof this.settings.types["default"]!="undefined"&&typeof this.settings.types["default"][rule]!="undefined")v=this.settings.types["default"][rule]}if(typeof v=="function")v=v.call(null,obj,this);v=this.callback("check",[rule,obj,v,this]);return v},check_move:function(nod,ref_node,how){if(this.locked)return false;if($(ref_node).closest("li.dragged").size())return false;var tree1=nod.parents(".tree:eq(0)").get(0);var tree2=ref_node.parents(".tree:eq(0)").get(0);if(tree1&&tree1!=tree2){var m=$.tree.reference(tree2.id).settings.rules.multitree;if(m=="none"||($.isArray(m)&&$.inArray(tree1.id,m)==-1))return false}var p=(how!="inside")?this.parent(ref_node):this.get_node(ref_node);nod=this.get_node(nod);if(p==false)return false;var r={max_depth:this.settings.rules.use_max_depth?this.check("max_depth",p):-1,max_children:this.settings.rules.use_max_children?this.check("max_children",p):-1,valid_children:this.check("valid_children",p)};var nod_type=(typeof nod=="string")?nod:this.get_type(nod);if(typeof r.valid_children!="undefined"&&(r.valid_children=="none"||(typeof r.valid_children=="object"&&$.inArray(nod_type,$.makeArray(r.valid_children))==-1)))return false;if(this.settings.rules.use_max_children){if(typeof r.max_children!="undefined"&&r.max_children!=-1){if(r.max_children==0)return false;var c_count=1;if(tree_component.drag_drop.moving==true&&tree_component.drag_drop.foreign==false){c_count=tree_component.drag_drop.dragged.size();c_count=c_count-p.find('> ul > li.dragged').size()}if(r.max_children<p.find('> ul > li').size()+c_count)return false}}if(this.settings.rules.use_max_depth){if(typeof r.max_depth!="undefined"&&r.max_depth===0)return this.error("MOVE: MAX-DEPTH REACHED");var mx=(r.max_depth>0)?r.max_depth:false;var i=0;var t=p;while(t!==-1){t=this.parent(t);i++;var m=this.check("max_depth",t);if(m>=0){mx=(mx===false)?(m-i):Math.min(mx,m-i)}if(mx!==false&&mx<=0)return this.error("MOVE: MAX-DEPTH REACHED")}if(mx!==false&&mx<=0)return this.error("MOVE: MAX-DEPTH REACHED");if(mx!==false){var incr=1;if(typeof nod!="string"){var t=nod;while(t.size()>0){if(mx-incr<0)return this.error("MOVE: MAX-DEPTH REACHED");t=t.children("ul").children("li");incr++}}}}if(this.callback("check_move",[nod,ref_node,how,this])==false)return false;return true},hover_branch:function(obj){if(this.locked)return this.error("LOCKED");var _this=this;var obj=_this.get_node(obj);if(!obj.size())return this.error("HOVER: NOT A VALID NODE");if(!_this.check("clickable",obj))return this.error("SELECT: NODE NOT SELECTABLE");if(this.hovered)this.hovered.children("A").removeClass("hover");this.hovered=obj;this.hovered.children("a").addClass("hover");this.scroll_into_view(this.hovered)},select_branch:function(obj,multiple){if(this.locked)return this.error("LOCKED");if(!obj&&this.hovered!==false)obj=this.hovered;var _this=this;obj=_this.get_node(obj);if(!obj.size())return this.error("SELECT: NOT A VALID NODE");obj.children("a").removeClass("hover");if(!_this.check("clickable",obj))return this.error("SELECT: NODE NOT SELECTABLE");if(_this.callback("beforechange",[obj.get(0),_this])===false)return this.error("SELECT: STOPPED BY USER");if(this.settings.rules.multiple!=false&&multiple&&obj.children("a.clicked").size()>0){return this.deselect_branch(obj)}if(this.settings.rules.multiple!=false&&multiple){this.selected_arr.push(obj)}if(this.settings.rules.multiple!=false&&!multiple){for(var i in this.selected_arr){if(!this.selected_arr.hasOwnProperty(i))continue;this.selected_arr[i].children("A").removeClass("clicked");this.callback("ondeselect",[this.selected_arr[i].get(0),_this])}this.selected_arr=[];this.selected_arr.push(obj);if(this.selected&&this.selected.children("A").hasClass("clicked")){this.selected.children("A").removeClass("clicked");this.callback("ondeselect",[this.selected.get(0),_this])}}if(!this.settings.rules.multiple){if(this.selected){this.selected.children("A").removeClass("clicked");this.callback("ondeselect",[this.selected.get(0),_this])}}this.selected=obj;if(this.hovered!==false){this.hovered.children("A").removeClass("hover");this.hovered=obj}this.selected.children("a").addClass("clicked").end().parents("li.closed").each(function(){_this.open_branch(this,true)});this.scroll_into_view(this.selected);this.callback("onselect",[this.selected.get(0),_this]);this.callback("onchange",[this.selected.get(0),_this])},deselect_branch:function(obj){if(this.locked)return this.error("LOCKED");var _this=this;var obj=this.get_node(obj);if(obj.children("a.clicked").size()==0)return this.error("DESELECT: NODE NOT SELECTED");obj.children("a").removeClass("clicked");this.callback("ondeselect",[obj.get(0),_this]);if(this.settings.rules.multiple!=false&&this.selected_arr.length>1){this.selected_arr=[];this.container.find("a.clicked").filter(":first-child").parent().each(function(){_this.selected_arr.push($(this))});if(obj.get(0)==this.selected.get(0)){this.selected=this.selected_arr[0]}}else{if(this.settings.rules.multiple!=false)this.selected_arr=[];this.selected=false}this.callback("onchange",[obj.get(0),_this])},toggle_branch:function(obj){if(this.locked)return this.error("LOCKED");var obj=this.get_node(obj);if(obj.hasClass("closed"))return this.open_branch(obj);if(obj.hasClass("open"))return this.close_branch(obj)},open_branch:function(obj,disable_animation,callback){var _this=this;if(this.locked)return this.error("LOCKED");var obj=this.get_node(obj);if(!obj.size())return this.error("OPEN: NO SUCH NODE");if(obj.hasClass("leaf"))return this.error("OPEN: OPENING LEAF NODE");if(this.settings.data.async&&obj.find("li").size()==0){if(this.callback("beforeopen",[obj.get(0),this])===false)return this.error("OPEN: STOPPED BY USER");obj.children("ul:eq(0)").remove().end().append("<ul><li class='last'><a class='loading' href='#'><ins>&nbsp;</ins>"+(_this.settings.lang.loading||"Loading ...")+"</a></li></ul>");obj.removeClass("closed").addClass("open");var _datastore=new $.tree.datastores[this.settings.data.type]();_datastore.load(this.callback("beforedata",[obj,this]),this,this.settings.data.opts,function(data){data=_this.callback("ondata",[data,_this]);if(!data||data.length==0){obj.removeClass("closed").removeClass("open").addClass("leaf").children("ul").remove();if(callback)callback.call();return}_datastore.parse(data,_this,_this.settings.data.opts,function(str){str=_this.callback("onparse",[str,_this]);obj.children("ul:eq(0)").replaceWith($("<ul>").html(str));obj.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed");obj.find("li").not(".open").not(".closed").addClass("leaf");_this.open_branch.apply(_this,[obj]);if(callback)callback.call()})});return true}else{if(!this.settings.data.async){if(this.callback("beforeopen",[obj.get(0),this])===false)return this.error("OPEN: STOPPED BY USER")}if(parseInt(this.settings.ui.animation)>0&&!disable_animation){obj.children("ul:eq(0)").css("display","none");obj.removeClass("closed").addClass("open");obj.children("ul:eq(0)").slideDown(parseInt(this.settings.ui.animation),function(){$(this).css("display","");if(callback)callback.call()})}else{obj.removeClass("closed").addClass("open");if(callback)callback.call()}this.callback("onopen",[obj.get(0),this]);return true}},close_branch:function(obj,disable_animation){if(this.locked)return this.error("LOCKED");var _this=this;var obj=this.get_node(obj);if(!obj.size())return this.error("CLOSE: NO SUCH NODE");if(_this.callback("beforeclose",[obj.get(0),_this])===false)return this.error("CLOSE: STOPPED BY USER");if(parseInt(this.settings.ui.animation)>0&&!disable_animation&&obj.children("ul:eq(0)").size()==1){obj.children("ul:eq(0)").slideUp(parseInt(this.settings.ui.animation),function(){if(obj.hasClass("open"))obj.removeClass("open").addClass("closed");$(this).css("display","")})}else{if(obj.hasClass("open"))obj.removeClass("open").addClass("closed")}if(this.selected&&this.settings.ui.selected_parent_close!==false&&obj.children("ul:eq(0)").find("a.clicked").size()>0){obj.find("li:has(a.clicked)").each(function(){_this.deselect_branch(this)});if(this.settings.ui.selected_parent_close=="select_parent"&&obj.children("a.clicked").size()==0)this.select_branch(obj,(this.settings.rules.multiple!=false&&this.selected_arr.length>0))}this.callback("onclose",[obj.get(0),this])},open_all:function(obj,callback){if(this.locked)return this.error("LOCKED");var _this=this;obj=obj?this.get_node(obj):this.container;var s=obj.find("li.closed").size();if(!callback)this.cl_count=0;else this.cl_count--;if(s>0){this.cl_count+=s;obj.find("li.closed").each(function(){var __this=this;_this.open_branch.apply(_this,[this,true,function(){_this.open_all.apply(_this,[__this,true])}])})}else if(this.cl_count==0)this.callback("onopen_all",[this])},close_all:function(obj){if(this.locked)return this.error("LOCKED");var _this=this;obj=obj?this.get_node(obj):this.container;obj.find("li.open").each(function(){_this.close_branch(this,true)});this.callback("onclose_all",[this])},set_lang:function(i){if(!$.isArray(this.settings.languages)||this.settings.languages.length==0)return false;if(this.locked)return this.error("LOCKED");if(!$.inArray(i,this.settings.languages)&&typeof this.settings.languages[i]!="undefined")i=this.settings.languages[i];if(typeof i=="undefined")return false;if(i==this.current_lang)return true;var st=false;var id="#"+this.container.attr("id");st=tree_component.get_css(id+" ."+this.current_lang);if(st!==false)st.style.display="none";st=tree_component.get_css(id+" ."+i);if(st!==false)st.style.display="";this.current_lang=i;return true},get_lang:function(){if(!$.isArray(this.settings.languages)||this.settings.languages.length==0)return false;return this.current_lang},create:function(obj,ref_node,position){if(this.locked)return this.error("LOCKED");var root=false;if(ref_node==-1){root=true;ref_node=this.container}else ref_node=ref_node?this.get_node(ref_node):this.selected;if(!root&&(!ref_node||!ref_node.size()))return this.error("CREATE: NO NODE SELECTED");var pos=position;var tmp=ref_node;if(position=="before"){position=ref_node.parent().children().index(ref_node);ref_node=ref_node.parents("li:eq(0)")}if(position=="after"){position=ref_node.parent().children().index(ref_node)+1;ref_node=ref_node.parents("li:eq(0)")}if(!root&&ref_node.size()==0){root=true;ref_node=this.container}if(!root){if(!this.check("creatable",ref_node))return this.error("CREATE: CANNOT CREATE IN NODE");if(ref_node.hasClass("closed")){if(this.settings.data.async&&ref_node.children("ul").size()==0){var _this=this;return this.open_branch(ref_node,true,function(){_this.create.apply(_this,[obj,ref_node,position])})}else this.open_branch(ref_node,true)}}var torename=false;if(!obj)obj={};else obj=$.extend(true,{},obj);if(!obj.attributes)obj.attributes={};if(!obj.attributes[this.settings.rules.type_attr])obj.attributes[this.settings.rules.type_attr]=this.get_type(tmp)||"default";if(this.settings.languages.length){if(!obj.data){obj.data={};torename=true}for(var i=0;i<this.settings.languages.length;i++){if(!obj.data[this.settings.languages[i]])obj.data[this.settings.languages[i]]=((typeof this.settings.lang.new_node).toLowerCase()!="string"&&this.settings.lang.new_node[i])?this.settings.lang.new_node[i]:this.settings.lang.new_node}}else{if(!obj.data){obj.data=this.settings.lang.new_node;torename=true}}obj=this.callback("ondata",[obj,this]);var obj_s=$.tree.datastores.json().parse(obj,this);obj_s=this.callback("onparse",[obj_s,this]);var $li=$(obj_s);if($li.children("ul").size()){if(!$li.is(".open"))$li.addClass("closed")}else $li.addClass("leaf");$li.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed");$li.find("li").not(".open").not(".closed").addClass("leaf");var r={max_depth:this.settings.rules.use_max_depth?this.check("max_depth",(root?-1:ref_node)):-1,max_children:this.settings.rules.use_max_children?this.check("max_children",(root?-1:ref_node)):-1,valid_children:this.check("valid_children",(root?-1:ref_node))};var nod_type=this.get_type($li);if(typeof r.valid_children!="undefined"&&(r.valid_children=="none"||($.isArray(r.valid_children)&&$.inArray(nod_type,r.valid_children)==-1)))return this.error("CREATE: NODE NOT A VALID CHILD");if(this.settings.rules.use_max_children){if(typeof r.max_children!="undefined"&&r.max_children!=-1&&r.max_children>=this.children(ref_node).size())return this.error("CREATE: MAX_CHILDREN REACHED")}if(this.settings.rules.use_max_depth){if(typeof r.max_depth!="undefined"&&r.max_depth===0)return this.error("CREATE: MAX-DEPTH REACHED");var mx=(r.max_depth>0)?r.max_depth:false;var i=0;var t=ref_node;while(t!==-1&&!root){t=this.parent(t);i++;var m=this.check("max_depth",t);if(m>=0){mx=(mx===false)?(m-i):Math.min(mx,m-i)}if(mx!==false&&mx<=0)return this.error("CREATE: MAX-DEPTH REACHED")}if(mx!==false&&mx<=0)return this.error("CREATE: MAX-DEPTH REACHED");if(mx!==false){var incr=1;var t=$li;while(t.size()>0){if(mx-incr<0)return this.error("CREATE: MAX-DEPTH REACHED");t=t.children("ul").children("li");incr++}}}if((typeof position).toLowerCase()=="undefined"||position=="inside")position=(this.settings.rules.createat=="top")?0:ref_node.children("ul:eq(0)").children("li").size();if(ref_node.children("ul").size()==0||(root==true&&ref_node.children("ul").children("li").size()==0)){if(!root)var a=this.moved($li,ref_node.children("a:eq(0)"),"inside",true);else var a=this.moved($li,this.container.children("ul:eq(0)"),"inside",true)}else if(pos=="before"&&ref_node.children("ul:eq(0)").children("li:nth-child("+(position+1)+")").size())var a=this.moved($li,ref_node.children("ul:eq(0)").children("li:nth-child("+(position+1)+")").children("a:eq(0)"),"before",true);else if(pos=="after"&&ref_node.children("ul:eq(0)").children("li:nth-child("+(position)+")").size())var a=this.moved($li,ref_node.children("ul:eq(0)").children("li:nth-child("+(position)+")").children("a:eq(0)"),"after",true);else if(ref_node.children("ul:eq(0)").children("li:nth-child("+(position+1)+")").size())var a=this.moved($li,ref_node.children("ul:eq(0)").children("li:nth-child("+(position+1)+")").children("a:eq(0)"),"before",true);else var a=this.moved($li,ref_node.children("ul:eq(0)").children("li:last").children("a:eq(0)"),"after",true);if(a===false)return this.error("CREATE: ABORTED");if(torename){this.select_branch($li.children("a:eq(0)"));this.rename()}return $li},rename:function(obj,new_name){if(this.locked)return this.error("LOCKED");obj=obj?this.get_node(obj):this.selected;var _this=this;if(!obj||!obj.size())return this.error("RENAME: NO NODE SELECTED");if(!this.check("renameable",obj))return this.error("RENAME: NODE NOT RENAMABLE");if(!this.callback("beforerename",[obj.get(0),_this.current_lang,_this]))return this.error("RENAME: STOPPED BY USER");obj.parents("li.closed").each(function(){_this.open_branch(this)});if(this.current_lang)obj=obj.find("a."+this.current_lang);else obj=obj.find("a:first");var rb={};rb[this.container.attr("id")]=this.get_rollback();var icn=obj.children("ins").clone();if((typeof new_name).toLowerCase()=="string"){obj.text(new_name).prepend(icn);_this.callback("onrename",[_this.get_node(obj).get(0),_this,rb])}else{var last_value="";obj.contents().each(function(){if(this.nodeType==3){last_value=this.data;return false}});_this.inp=$("<input type='text' autocomplete='off' />");_this.inp.val(last_value.replace(/&amp;/g,"&").replace(/&gt;/g,">").replace(/&lt;/g,"<")).bind("mousedown",function(event){event.stopPropagation()}).bind("mouseup",function(event){event.stopPropagation()}).bind("click",function(event){event.stopPropagation()}).bind("keyup",function(event){var key=event.keyCode||event.which;if(key==27){this.value=last_value;this.blur();return}if(key==13){this.blur();return}});_this.inp.blur(function(event){if(this.value=="")this.value=last_value;obj.text(this.value).prepend(icn);obj.get(0).style.display="";obj.prevAll("span").remove();_this.inp=false;_this.callback("onrename",[_this.get_node(obj).get(0),_this,rb])});var spn=$("<span />").addClass(obj.attr("class")).append(icn).append(_this.inp);obj.get(0).style.display="none";obj.parent().prepend(spn);_this.inp.get(0).focus();_this.inp.get(0).select()}},remove:function(obj){if(this.locked)return this.error("LOCKED");var _this=this;var rb={};rb[this.container.attr("id")]=this.get_rollback();if(obj&&(!this.selected||this.get_node(obj).get(0)!=this.selected.get(0))){obj=this.get_node(obj);if(obj.size()){if(!this.check("deletable",obj))return this.error("DELETE: NODE NOT DELETABLE");if(!this.callback("beforedelete",[obj.get(0),_this]))return this.error("DELETE: STOPPED BY USER");$parent=obj.parent();if(obj.find("a.clicked").size()){var reset_selected=false;_this.selected_arr=[];this.container.find("a.clicked").filter(":first-child").parent().each(function(){if(!reset_selected&&this==_this.selected.get(0))reset_selected=true;if($(this).parents().index(obj)!=-1)return true;_this.selected_arr.push($(this))});if(reset_selected)this.selected=this.selected_arr[0]||false}obj=obj.remove();$parent.children("li:last").addClass("last");if($parent.children("li").size()==0){$li=$parent.parents("li:eq(0)");$li.removeClass("open").removeClass("closed").addClass("leaf").children("ul").remove()}this.callback("ondelete",[obj.get(0),this,rb])}}else if(this.selected){if(!this.check("deletable",this.selected))return this.error("DELETE: NODE NOT DELETABLE");if(!this.callback("beforedelete",[this.selected.get(0),_this]))return this.error("DELETE: STOPPED BY USER");$parent=this.selected.parent();var obj=this.selected;if(this.settings.rules.multiple==false||this.selected_arr.length==1){var stop=true;var tmp=this.settings.ui.selected_delete=="select_previous"?this.prev(this.selected):false}obj=obj.remove();$parent.children("li:last").addClass("last");if($parent.children("li").size()==0){$li=$parent.parents("li:eq(0)");$li.removeClass("open").removeClass("closed").addClass("leaf").children("ul").remove()}if(!stop&&this.settings.rules.multiple!=false){var _this=this;this.selected_arr=[];this.container.find("a.clicked").filter(":first-child").parent().each(function(){_this.selected_arr.push($(this))});if(this.selected_arr.length>0){this.selected=this.selected_arr[0];this.remove()}}if(stop&&tmp)this.select_branch(tmp);this.callback("ondelete",[obj.get(0),this,rb])}else return this.error("DELETE: NO NODE SELECTED")},next:function(obj,strict){obj=this.get_node(obj);if(!obj.size())return false;if(strict)return(obj.nextAll("li").size()>0)?obj.nextAll("li:eq(0)"):false;if(obj.hasClass("open"))return obj.find("li:eq(0)");else if(obj.nextAll("li").size()>0)return obj.nextAll("li:eq(0)");else return obj.parents("li").next("li").eq(0)},prev:function(obj,strict){obj=this.get_node(obj);if(!obj.size())return false;if(strict)return(obj.prevAll("li").size()>0)?obj.prevAll("li:eq(0)"):false;if(obj.prev("li").size()){var obj=obj.prev("li").eq(0);while(obj.hasClass("open"))obj=obj.children("ul:eq(0)").children("li:last");return obj}else return obj.parents("li:eq(0)").size()?obj.parents("li:eq(0)"):false},parent:function(obj){obj=this.get_node(obj);if(!obj.size())return false;return obj.parents("li:eq(0)").size()?obj.parents("li:eq(0)"):-1},children:function(obj){if(obj===-1)return this.container.children("ul:eq(0)").children("li");obj=this.get_node(obj);if(!obj.size())return false;return obj.children("ul:eq(0)").children("li")},toggle_dots:function(){if(this.settings.ui.dots){this.settings.ui.dots=false;this.container.children("ul:eq(0)").addClass("no_dots")}else{this.settings.ui.dots=true;this.container.children("ul:eq(0)").removeClass("no_dots")}},callback:function(cb,args){var p=false;var r=null;for(var i in this.settings.plugins){if(typeof $.tree.plugins[i]!="object")continue;p=$.tree.plugins[i];if(p.callbacks&&typeof p.callbacks[cb]=="function")r=p.callbacks[cb].apply(this,args);if(typeof r!=="undefined"&&r!==null){if(cb=="ondata"||cb=="onparse")args[0]=r;else return r}}p=this.settings.callback[cb];if(typeof p=="function")return p.apply(null,args)},get_rollback:function(){var rb={};rb.html=this.container.html();rb.selected=this.selected?this.selected.attr("id"):false;return rb},moved:function(what,where,how,is_new,is_copy,rb){var what=$(what);var $parent=$(what).parents("ul:eq(0)");var $where=$(where);if($where.is("ins"))$where=$where.parent();if(!rb){var rb={};rb[this.container.attr("id")]=this.get_rollback();if(!is_new){var tmp=what.size()>1?what.eq(0).parents(".tree:eq(0)"):what.parents(".tree:eq(0)");if(tmp.get(0)!=this.container.get(0)){tmp=tree_component.inst[tmp.attr("id")];rb[tmp.container.attr("id")]=tmp.get_rollback()}delete tmp}}if(how=="inside"&&this.settings.data.async){var _this=this;if(this.get_node($where).hasClass("closed")){return this.open_branch(this.get_node($where),true,function(){_this.moved.apply(_this,[what,where,how,is_new,is_copy,rb])})}if(this.get_node($where).find("> ul > li > a.loading").size()==1){setTimeout(function(){_this.moved.apply(_this,[what,where,how,is_new,is_copy])},200);return}}if(what.size()>1){var _this=this;var tmp=this.moved(what.eq(0),where,how,false,is_copy,rb);what.each(function(i){if(i==0)return;if(tmp){tmp=_this.moved(this,tmp.children("a:eq(0)"),"after",false,is_copy,rb)}});return what}if(is_copy){_what=what.clone();_what.each(function(i){this.id=this.id+"_copy";$(this).find("li").each(function(){this.id=this.id+"_copy"});$(this).removeClass("dragged").find("a.clicked").removeClass("clicked").end().find("li.dragged").removeClass("dragged")})}else _what=what;if(is_new){if(!this.callback("beforecreate",[this.get_node(what).get(0),this.get_node(where).get(0),how,this]))return false}else{if(!this.callback("beforemove",[this.get_node(what).get(0),this.get_node(where).get(0),how,this,is_copy]))return false}if(!is_new){var tmp=what.parents(".tree:eq(0)");if(tmp.get(0)!=this.container.get(0)){tmp=tree_component.inst[tmp.attr("id")];if(tmp.settings.languages.length){var res=[];if(this.settings.languages.length==0)res.push("."+tmp.current_lang);else{for(var i in this.settings.languages){if(!this.settings.languages.hasOwnProperty(i))continue;for(var j in tmp.settings.languages){if(!tmp.settings.languages.hasOwnProperty(j))continue;if(this.settings.languages[i]==tmp.settings.languages[j])res.push("."+this.settings.languages[i])}}}if(res.length==0)return this.error("MOVE: NO COMMON LANGUAGES");_what.find("a").not(res.join(",")).remove()}_what.find("a.clicked").removeClass("clicked")}}what=_what;switch(how){case"before":$where.parents("ul:eq(0)").children("li.last").removeClass("last");$where.parent().before(what.removeClass("last"));$where.parents("ul:eq(0)").children("li:last").addClass("last");break;case"after":$where.parents("ul:eq(0)").children("li.last").removeClass("last");$where.parent().after(what.removeClass("last"));$where.parents("ul:eq(0)").children("li:last").addClass("last");break;case"inside":if($where.parent().children("ul:first").size()){if(this.settings.rules.createat=="top"){$where.parent().children("ul:first").prepend(what.removeClass("last")).children("li:last").addClass("last");var tmp_node=$where.parent().children("ul:first").children("li:first");if(tmp_node.size()){how="before";where=tmp_node}}else{var tmp_node=$where.parent().children("ul:first").children(".last");if(tmp_node.size()){how="after";where=tmp_node}$where.parent().children("ul:first").children(".last").removeClass("last").end().append(what.removeClass("last")).children("li:last").addClass("last")}}else{what.addClass("last");$where.parent().removeClass("leaf").append("<ul/>");if(!$where.parent().hasClass("open"))$where.parent().addClass("closed");$where.parent().children("ul:first").prepend(what)}if($where.parent().hasClass("closed")){this.open_branch($where)}break;default:break}if($parent.find("li").size()==0){var $li=$parent.parent();$li.removeClass("open").removeClass("closed").addClass("leaf");if(!$li.is(".tree"))$li.children("ul").remove();$li.parents("ul:eq(0)").children("li.last").removeClass("last").end().children("li:last").addClass("last")}else{$parent.children("li.last").removeClass("last");$parent.children("li:last").addClass("last")}if(is_copy)this.callback("oncopy",[this.get_node(what).get(0),this.get_node(where).get(0),how,this,rb]);else if(is_new)this.callback("oncreate",[this.get_node(what).get(0),($where.is("ul")?-1:this.get_node(where).get(0)),how,this,rb]);else this.callback("onmove",[this.get_node(what).get(0),this.get_node(where).get(0),how,this,rb]);return what},error:function(code){this.callback("error",[code,this]);return false},lock:function(state){this.locked=state;if(this.locked)this.container.children("ul:eq(0)").addClass("locked");else this.container.children("ul:eq(0)").removeClass("locked")},cut:function(obj){if(this.locked)return this.error("LOCKED");obj=obj?this.get_node(obj):this.container.find("a.clicked").filter(":first-child").parent();if(!obj||!obj.size())return this.error("CUT: NO NODE SELECTED");tree_component.cut_copy.copy_nodes=false;tree_component.cut_copy.cut_nodes=obj},copy:function(obj){if(this.locked)return this.error("LOCKED");obj=obj?this.get_node(obj):this.container.find("a.clicked").filter(":first-child").parent();if(!obj||!obj.size())return this.error("COPY: NO NODE SELECTED");tree_component.cut_copy.copy_nodes=obj;tree_component.cut_copy.cut_nodes=false},paste:function(obj,position){if(this.locked)return this.error("LOCKED");var root=false;if(obj==-1){root=true;obj=this.container}else obj=obj?this.get_node(obj):this.selected;if(!root&&(!obj||!obj.size()))return this.error("PASTE: NO NODE SELECTED");if(!tree_component.cut_copy.copy_nodes&&!tree_component.cut_copy.cut_nodes)return this.error("PASTE: NOTHING TO DO");var _this=this;var pos=position;if(position=="before"){position=obj.parent().children().index(obj);obj=obj.parents("li:eq(0)")}else if(position=="after"){position=obj.parent().children().index(obj)+1;obj=obj.parents("li:eq(0)")}else if((typeof position).toLowerCase()=="undefined"||position=="inside"){position=(this.settings.rules.createat=="top")?0:obj.children("ul:eq(0)").children("li").size()}if(!root&&obj.size()==0){root=true;obj=this.container}if(tree_component.cut_copy.copy_nodes&&tree_component.cut_copy.copy_nodes.size()){var ok=true;if(!root&&!this.check_move(tree_component.cut_copy.copy_nodes,obj.children("a:eq(0)"),"inside"))return false;if(obj.children("ul").size()==0||(root==true&&obj.children("ul").children("li").size()==0)){if(!root)var a=this.moved(tree_component.cut_copy.copy_nodes,obj.children("a:eq(0)"),"inside",false,true);else var a=this.moved(tree_component.cut_copy.copy_nodes,this.container.children("ul:eq(0)"),"inside",false,true)}else if(pos=="before"&&obj.children("ul:eq(0)").children("li:nth-child("+(position+1)+")").size())var a=this.moved(tree_component.cut_copy.copy_nodes,obj.children("ul:eq(0)").children("li:nth-child("+(position+1)+")").children("a:eq(0)"),"before",false,true);else if(pos=="after"&&obj.children("ul:eq(0)").children("li:nth-child("+(position)+")").size())var a=this.moved(tree_component.cut_copy.copy_nodes,obj.children("ul:eq(0)").children("li:nth-child("+(position)+")").children("a:eq(0)"),"after",false,true);else if(obj.children("ul:eq(0)").children("li:nth-child("+(position+1)+")").size())var a=this.moved(tree_component.cut_copy.copy_nodes,obj.children("ul:eq(0)").children("li:nth-child("+(position+1)+")").children("a:eq(0)"),"before",false,true);else var a=this.moved(tree_component.cut_copy.copy_nodes,obj.children("ul:eq(0)").children("li:last").children("a:eq(0)"),"after",false,true);tree_component.cut_copy.copy_nodes=false}if(tree_component.cut_copy.cut_nodes&&tree_component.cut_copy.cut_nodes.size()){var ok=true;obj.parents().andSelf().each(function(){if(tree_component.cut_copy.cut_nodes.index(this)!=-1){ok=false;return false}});if(!ok)return this.error("Invalid paste");if(!root&&!this.check_move(tree_component.cut_copy.cut_nodes,obj.children("a:eq(0)"),"inside"))return false;if(obj.children("ul").size()==0||(root==true&&obj.children("ul").children("li").size()==0)){if(!root)var a=this.moved(tree_component.cut_copy.cut_nodes,obj.children("a:eq(0)"),"inside");else var a=this.moved(tree_component.cut_copy.cut_nodes,this.container.children("ul:eq(0)"),"inside")}else if(pos=="before"&&obj.children("ul:eq(0)").children("li:nth-child("+(position+1)+")").size())var a=this.moved(tree_component.cut_copy.cut_nodes,obj.children("ul:eq(0)").children("li:nth-child("+(position+1)+")").children("a:eq(0)"),"before");else if(pos=="after"&&obj.children("ul:eq(0)").children("li:nth-child("+(position)+")").size())var a=this.moved(tree_component.cut_copy.cut_nodes,obj.children("ul:eq(0)").children("li:nth-child("+(position)+")").children("a:eq(0)"),"after");else if(obj.children("ul:eq(0)").children("li:nth-child("+(position+1)+")").size())var a=this.moved(tree_component.cut_copy.cut_nodes,obj.children("ul:eq(0)").children("li:nth-child("+(position+1)+")").children("a:eq(0)"),"before");else var a=this.moved(tree_component.cut_copy.cut_nodes,obj.children("ul:eq(0)").children("li:last").children("a:eq(0)"),"after");tree_component.cut_copy.cut_nodes=false}},search:function(str,func){var _this=this;if(!str||(this.srch&&str!=this.srch)){this.srch="";this.srch_opn=false;this.container.find("a.search").removeClass("search")}this.srch=str;if(!str)return;if(!func)func="contains";if(this.settings.data.async){if(!this.srch_opn){var dd=$.extend({"search":str},this.callback("beforedata",[false,this]));$.ajax({type:this.settings.data.opts.method,url:this.settings.data.opts.url,data:dd,dataType:"text",success:function(data){_this.srch_opn=$.unique(data.split(","));_this.search.apply(_this,[str,func])}})}else if(this.srch_opn.length){if(this.srch_opn&&this.srch_opn.length){var opn=false;for(var j=0;j<this.srch_opn.length;j++){if(this.get_node("#"+this.srch_opn[j]).size()>0){opn=true;var tmp="#"+this.srch_opn[j];delete this.srch_opn[j];this.open_branch(tmp,true,function(){_this.search.apply(_this,[str,func])})}}if(!opn){this.srch_opn=[];_this.search.apply(_this,[str,func])}}}else{this.srch_opn=false;var selector="a";if(this.settings.languages.length)selector+="."+this.current_lang;this.callback("onsearch",[this.container.find(selector+":"+func+"('"+str+"')"),this])}}else{var selector="a";if(this.settings.languages.length)selector+="."+this.current_lang;var nn=this.container.find(selector+":"+func+"('"+str+"')");nn.parents("li.closed").each(function(){_this.open_branch(this,true)});this.callback("onsearch",[nn,this])}},add_sheet:tree_component.add_sheet,destroy:function(){this.callback("ondestroy",[this]);this.container.unbind(".jstree");$("#"+this.container.attr("id")).die("click.jstree").die("dblclick.jstree").die("mouseover.jstree").die("mouseout.jstree").die("mousedown.jstree");this.container.removeClass("tree ui-widget ui-widget-content tree-default tree-"+this.settings.ui.theme_name).children("ul").removeClass("no_dots ltr locked").find("li").removeClass("leaf").removeClass("open").removeClass("closed").removeClass("last").children("a").removeClass("clicked hover search");if(this.cntr==tree_component.focused){for(var i in tree_component.inst){if(i!=this.cntr&&i!=this.container.attr("id")){tree_component.inst[i].focus();break}}}tree_component.inst[this.cntr]=false;tree_component.inst[this.container.attr("id")]=false;delete tree_component.inst[this.cntr];delete tree_component.inst[this.container.attr("id")];tree_component.cntr--}}};tree_component.cntr=0;tree_component.inst={};tree_component.themes=[];tree_component.drag_drop={isdown:false,drag_node:false,drag_help:false,dragged:false,init_x:false,init_y:false,moving:false,origin_tree:false,marker:false,move_type:false,ref_node:false,appended:false,foreign:false,droppable:[],open_time:false,scroll_time:false};tree_component.mouseup=function(event){var tmp=tree_component.drag_drop;if(tmp.open_time)clearTimeout(tmp.open_time);if(tmp.scroll_time)clearTimeout(tmp.scroll_time);if(tmp.moving&&$.tree.drag_end!==false)$.tree.drag_end.call(null,event,tmp);if(tmp.foreign===false&&tmp.drag_node&&tmp.drag_node.size()){tmp.drag_help.remove();if(tmp.move_type){var tree1=tree_component.inst[tmp.ref_node.parents(".tree:eq(0)").attr("id")];if(tree1)tree1.moved(tmp.dragged,tmp.ref_node,tmp.move_type,false,(tmp.origin_tree.settings.rules.drag_copy=="on"||(tmp.origin_tree.settings.rules.drag_copy=="ctrl"&&event.ctrlKey)))}tmp.move_type=false;tmp.ref_node=false}if(tmp.foreign!==false){if(tmp.drag_help)tmp.drag_help.remove();if(tmp.move_type){var tree1=tree_component.inst[tmp.ref_node.parents(".tree:eq(0)").attr("id")];if(tree1)tree1.callback("ondrop",[tmp.f_data,tree1.get_node(tmp.ref_node).get(0),tmp.move_type,tree1])}tmp.foreign=false;tmp.move_type=false;tmp.ref_node=false}if(tree_component.drag_drop.marker)tree_component.drag_drop.marker.hide();if(tmp.dragged&&tmp.dragged.size())tmp.dragged.removeClass("dragged");tmp.dragged=false;tmp.drag_help=false;tmp.drag_node=false;tmp.f_type=false;tmp.f_data=false;tmp.init_x=false;tmp.init_y=false;tmp.moving=false;tmp.appended=false;tmp.origin_tree=false;if(tmp.isdown){tmp.isdown=false;event.preventDefault();event.stopPropagation();return false}};tree_component.mousemove=function(event){var tmp=tree_component.drag_drop;var is_start=false;if(tmp.isdown){if(!tmp.moving&&Math.abs(tmp.init_x-event.pageX)<5&&Math.abs(tmp.init_y-event.pageY)<5){event.preventDefault();event.stopPropagation();return false}else{if(!tmp.moving){tree_component.drag_drop.moving=true;is_start=true}}if(tmp.open_time)clearTimeout(tmp.open_time);if(tmp.drag_help!==false){if(!tmp.appended){if(tmp.foreign!==false)tmp.origin_tree=$.tree.focused();$("body").append(tmp.drag_help);tmp.w=tmp.drag_help.width();tmp.appended=true}tmp.drag_help.css({"left":(event.pageX+5),"top":(event.pageY+15)})}if(is_start&&$.tree.drag_start!==false)$.tree.drag_start.call(null,event,tmp);if($.tree.drag!==false)$.tree.drag.call(null,event,tmp);if(event.target.tagName=="DIV"&&event.target.id=="jstree-marker")return false;var et=$(event.target);if(et.is("ins"))et=et.parent();var cnt=et.is(".tree")?et:et.parents(".tree:eq(0)");if(cnt.size()==0||!tree_component.inst[cnt.attr("id")]){if(tmp.scroll_time)clearTimeout(tmp.scroll_time);if(tmp.drag_help!==false)tmp.drag_help.find("li:eq(0) ins").addClass("forbidden");tmp.move_type=false;tmp.ref_node=false;tree_component.drag_drop.marker.hide();return false}var tree2=tree_component.inst[cnt.attr("id")];tree2.off_height();if(tmp.scroll_time)clearTimeout(tmp.scroll_time);tmp.scroll_time=setTimeout(function(){tree2.scroll_check(event.pageX,event.pageY)},50);var mov=false;var st=cnt.scrollTop();if(event.target.tagName=="A"||event.target.tagName=="INS"){if(et.is("#jstree-dragged"))return false;if(tree2.get_node(event.target).hasClass("closed")){tmp.open_time=setTimeout(function(){tree2.open_branch(et)},500)}var et_off=et.offset();var goTo={x:(et_off.left-1),y:(event.pageY-et_off.top)};var arr=[];if(goTo.y<tree2.li_height/3+1)arr=["before","inside","after"];else if(goTo.y>tree2.li_height*2/3-1)arr=["after","inside","before"];else{if(goTo.y<tree2.li_height/2)arr=["inside","before","after"];else arr=["inside","after","before"]}var ok=false;var nn=(tmp.foreign==false)?tmp.origin_tree.container.find("li.dragged"):tmp.f_type;$.each(arr,function(i,val){if(tree2.check_move(nn,et,val)){mov=val;ok=true;return false}});if(ok){switch(mov){case"before":goTo.y=et_off.top-2;tree_component.drag_drop.marker.attr("class","marker");break;case"after":goTo.y=et_off.top-2+tree2.li_height;tree_component.drag_drop.marker.attr("class","marker");break;case"inside":goTo.x-=2;goTo.y=et_off.top-2+tree2.li_height/2;tree_component.drag_drop.marker.attr("class","marker_plus");break}tmp.move_type=mov;tmp.ref_node=$(event.target);if(tmp.drag_help!==false)tmp.drag_help.find(".forbidden").removeClass("forbidden");tree_component.drag_drop.marker.css({"left":goTo.x,"top":goTo.y}).show()}}if((et.is(".tree")||et.is("ul"))&&et.find("li:eq(0)").size()==0){var et_off=et.offset();tmp.move_type="inside";tmp.ref_node=cnt.children("ul:eq(0)");if(tmp.drag_help!==false)tmp.drag_help.find(".forbidden").removeClass("forbidden");tree_component.drag_drop.marker.attr("class","marker_plus");tree_component.drag_drop.marker.css({"left":(et_off.left+10),"top":et_off.top+15}).show()}else if((event.target.tagName!="A"&&event.target.tagName!="INS")||!ok){if(tmp.drag_help!==false)tmp.drag_help.find("li:eq(0) ins").addClass("forbidden");tmp.move_type=false;tmp.ref_node=false;tree_component.drag_drop.marker.hide()}event.preventDefault();event.stopPropagation();return false}return true};$(function(){$(document).bind("mousemove.jstree",tree_component.mousemove);$(document).bind("mouseup.jstree",tree_component.mouseup)});tree_component.cut_copy={copy_nodes:false,cut_nodes:false};tree_component.css=false;tree_component.get_css=function(rule_name,delete_flag){rule_name=rule_name.toLowerCase();var css_rules=tree_component.css.cssRules||tree_component.css.rules;var j=0;do{if(css_rules.length&&j>css_rules.length+5)return false;if(css_rules[j].selectorText&&css_rules[j].selectorText.toLowerCase()==rule_name){if(delete_flag==true){if(tree_component.css.removeRule)document.styleSheets[i].removeRule(j);if(tree_component.css.deleteRule)document.styleSheets[i].deleteRule(j);return true}else return css_rules[j]}}while(css_rules[++j]);return false};tree_component.add_css=function(rule_name){if(tree_component.get_css(rule_name))return false;(tree_component.css.insertRule)?tree_component.css.insertRule(rule_name+' { }',0):tree_component.css.addRule(rule_name,null,0);return tree_component.get_css(rule_name)};tree_component.remove_css=function(rule_name){return tree_component.get_css(rule_name,true)};tree_component.add_sheet=function(opts){if(opts.str){var tmp=document.createElement("style");tmp.type="text/css";if(tmp.styleSheet)tmp.styleSheet.cssText=opts.str;else tmp.appendChild(document.createTextNode(opts.str));document.getElementsByTagName("head")[0].appendChild(tmp);return tmp.sheet}if(opts.url){if(document.createStyleSheet){try{document.createStyleSheet(opts.url)}catch(e){}}else{var newSS=document.createElement('link');newSS.rel='stylesheet';newSS.type='text/css';newSS.media="all";newSS.href=opts.url;document.getElementsByTagName("head")[0].appendChild(newSS);return newSS.styleSheet}}};$(function(){var u=navigator.userAgent.toLowerCase();var v=(u.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,'0'])[1];var css='/* TREE LAYOUT */ .tree ul { margin:0 0 0 5px; padding:0 0 0 0; list-style-type:none; } .tree li { display:block; min-height:18px; line-height:18px; padding:0 0 0 15px; margin:0 0 0 0; /* Background fix */ clear:both; } .tree li ul { display:none; } .tree li a, .tree li span { display:inline-block;line-height:16px;height:16px;color:black;white-space:nowrap;text-decoration:none;padding:1px 4px 1px 4px;margin:0; } .tree li a:focus { outline: none; } .tree li a input, .tree li span input { margin:0;padding:0 0;display:inline-block;height:12px !important;border:1px solid white;background:white;font-size:10px;font-family:Verdana; } .tree li a input:not([class="xxx"]), .tree li span input:not([class="xxx"]) { padding:1px 0; } /* FOR DOTS */ .tree .ltr li.last { float:left; } .tree > ul li.last { overflow:visible; } /* OPEN OR CLOSE */ .tree li.open ul { display:block; } .tree li.closed ul { display:none !important; } /* FOR DRAGGING */ #jstree-dragged { position:absolute; top:-10px; left:-10px; margin:0; padding:0; } #jstree-dragged ul ul ul { display:none; } #jstree-marker { padding:0; margin:0; line-height:5px; font-size:1px; overflow:hidden; height:5px; position:absolute; left:-45px; top:-30px; z-index:1000; background-color:transparent; background-repeat:no-repeat; display:none; } #jstree-marker.marker { width:45px; background-position:-32px top; } #jstree-marker.marker_plus { width:5px; background-position:right top; } /* BACKGROUND DOTS */ .tree li li { overflow:hidden; } .tree > .ltr > li { display:table; } /* ICONS */ .tree ul ins { display:inline-block; text-decoration:none; width:16px; height:16px; } .tree .ltr ins { margin:0 4px 0 0px; } ';if(/msie/.test(u)&&!/opera/.test(u)){if(parseInt(v)==6)css+='.tree li { height:18px; zoom:1; } .tree li li { overflow:visible; } .tree .ltr li.last { margin-top: expression( (this.previousSibling && /open/.test(this.previousSibling.className) ) ? "-2px" : "0"); } .marker { width:45px; background-position:-32px top; } .marker_plus { width:5px; background-position:right top; }';if(parseInt(v)==7)css+='.tree li li { overflow:visible; } .tree .ltr li.last { margin-top: expression( (this.previousSibling && /open/.test(this.previousSibling.className) ) ? "-2px" : "0"); }'}if(/opera/.test(u))css+='.tree > ul > li.last:after { content:"."; display: block; height:1px; clear:both; visibility:hidden; }';if(/mozilla/.test(u)&&!/(compatible|webkit)/.test(u)&&v.indexOf("1.8")==0)css+='.tree .ltr li a { display:inline; float:left; } .tree li ul { clear:both; }';tree_component.css=tree_component.add_sheet({str:css})})})(jQuery);(function($){$.extend($.tree.datastores,{"html":function(){return{get:function(obj,tree,opts){return obj&&$(obj).size()?$('<div>').append(tree.get_node(obj).clone()).html():tree.container.children("ul:eq(0)").html()},parse:function(data,tree,opts,callback){if(callback)callback.call(null,data);return data},load:function(data,tree,opts,callback){if(opts.url){$.ajax({'type':opts.method,'url':opts.url,'data':data,'dataType':"html",'success':function(d,textStatus){callback.call(null,d)},'error':function(xhttp,textStatus,errorThrown){callback.call(null,false);tree.error(errorThrown+" "+textStatus)}})}else{callback.call(null,opts.static||tree.container.children("ul:eq(0)").html())}}}},"json":function(){return{get:function(obj,tree,opts){var _this=this;if(!obj||$(obj).size()==0)obj=tree.container.children("ul").children("li");else obj=$(obj);if(!opts)opts={};if(!opts.outer_attrib)opts.outer_attrib=["id","rel","class"];if(!opts.inner_attrib)opts.inner_attrib=[];if(obj.size()>1){var arr=[];obj.each(function(){arr.push(_this.get(this,tree,opts))});return arr}if(obj.size()==0)return[];var json={attributes:{},data:{}};if(obj.hasClass("open"))json.data.state="open";if(obj.hasClass("closed"))json.data.state="closed";for(var i in opts.outer_attrib){if(!opts.outer_attrib.hasOwnProperty(i))continue;var val=(opts.outer_attrib[i]=="class")?obj.attr(opts.outer_attrib[i]).replace(/(^| )last( |$)/ig," ").replace(/(^| )(leaf|closed|open)( |$)/ig," "):obj.attr(opts.outer_attrib[i]);if(typeof val!="undefined"&&val.toString().replace(" ","").length>0)json.attributes[opts.outer_attrib[i]]=val;delete val}if(tree.settings.languages.length){for(var i in tree.settings.languages){if(!tree.settings.languages.hasOwnProperty(i))continue;var a=obj.children("a."+tree.settings.languages[i]);if(opts.force||opts.inner_attrib.length||a.children("ins").get(0).style.backgroundImage.toString().length||a.children("ins").get(0).className.length){json.data[tree.settings.languages[i]]={};json.data[tree.settings.languages[i]].title=tree.get_text(obj,tree.settings.languages[i]);if(a.children("ins").get(0).style.className.length){json.data[tree.settings.languages[i]].icon=a.children("ins").get(0).style.className}if(a.children("ins").get(0).style.backgroundImage.length){json.data[tree.settings.languages[i]].icon=a.children("ins").get(0).style.backgroundImage.replace("url(","").replace(")","")}if(opts.inner_attrib.length){json.data[tree.settings.languages[i]].attributes={};for(var j in opts.inner_attrib){if(!opts.inner_attrib.hasOwnProperty(j))continue;var val=a.attr(opts.inner_attrib[j]);if(typeof val!="undefined"&&val.toString().replace(" ","").length>0)json.data[tree.settings.languages[i]].attributes[opts.inner_attrib[j]]=val;delete val}}}else{json.data[tree.settings.languages[i]]=tree.get_text(obj,tree.settings.languages[i])}}}else{var a=obj.children("a");json.data.title=tree.get_text(obj);if(a.children("ins").size()&&a.children("ins").get(0).className.length){json.data.icon=a.children("ins").get(0).className}if(a.children("ins").size()&&a.children("ins").get(0).style.backgroundImage.length){json.data.icon=a.children("ins").get(0).style.backgroundImage.replace("url(","").replace(")","")}if(opts.inner_attrib.length){json.data.attributes={};for(var j in opts.inner_attrib){if(!opts.inner_attrib.hasOwnProperty(j))continue;var val=a.attr(opts.inner_attrib[j]);if(typeof val!="undefined"&&val.toString().replace(" ","").length>0)json.data.attributes[opts.inner_attrib[j]]=val;delete val}}}if(obj.children("ul").size()>0){json.children=[];obj.children("ul").children("li").each(function(){json.children.push(_this.get(this,tree,opts))})}return json},parse:function(data,tree,opts,callback){if(Object.prototype.toString.apply(data)==="[object Array]"){var str='';for(var i=0;i<data.length;i++){if(typeof data[i]=="function")continue;str+=this.parse(data[i],tree,opts)}if(callback)callback.call(null,str);return str}if(!data||!data.data){if(callback)callback.call(null,false);return""}var str='';str+="<li ";var cls=false;if(data.attributes){for(var i in data.attributes){if(!data.attributes.hasOwnProperty(i))continue;if(i=="class"){str+=" class='"+data.attributes[i]+" ";if(data.state=="closed"||data.state=="open")str+=" "+data.state+" ";str+="' ";cls=true}else str+=" "+i+"='"+data.attributes[i]+"' "}}if(!cls&&(data.state=="closed"||data.state=="open"))str+=" class='"+data.state+"' ";str+=">";if(tree.settings.languages.length){for(var i=0;i<tree.settings.languages.length;i++){var attr={};attr["href"]="";attr["style"]="";attr["class"]=tree.settings.languages[i];if(data.data[tree.settings.languages[i]]&&(typeof data.data[tree.settings.languages[i]].attributes).toLowerCase()!="undefined"){for(var j in data.data[tree.settings.languages[i]].attributes){if(!data.data[tree.settings.languages[i]].attributes.hasOwnProperty(j))continue;if(j=="style"||j=="class")attr[j]+=" "+data.data[tree.settings.languages[i]].attributes[j];else attr[j]=data.data[tree.settings.languages[i]].attributes[j]}}str+="<a";for(var j in attr){if(!attr.hasOwnProperty(j))continue;str+=' '+j+'="'+attr[j]+'" '}str+=">";if(data.data[tree.settings.languages[i]]&&data.data[tree.settings.languages[i]].icon){str+="<ins "+(data.data[tree.settings.languages[i]].icon.indexOf("/")==-1?" class='"+data.data[tree.settings.languages[i]].icon+"' ":" style='background-image:url(\""+data.data[tree.settings.languages[i]].icon+"\");' ")+">&nbsp;</ins>"}else str+="<ins>&nbsp;</ins>";str+=((typeof data.data[tree.settings.languages[i]].title).toLowerCase()!="undefined"?data.data[tree.settings.languages[i]].title:data.data[tree.settings.languages[i]])+"</a>"}}else{var attr={};attr["href"]="";attr["style"]="";attr["class"]="";if((typeof data.data.attributes).toLowerCase()!="undefined"){for(var i in data.data.attributes){if(!data.data.attributes.hasOwnProperty(i))continue;if(i=="style"||i=="class")attr[i]+=" "+data.data.attributes[i];else attr[i]=data.data.attributes[i]}}str+="<a";for(var i in attr){if(!attr.hasOwnProperty(i))continue;str+=' '+i+'="'+attr[i]+'" '}str+=">";if(data.data.icon){str+="<ins "+(data.data.icon.indexOf("/")==-1?" class='"+data.data.icon+"' ":" style='background-image:url(\""+data.data.icon+"\");' ")+">&nbsp;</ins>"}else str+="<ins>&nbsp;</ins>";str+=((typeof data.data.title).toLowerCase()!="undefined"?data.data.title:data.data)+"</a>"}if(data.children&&data.children.length){str+='<ul>';for(var i=0;i<data.children.length;i++){str+=this.parse(data.children[i],tree,opts)}str+='</ul>'}str+="</li>";if(callback)callback.call(null,str);return str},load:function(data,tree,opts,callback){if(opts.static){callback.call(null,opts.static)}else{$.ajax({'type':opts.method,'url':opts.url,'data':data,'dataType':"json",'success':function(d,textStatus){callback.call(null,d)},'error':function(xhttp,textStatus,errorThrown){callback.call(null,false);tree.error(errorThrown+" "+textStatus)}})}}}}})})(jQuery);
\ No newline at end of file
diff --git a/webconsole-plugins/useradmin/src/main/resources/res/jsTree.v.0.9.9a/themes/themeroller/dot_for_ie.gif b/webconsole-plugins/useradmin/src/main/resources/res/jsTree.v.0.9.9a/themes/themeroller/dot_for_ie.gif
new file mode 100644
index 0000000..c0cc5fd
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/res/jsTree.v.0.9.9a/themes/themeroller/dot_for_ie.gif
Binary files differ
diff --git a/webconsole-plugins/useradmin/src/main/resources/res/jsTree.v.0.9.9a/themes/themeroller/icons.png b/webconsole-plugins/useradmin/src/main/resources/res/jsTree.v.0.9.9a/themes/themeroller/icons.png
new file mode 100644
index 0000000..b12618a
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/res/jsTree.v.0.9.9a/themes/themeroller/icons.png
Binary files differ
diff --git a/webconsole-plugins/useradmin/src/main/resources/res/jsTree.v.0.9.9a/themes/themeroller/style.css b/webconsole-plugins/useradmin/src/main/resources/res/jsTree.v.0.9.9a/themes/themeroller/style.css
new file mode 100644
index 0000000..4b2c6a0
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/res/jsTree.v.0.9.9a/themes/themeroller/style.css
@@ -0,0 +1,39 @@
+/* LOCKED */

+.tree-themeroller .locked li a { color:gray; }

+/* DOTS */

+.tree-themeroller ul { background-position:6px 1px; background-repeat:repeat-y; background-image:url(data:image/gif;base64,R0lGODlhAgACAIAAAB4dGf///yH5BAEAAAEALAAAAAACAAIAAAICRF4AOw==); _background-image:url("dot_for_ie.gif"); *background-image:url("dot_for_ie.gif"); }

+.tree-themeroller li { background-position:-64px -16px; background-repeat:no-repeat; background-image:url("icons.png"); }

+/* NO DOTS */

+.tree-themeroller .no_dots, .tree-themeroller .no_dots ul { background:transparent; }

+.tree-themeroller .no_dots li.leaf { background-image:none; background-color:transparent; }

+/* OPEN or CLOSED */

+.tree-themeroller li.open { background:url("icons.png") -32px -48px no-repeat; }

+.tree-themeroller li.closed, #jstree-dragged.tree-themeroller li li.open { background:url("icons.png") -48px -32px no-repeat; }

+#jstree-marker { background-image:url("icons.png"); }

+

+.tree-themeroller li, .tree-themeroller li a, .tree-themeroller li a ins { line-height:16px !important; }

+.tree-themeroller li a .ui-icon { overflow:visible; }

+

+/* DEFAULT, HOVER, CLICKED, LOADING STATES 

+.tree-themeroller li a, .tree-themeroller li span { border-radius:3px; -moz-border-radius:3px; -webkit-border-radius:3px; }

+.tree-themeroller li a:hover, .tree-themeroller li a.hover, .tree-themeroller li span { background: #e7f4f9; border:1px solid #d8f0fa; padding:0px 3px 0px 3px; }

+.tree-themeroller li a.clicked, .tree-themeroller li a.clicked:hover, .tree-themeroller li span.clicked { background: #beebff; border:1px solid #99defd; padding:0px 3px 0px 3px; }

+*/

+/* ICONS */

+.tree-themeroller ul li a.loading ins { background-image:url("throbber.gif") !important; background-position:0 0 !important; } /* UL is added to make selector stronger */

+/*

+.tree-themeroller ins { background-image:url("icons.png"); background-position:0 0; background-repeat:no-repeat; }

+.tree-themeroller li a ins.forbidden { background-position:-16px -16px; }

+.tree-themeroller .locked li a ins { background-position:0 -48px; }

+.tree-themeroller li span ins { background-position:-16px 0; }

+*/

+

+#jstree-dragged.tree-themeroller ins { background:url("icons.png") -16px -32px no-repeat; }

+#jstree-dragged.tree-themeroller ins.forbidden { background:url("icons.png") -16px -16px no-repeat; }

+

+/* CONTEXT MENU 

+.tree-themeroller-context a ins { background-image:url("icons.png"); background-repeat:no-repeat; background-position:-64px -64px; }

+.tree-themeroller-context a ins.create { background-position:0 -16px; }

+.tree-themeroller-context a ins.rename { background-position:-16px 0px; }

+.tree-themeroller-context a ins.remove { background-position:0 -32px; }

+*/
\ No newline at end of file
diff --git a/webconsole-plugins/useradmin/src/main/resources/res/jsTree.v.0.9.9a/themes/themeroller/throbber.gif b/webconsole-plugins/useradmin/src/main/resources/res/jsTree.v.0.9.9a/themes/themeroller/throbber.gif
new file mode 100644
index 0000000..95ff649
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/res/jsTree.v.0.9.9a/themes/themeroller/throbber.gif
Binary files differ
diff --git a/webconsole-plugins/useradmin/src/main/resources/res/json2.min.js b/webconsole-plugins/useradmin/src/main/resources/res/json2.min.js
new file mode 100644
index 0000000..2360c34
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/res/json2.min.js
@@ -0,0 +1,29 @@
+/* http://www.JSON.org/json2.js */

+if(!this.JSON){this.JSON={};}

+(function(){function f(n){return n<10?'0'+n:n;}

+if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+

+f(this.getUTCMonth()+1)+'-'+

+f(this.getUTCDate())+'T'+

+f(this.getUTCHours())+':'+

+f(this.getUTCMinutes())+':'+

+f(this.getUTCSeconds())+'Z':null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}

+var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}

+function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}

+if(typeof rep==='function'){value=rep.call(holder,key,value);}

+switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}

+gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}

+v=partial.length===0?'[]':gap?'[\n'+gap+

+partial.join(',\n'+gap)+'\n'+

+mind+']':'['+partial.join(',')+']';gap=mind;return v;}

+if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==='string'){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}

+v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+

+mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}

+if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}

+rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}

+return str('',{'':value});};}

+if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}

+return reviver.call(holder,key,value);}

+text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+

+('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}

+if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}

+throw new SyntaxError('JSON.parse');};}}());
\ No newline at end of file
diff --git a/webconsole-plugins/useradmin/src/main/resources/res/plugin.css b/webconsole-plugins/useradmin/src/main/resources/res/plugin.css
new file mode 100644
index 0000000..9ec5d94
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/res/plugin.css
@@ -0,0 +1,10 @@
+/* your css definitions here */

+#userTree { width: 20% }

+#userTree li a { padding-left: 12px ! important}

+.header ul { float: right }

+#roleDetails .actions { width: 32px }

+input.k, input.v { width: 100% }

+#roleDetails .property-type {width: 5em}

+.actions ul { float : right }

+#newDialogRole select { width : 100% }

+.required { font-style:italic }

diff --git a/webconsole-plugins/useradmin/src/main/resources/res/plugin.html b/webconsole-plugins/useradmin/src/main/resources/res/plugin.html
new file mode 100644
index 0000000..f0563a6
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/res/plugin.html
@@ -0,0 +1,125 @@
+<script type="text/javascript" src="${pluginRoot}/res/jsTree.v.0.9.9a/jquery.tree.min.js"></script>
+<script type="text/javascript" src="${pluginRoot}/res/crypto-js-3.0.2/core-min.js"></script>
+<script type="text/javascript" src="${pluginRoot}/res/crypto-js-3.0.2/x64-core-min.js"></script>
+<script type="text/javascript" src="${pluginRoot}/res/crypto-js-3.0.2/md5-min.js"></script>
+<script type="text/javascript" src="${pluginRoot}/res/crypto-js-3.0.2/sha1-min.js"></script>
+<script type="text/javascript" src="${pluginRoot}/res/crypto-js-3.0.2/sha256-min.js"></script>
+<script type="text/javascript" src="${pluginRoot}/res/crypto-js-3.0.2/sha512-min.js"></script>
+<script type="text/javascript" src="${pluginRoot}/res/json2.min.js"></script>
+<script type="text/javascript" src="${pluginRoot}/res/plugin.js"></script>
+<script type="text/javascript">
+// <![CDATA[
+var i18n = {
+	abort : '${abort}',
+	close : '${abort}',
+	add   : '${save}',
+	root  : '${role.tree.root}',
+	status: '${role.statline}'
+}
+// ]]>
+</script>
+
+<!-- status line -->
+<p class="statline">&nbsp;</p>
+
+<!-- table caption -->
+<form method="post" action="${pluginRoot}">
+	<div class="ui-widget-header ui-corner-top buttonGroup">
+		<button id="newRole">${role.new}</button>
+		<button id="reload">${reload}</button>
+	</div>
+</form>
+
+<table class="nicetable">
+	<tr>
+		<td id="userTree">-</td>
+		<td id="roleDetails">
+			<table class="nicetable ui-helper-hidden">
+				<thead class="ui-widget-header ">
+					<tr>
+						<td class="property-name">${role.key}</td>
+						<td class="property-value">${role.value}</td>
+						<td class="property-type">${type}</td>
+						<td class="actions">${bundles.actions}</td>
+					</tr>
+				</thead>
+				<tfoot class="ui-widget-header">
+					<tr>
+						<td colspan="4">
+							<button id="delRole">${delete}</button> 
+							<button id="savRole">${save}</button>
+						</td>
+					</tr>
+				</tfoot>
+				<tbody>
+					<tr class="ui-priority-primary header header-props">
+						<td colspan="4" class="">
+							${role.properties}
+							<ul class="icons">
+								<li class="dynhover">
+									<span class="ui-icon ui-icon-plus">&nbsp;</span>
+								</li>
+							</ul>
+						</td>
+					</tr>
+					<tr class="ui-priority-primary header header-cred">
+						<td colspan="4">
+							${role.credentials}
+							<ul class="icons">
+								<li class="dynhover">
+									<span class="ui-icon ui-icon-plus">&nbsp;</span>
+								</li>
+							</ul>
+						</td>
+					</tr>
+					<tr>
+						<td><input class="k" /></td>
+						<td><input class="v" /></td>
+						<td>
+							<select class="dynhover">
+								<option value="string">${type.string}</option>
+								<option value="byte[]">${type.bytes}</option>
+								<option value="password-MD5">${type.password-MD5}</option>
+								<option value="password-SHA1">${type.password-SHA1}</option>
+								<option value="password-SHA256">${type.password-SHA256}</option>
+								<option value="password-SHA512">${type.password-SHA512}</option>
+							</select>
+						</td>
+						<td class="actions">
+							<ul class="icons">
+								<li class="dynhover">
+									<span class="ui-icon ui-icon-trash">&nbsp;</span>
+								</li>
+							</ul>
+						</td>
+					</tr>
+				</tbody>
+			</table>
+			<div id="roleDetailsHelp">${role.help.initial}</div>
+		</td>
+	</tr>
+</table>
+
+<div class="ui-helper-hidden1" title="${role.new.title}" id="newDialogRole">
+	<table class="nicetable">
+		<tr>
+			<td class="label">
+				${role.name}
+			</td>
+			<td>
+				<input/>
+			</td>
+		</tr>
+		<tr>
+			<td class="label">
+				${type}
+			</td>
+			<td>
+				<select class="dynhover">
+					<option value="1">${role.type.1}</option>
+					<option value="2">${role.type.2}</option>
+				</select>
+			</td>
+		</tr>
+	</table>
+</div>
diff --git a/webconsole-plugins/useradmin/src/main/resources/res/plugin.js b/webconsole-plugins/useradmin/src/main/resources/res/plugin.js
new file mode 100644
index 0000000..d474482
--- /dev/null
+++ b/webconsole-plugins/useradmin/src/main/resources/res/plugin.js
@@ -0,0 +1,372 @@
+/* your java script code here */

+

+var userTree = false;

+var selectedRole = false;

+var newDialogRole = false;

+var roleDetails = false;

+var roleDetailsHelp = false;

+var roleDetailsTable = false;

+var roleDetailsBody = false;

+var roleDetailsTemplate = false;

+var roleDetailsTemplateP = false;

+var roleDetailsTemplateC = false;

+

+function roleObj(node) {

+	node = node && node.attr ? node.attr('role') : false;

+	return node ? JSON.parse(node) : false;

+}

+

+var treeSettings = {

+	data : {

+		type : 'json',

+		opts : { 'static' : [] }

+	},

+	ui       : { theme_name : 'themeroller' },

+	rules    : { multiple : false, valid_children: ['root'] },

+	types    : {

+		root : { valid_children: ['t0', 't1', 't2'] },

+		t2   : { valid_children: ['t0', 't1', 't2'] },

+		t1   : { valid_children: 'none' },

+		t0   : { valid_children: 'none' }

+	},

+	callback : {

+		onselect : function(node) {

+			var _role = $(node).attr('role');

+			if (_role) {

+				var role = JSON.parse( _role );

+				onSelectNode(role.name);

+				$(node).children('a').addClass('ui-priority-primary');

+			} else {

+				roleDetailsHelp.removeClass('ui-helper-hidden');

+				roleDetailsTable.addClass('ui-helper-hidden');

+			}

+		},

+		onparse : function (s, t) {

+			return $(s)

+					.find('li[rel=t2] > a > ins').addClass('ui-icon ui-icon-contact').end()

+					.find('li[rel=t1] > a > ins').addClass('ui-icon ui-icon-person').end()

+					.find('li[rel=t0] > a > ins').addClass('ui-icon ui-icon-bullet').end();

+		},

+		ondeselect : function(node) { $(node).children('a').removeClass('ui-priority-primary') },

+		ondblclk   : function(node, tree_obj) {

+			var n = $(node);

+			var pp = tree_obj.parent(node);

+			var r = roleObj(n);

+			var g = roleObj(pp);

+			console.log(r, g);

+			if (r && g) {

+				if( isInMemberArray(r, g.members, 1) ) {

+					$.post(pluginRoot, { action: 'removeMember', role: r.name, group: g.name });

+					$.post(pluginRoot, { action: 'addRequiredMember', role: r.name, group: g.name }, function(data) {

+						pp.attr('role', JSON.stringify(data));

+					}, 'json');

+					n.addClass('required');

+				} else if( isInMemberArray(r, g.rmembers, 1) ) {

+					$.post(pluginRoot, { action: 'removeMember', role: r.name, group: g.name });

+					$.post(pluginRoot, { action: 'addMember', role: r.name, group: g.name }, function(data) {

+						pp.attr('role', JSON.stringify(data));

+					}, 'json');

+					n.removeClass('required');

+				}

+			}

+		},

+		beforemove : function(node, ref_node, type, tree_obj, is_copy) {

+			var _ = dragObj(node, ref_node, type, tree_obj);

+			// --- check if the move is valid:

+			// don't move things around the same/root level

+			if (_.to == false && _.from == false) return false;

+			// no copy to the root folder

+			if (is_copy && _.to == false) return false;

+			// no rearrange withing the folder

+			if (_.to != false && _.from != false && _.to.name == _.from.name) return false;

+			// already contains such a member

+			if (_.to != false && isMember(_.node, _.to)) return false;

+

+			// do copy-move

+			// unassign from the old group, if it is move

+			if (!is_copy && _.from) $.post(pluginRoot, {'action': 'removeMember', 'role' : _.node.name, 'group' : _.from.name} , function(data) {}, 'json');

+			// assign to the new group

+			if (_.to) $.post(pluginRoot, {'action': 'addMember', 'role' : _.node.name, 'group' : _.to.name} , function(data) {}, 'json');

+

+			return true;

+		}

+	}

+}

+

+$(function() {

+	userTree = $('#userTree');

+	roleDetails = $('#roleDetails');

+	roleDetailsTable = roleDetails.find('table');

+	roleDetailsHelp = roleDetails.find('#roleDetailsHelp');

+	roleDetailsBody = roleDetailsTable.find('tbody');

+	roleDetailsTemplateP = roleDetailsBody.find('tr:eq(0)');

+	roleDetailsTemplateC = roleDetailsBody.find('tr:eq(1)');

+	roleDetailsTemplate = roleDetailsBody.find('tr:eq(2)').clone();

+	roleDetailsBody.find('tr').not('.header').remove();

+

+	// add new property/credential code

+	$('tr.header span.ui-icon-plus').click(function() {

+		$(this).parent().parent().parent().parent().after(newProp());

+	});

+

+	// new role dialog

+	var _buttons = {};

+	_buttons[i18n.close] = function() {

+		$(this).dialog('close');

+	}

+	_buttons[i18n.add] = function() {

+		var _ = newDialogRole;

+		var n = _.find('input');

+		if (!n.val()) {

+			n.addClass('ui-state-error');

+			return false;

+		} else n.removeClass('ui-state-error');

+		var t = _.find('select').val();

+		$.post(pluginRoot, {'action': 'set', 'data' : JSON.stringify({'name': n.val(), 'type': new Number(t)})} , function(data) {

+			_.dialog('close');

+			$('#reload').click();

+		}, 'json');

+	}

+	newDialogRole = $("#newDialogRole").dialog({

+		autoOpen : false,

+		modal    : true,

+		open     : function() { $(this).find('input').val('').removeClass('ui-state-error') },

+		closeText: i18n.abort,

+		buttons  : _buttons

+	});

+

+	// role info buttons

+	$('#delRole').click( function() {

+		if (selectedRole) $.post(pluginRoot, {'action': 'del', 'role' : selectedRole}, function() {

+			$('#reload').click();

+		});

+	});

+	$('#savRole').click( doSaveRole );

+

+	// top-frame buttons

+	$('#newRole').click( function() {

+		newDialogRole.dialog('open');

+		return false;

+	});

+	$('#reload').click( function() {

+		$.post(pluginRoot, {'action': 'list'} , function(data) {

+			roleDetailsHelp.removeClass('ui-helper-hidden');

+			roleDetailsTable.addClass('ui-helper-hidden');

+

+			var sortedGroups = sortGroups(data);

+			var treeRoot = buildTree(sortedGroups);

+

+			treeSettings.data.opts['static'] = treeRoot;

+			userTree.empty().tree(treeSettings);

+		}, 'json');

+		return false;

+	}).click();

+});

+

+function newProp() {

+	var tr = roleDetailsTemplate.clone()

+		.find('li').click( function() {

+			tr.remove();

+		}).end()

+		.find('select').change( function(evt) {

+			tr.find('.v').replaceWith('<input class="v" '+ ($(this).val().indexOf('password') == 0 ? 'type="password"' : '') + '/>');

+			initStaticWidgets(tr);

+		}).end()

+	initStaticWidgets(tr);

+	return tr;

+}

+function hashToArray(s) {

+    var r = [];

+    while(s.length > 0) {

+        r.push(parseInt(s.substring(0, 2), 16));

+        s = s.substring(2);

+    }

+    return r;

+}

+function strToArray(s) {

+    var r = [];

+    var el = s.split(',');

+    for(var i=0;i<el.length;i++) r.push( parseInt(el[i], 10) );

+    return r;

+}

+function doSaveRole() {

+	if (!selectedRole) return;

+	var doProps = true;

+	var data = {

+		name : selectedRole,

+		properties : {},

+		credentials : {}

+	};

+	roleDetailsBody.find('tr').each( function() {

+		var _ = $(this);

+		if (_.hasClass('header-props')) doProps = true;

+		else if (_.hasClass('header-cred')) doProps = false;

+		else {

+			var k = _.find('.k').val();

+			var v = _.find('.v').val();

+			var t = _.find('select').val();

+			

+			if (t.indexOf('password-') == 0) {

+				var hash =  CryptoJS[t.substring(9)](v).toString(CryptoJS.enc.Hex);

+				v = hashToArray(hash);

+			} else if (t == 'byte[]') {

+				v = strToArray(v);

+			}

+			

+			if (doProps) data.properties[k] = v;

+			else data.credentials[k] = v;

+		}

+	});

+	$.post(pluginRoot, {'action': 'set', 'data' : JSON.stringify(data)});

+}

+

+function isInMemberArray(role, g) {

+	if(g) for(var i in g) if (g[i].name == role.name) return true;

+	return false;

+}

+

+function isMember(role, group) {

+	if (!role) return false;

+	if (!group) return false;

+	if (isInMemberArray(role, group.members)) return true;

+	if (isInMemberArray(role, group.rmembers)) return true;

+}

+

+function buildTree(sortedGroups) {

+	var treeRoot = {

+		data : i18n.root,

+		state: 'open',

+		attributes : { 'rel' : 'root' },

+		children: []

+	};

+	var treeNode = function(name, role, parent, req) {

+		if (!role) return;

+		if (!parent) parent = treeRoot.children;

+		var node = {

+			data  : role.name,

+			attributes : {

+				'rel'   : 't' + role.type,

+				'role'  : JSON.stringify(role)

+			}

+		}

+		if (req) node.attributes['class'] = 'required';

+		parent.push(node);

+		if (role.type == 2) {

+			node['children'] = [];

+			node = node['children'];

+			if (role.members) $.each(role.members, function(idx, role) {

+				treeNode(role.name, role, node, 0);

+			});

+			if (role.rmembers) $.each(role.rmembers, function(idx, role) {

+				treeNode(role.name, role, node, 1);

+			});

+		}

+	}

+

+	$.each(sortedGroups, treeNode);

+	return treeRoot;

+}

+

+function sortGroups(data) {

+	var rootGroups = {}; // only root groups - without parents

+	var unassigned = {}; // non-groups, not assigned to any group

+	var processed = {}; // all processed entries

+	var u = 0;

+	var g = 0;

+	var r = 0;

+

+	var _st = function(map, n, role) {

+		if (typeof map[n] == 'undefined') { // not added - add

+			map[n] = role;

+		} else if (map[n] != false) { // already added

+			map[n] = false; // mark for removal

+		}

+	}

+

+	var groupF = function(i1, role) {

+		var n = role.name;

+		var t = role.type;

+

+		if (t == 2) { // group

+			// don't process twice

+			if (processed[n]) {

+				rootGroups[n] = false;

+				return true;

+			}

+			processed[n]=role;

+

+			_st(rootGroups, n, role);

+

+			if (role.members) $.each(role.members, groupF);

+			if (role.rmembers) $.each(role.rmembers, groupF);

+			g++;

+		} else { // role or user

+			if (t == 1) u++; else r++;

+			_st(unassigned, n, role);

+		}

+	}

+

+	$.each(data, groupF);

+	$('.statline').text( i18n.status.msgFormat(g,u,r) );

+

+	return $.extend(rootGroups, unassigned);

+}

+

+function onSelectNode(role) {

+	$.post(pluginRoot, {'action': 'get', 'role' : role} , function(data) {

+		selectedRole = role;

+		roleDetailsHelp.addClass('ui-helper-hidden');

+		roleDetailsTable.removeClass('ui-helper-hidden');

+		roleDetailsBody.find('tr').not('.header').remove();

+

+		var target = false;

+		var _append = function(k,v) {

+			var t = $.isArray(v) ? 'byte[]' : 'string';

+			target.after(newProp()

+				.data('k', k)

+				.find('input.k').val(k).end()

+				.find('input.v').val(v).end()

+				.find('select').val(t).end()

+			);

+		}

+		var x = data.properties;

+		if (x) {

+			target = roleDetailsTemplateP;

+			$.each(x, _append);

+		}

+		x = data.credentials;

+		if (x) {

+			target = roleDetailsTemplateC;

+			$.each(x, _append);

+		}

+		// show/user credentials view if user/or not (respectively)

+		x = roleDetailsBody.find('.header-cred');

+		if (data.type != 1) x.addClass('ui-helper-hidden');

+		else x.removeClass('ui-helper-hidden');

+	}, 'json')

+	return false;

+}

+

+function dragObj(node, ref_node, type, tree_obj) {

+    // determine the destination folder

+	var _role = false;

+	if ('inside' == type) {

+		_role = $(ref_node).attr('role');

+	} else {

+		_role = tree_obj.parent(ref_node)

+		_role = _role.attr ? _role.attr('role') : false;

+	}

+	var to = _role ? JSON.parse(_role) : false;

+	// determine object to move

+	_role = $(node).attr('role');

+	var source =  JSON.parse(_role);

+	// determine the previous location (in case it is move, not copy)

+	_role = tree_obj.parent(node);

+	var from = _role.attr && _role.attr('role') ? JSON.parse(_role.attr('role')) : false;

+

+	return {

+		'to' : to,

+		'from' : from,

+		'node' : source

+	}

+}