You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by im...@apache.org on 2014/12/13 05:19:28 UTC

[1/8] stratos git commit: application editor partial added

Repository: stratos
Updated Branches:
  refs/heads/4.1.0-test 2f7d4aaf8 -> 55e0d8444


application editor partial added


Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/3aab09eb
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/3aab09eb
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/3aab09eb

Branch: refs/heads/4.1.0-test
Commit: 3aab09eb1c7691c86c8c198294f5d498ba369875
Parents: 2f7d4aa
Author: Dakshika Jayathilaka <si...@gmail.com>
Authored: Thu Dec 11 16:55:54 2014 +0530
Committer: Imesh Gunaratne <im...@apache.org>
Committed: Sat Dec 13 09:45:23 2014 +0530

----------------------------------------------------------------------
 .../console/applications_form.jag               |   7 +-
 .../theme0/partials/applications_editor.hbs     |   0
 .../theme0/renderers/applications_form.js       | 104 +++++++++++++++----
 3 files changed, 89 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/3aab09eb/components/org.apache.stratos.manager.console/console/applications_form.jag
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/applications_form.jag b/components/org.apache.stratos.manager.console/console/applications_form.jag
index c4f5b6a..66071da 100644
--- a/components/org.apache.stratos.manager.console/console/applications_form.jag
+++ b/components/org.apache.stratos.manager.console/console/applications_form.jag
@@ -33,7 +33,7 @@ var log = new Log("apachestratos.applications_form"),
         elements = uriMatcher.match('/{context}/applications/{formtype}/'),
         breadcrumbPathLevelOne = 'applications',
         formDataEdit = topology_data = '',
-        isEdit = applicationView = isForm = false,
+        isEdit = applicationView = applicationEditor= isForm = false,
         userPermissions = session.get('PERMISSIONS');
 
 //create left menu
@@ -47,6 +47,8 @@ if (!elements) {
     if (elements.formtype == 'applications' && elements.action != 'new') {
         applicationView = true;
         topology_data = util.RESTCalls.getApplicationTopology(elements.action);
+    }else if(elements.formtype == 'applications' && elements.action == 'new'){
+        applicationEditor = true;
     }else  if(elements.action != 'new'){
         isEdit = true;
     }
@@ -112,7 +114,8 @@ var caramelData = {
     appName: elements.action,
     topology_data: JSON.stringify(topology_data),
     applicationView: applicationView,
-    formTitle: formTitle,
+    applicationEditor: applicationEditor,
+formTitle: formTitle,
     formDataRaw: JSON.stringify(formDataRaw),
     //formDataRaw: JSON.stringify(partition_data.partition[0]),
     formDataEdit: JSON.stringify(formDataEdit),

http://git-wip-us.apache.org/repos/asf/stratos/blob/3aab09eb/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs b/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/stratos/blob/3aab09eb/components/org.apache.stratos.manager.console/console/themes/theme0/renderers/applications_form.js
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/renderers/applications_form.js b/components/org.apache.stratos.manager.console/console/themes/theme0/renderers/applications_form.js
index fd23107..2a7d8fe 100644
--- a/components/org.apache.stratos.manager.console/console/themes/theme0/renderers/applications_form.js
+++ b/components/org.apache.stratos.manager.console/console/themes/theme0/renderers/applications_form.js
@@ -22,7 +22,7 @@ var render = function (theme, data, meta, require) {
 
     if(data.error.length === 0 ){
 
-        if(data.applicationView == true){
+        if(data.applicationView == true) {
             theme('index', {
                 page_meta: [
                     {
@@ -33,42 +33,42 @@ var render = function (theme, data, meta, require) {
                         }
                     }
                 ],
-                header:[
+                header: [
                     {
                         partial: 'index_header',
-                        context:{
+                        context: {
                         }
                     }
                 ],
-                sub_header:[
+                sub_header: [
                     {
-                        partial:'index_sub_header',
-                        context:{
-                            breadcrumbPathLevelOne:data.breadcrumbPathLevelOne,
-                            breadcrumbPathLevelTwo:data.breadcrumbPathLevelTwo
+                        partial: 'index_sub_header',
+                        context: {
+                            breadcrumbPathLevelOne: data.breadcrumbPathLevelOne,
+                            breadcrumbPathLevelTwo: data.breadcrumbPathLevelTwo
                         }
                     }
                 ],
-                left_menu:[
+                left_menu: [
                     {
-                        partial:'index_left_menu',
-                        context:{
-                            left_menu:data.left_menu
+                        partial: 'index_left_menu',
+                        context: {
+                            left_menu: data.left_menu
                         }
                     }
                 ],
-                right_menu_help:[
+                right_menu_help: [
                     {
-                        partial:'index_right_menu_help',
-                        context:{
+                        partial: 'index_right_menu_help',
+                        context: {
 
                         }
                     }
                 ],
                 content: [
                     {
-                        partial:'applications_topology',
-                        context:{
+                        partial: 'applications_topology',
+                        context: {
                             formContext: data.breadcrumbPathLevelTwo,
                             appName: data.appName,
                             topology_data: data.topology_data,
@@ -78,10 +78,74 @@ var render = function (theme, data, meta, require) {
                             formDataRaw: data.formDataRaw,
                             formDataEdit: data.formDataEdit,
                             isForm: data.isForm,
-                            isEdit:data.isEdit,
+                            isEdit: data.isEdit,
                             formTitle: data.formTitle,
-                            content_body: {sections:
-                                data.list_data
+                            content_body: {sections: data.list_data
+                            }
+                        }
+                    }
+
+                ]
+            });
+        }else if(data.applicationEditor == true){
+            theme('index', {
+                page_meta: [
+                    {
+                        partial: 'index_title',
+                        context: {
+                            page_title: 'Apache Stratos - Application Managment',
+                            page_description: 'Apache Stratos - Application Managment'
+                        }
+                    }
+                ],
+                header: [
+                    {
+                        partial: 'index_header',
+                        context: {
+                        }
+                    }
+                ],
+                sub_header: [
+                    {
+                        partial: 'index_sub_header',
+                        context: {
+                            breadcrumbPathLevelOne: data.breadcrumbPathLevelOne,
+                            breadcrumbPathLevelTwo: data.breadcrumbPathLevelTwo
+                        }
+                    }
+                ],
+                left_menu: [
+                    {
+                        partial: 'index_left_menu',
+                        context: {
+                            left_menu: data.left_menu
+                        }
+                    }
+                ],
+                right_menu_help: [
+                    {
+                        partial: 'index_right_menu_help',
+                        context: {
+
+                        }
+                    }
+                ],
+                content: [
+                    {
+                        partial: 'applications_editor',
+                        context: {
+                            formContext: data.breadcrumbPathLevelTwo,
+                            appName: data.appName,
+                            topology_data: data.topology_data,
+                            form_action: data.form_action,
+                            formHtml: data.formHtml,
+                            formData: data.formData,
+                            formDataRaw: data.formDataRaw,
+                            formDataEdit: data.formDataEdit,
+                            isForm: data.isForm,
+                            isEdit: data.isEdit,
+                            formTitle: data.formTitle,
+                            content_body: {sections: data.list_data
                             }
                         }
                     }


[3/8] stratos git commit: fix groups listing with new JSON return

Posted by im...@apache.org.
fix groups listing with new JSON return


Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/5150a8be
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/5150a8be
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/5150a8be

Branch: refs/heads/4.1.0-test
Commit: 5150a8be8b92a0e9110dde791a03359a65f26a57
Parents: 3aab09e
Author: Dakshika Jayathilaka <si...@gmail.com>
Authored: Thu Dec 11 23:06:26 2014 +0530
Committer: Imesh Gunaratne <im...@apache.org>
Committed: Sat Dec 13 09:45:24 2014 +0530

----------------------------------------------------------------------
 .../console/applications_form.jag                        | 11 ++++++-----
 .../console/themes/theme0/partials/applications_form.hbs |  2 +-
 2 files changed, 7 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/5150a8be/components/org.apache.stratos.manager.console/console/applications_form.jag
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/applications_form.jag b/components/org.apache.stratos.manager.console/console/applications_form.jag
index 66071da..91d01b3 100644
--- a/components/org.apache.stratos.manager.console/console/applications_form.jag
+++ b/components/org.apache.stratos.manager.console/console/applications_form.jag
@@ -69,13 +69,14 @@ var formtype = elements.formtype;
 switch (formtype) {
     case "groups":
         list_data = util.RESTCalls.getGroups();
-        if (list_data.serviceGroup && list_data.serviceGroup.length === 0) {
+            log.info(list_data)
+        if (list_data.groups && list_data.groups.length === 0) {
             list_data = null;
         }else{
-            formDataEdit = list_data.serviceGroup;
-            for (specNumber in list_data.serviceGroup) {
-                if (list_data.serviceGroup[specNumber].name == elements.action) {
-                    formDataEdit = list_data.serviceGroup[specNumber];
+            formDataEdit = list_data.groups;
+            for (specNumber in list_data.groups) {
+                if (list_data.groups[specNumber].name == elements.action) {
+                    formDataEdit = list_data.groups[specNumber];
                 }
 
             }

http://git-wip-us.apache.org/repos/asf/stratos/blob/5150a8be/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_form.hbs
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_form.hbs b/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_form.hbs
index 83d660a..7354382 100644
--- a/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_form.hbs
+++ b/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_form.hbs
@@ -107,7 +107,7 @@
                         </div>
                     </div>
                 {{/each}}
-                {{#each content_body.sections.serviceGroup}}
+                {{#each content_body.sections.groups}}
                     <div class="block col-md-4 grid-group-item border-right">
                         <div class="toggle-menu-icon">
                             <i class="fa fa-th-large"></i>


[8/8] stratos git commit: notify update status on nodes

Posted by im...@apache.org.
notify update status on nodes


Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/55e0d844
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/55e0d844
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/55e0d844

Branch: refs/heads/4.1.0-test
Commit: 55e0d844413bb48384a0a79a5fcfb32ecc8f1189
Parents: e161508
Author: Dakshika Jayathilaka <si...@gmail.com>
Authored: Sat Dec 13 06:14:22 2014 +0530
Committer: Imesh Gunaratne <im...@apache.org>
Committed: Sat Dec 13 09:45:25 2014 +0530

----------------------------------------------------------------------
 .../theme0/css/custom/application_editor.css     | 19 +++++++++++++++++--
 .../theme0/js/custom/applications-editor.js      |  8 ++++++--
 .../theme0/partials/applications_editor.hbs      |  4 ++--
 3 files changed, 25 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/55e0d844/components/org.apache.stratos.manager.console/console/themes/theme0/css/custom/application_editor.css
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/css/custom/application_editor.css b/components/org.apache.stratos.manager.console/console/themes/theme0/css/custom/application_editor.css
index 9b76099..879f2af 100644
--- a/components/org.apache.stratos.manager.console/console/themes/theme0/css/custom/application_editor.css
+++ b/components/org.apache.stratos.manager.console/console/themes/theme0/css/custom/application_editor.css
@@ -26,6 +26,7 @@
     word-wrap: break-word;
     padding-top: 24px;
     text-align: center;
+    cursor: pointer;
 }
 
 .block-cartridge {
@@ -67,7 +68,7 @@
 
 #whiteboard{
     width: 800px;
-    height: 600px;
+    height: 585px;
     position: absolute;
 }
 
@@ -138,4 +139,18 @@
     float: right;
 }
 
-#component-data{margin-top: 20px}
\ No newline at end of file
+#component-data{margin-top: 20px}
+.stepnode i {
+    margin-top: 2px;
+    color: #e67e22;
+}
+
+.notification {
+    position: absolute;
+    background-color: #fff;
+    width: 30px;
+    height: 30px;
+    border-radius: 15px;
+    top: 52px;
+    left: 52px;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/stratos/blob/55e0d844/components/org.apache.stratos.manager.console/console/themes/theme0/js/custom/applications-editor.js
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/js/custom/applications-editor.js b/components/org.apache.stratos.manager.console/console/themes/theme0/js/custom/applications-editor.js
index 5298114..2da8c15 100644
--- a/components/org.apache.stratos.manager.console/console/themes/theme0/js/custom/applications-editor.js
+++ b/components/org.apache.stratos.manager.console/console/themes/theme0/js/custom/applications-editor.js
@@ -98,6 +98,7 @@ function addJsplumbCartridge(idname, cartridgeCounter) {
         anchor: "TopCenter"
     }, endpointOptions);
     // jsPlumb.addEndpoint($(Div), sourceEndpoint);
+    $(Div).append('<div class="notification"><i class="fa fa-exclamation-circle fa-2x"></i></div>');
     DragEl($(Div));
     Repaint();
 }
@@ -110,6 +111,7 @@ function addJsplumbGroup(groupJSON, cartridgeCounter){
         .addClass('input-false')
         .addClass('stepnode')
         .appendTo('#whiteboard');
+    $(divRoot).append('<div class="notification"><i class="fa fa-exclamation-circle fa-2x"></i></div>');
     jsPlumb.addEndpoint($(divRoot), {
         anchor:"BottomCenter"
     }, bottomConnectorOptions);
@@ -136,7 +138,7 @@ function addJsplumbGroup(groupJSON, cartridgeCounter){
                 .addClass('input-false')
                 .addClass('stepnode')
                 .appendTo('#whiteboard');
-
+            $(divCartridge).append('<div class="notification"><i class="fa fa-exclamation-circle fa-2x"></i></div>');
             jsPlumb.addEndpoint($(divCartridge), {
                 anchor: "TopCenter"
             }, generatedCartridgeEndpointOptions);
@@ -162,6 +164,7 @@ function addJsplumbGroup(groupJSON, cartridgeCounter){
                 .addClass('stepnode')
                 .addClass('input-false')
                 .appendTo('#whiteboard');
+            $(divGroup).append('<div class="notification"><i class="fa fa-exclamation-circle fa-2x"></i></div>');
             jsPlumb.addEndpoint($(divGroup), {
                 anchor:"BottomCenter"
             }, bottomConnectorOptions);
@@ -674,7 +677,7 @@ $(document).ready(function(){
     DragEl(".stepnode");
     Repaint();
 
-    $('#whiteboard').on('dblclick', '.stepnode', function(){
+    $('#whiteboard').on('click', '.stepnode', function(){
         //get tab activated
         if($(this).attr('id') == 'applicationId'){
             activateTab('general');
@@ -737,6 +740,7 @@ $(document).ready(function(){
     $('#component-info-update').on('click', function(){
         $('#'+blockId).attr('data-generated', encodeURIComponent(JSON.stringify(editor.getValue())));
         $('#'+blockId).removeClass('input-false');
+        $('#'+blockId).find('div>i').removeClass('fa-exclamation-circle').addClass('fa-check-circle-o').css('color','#2ecc71');
         $('#deploy').prop("disabled", false);
     });
 

http://git-wip-us.apache.org/repos/asf/stratos/blob/55e0d844/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs b/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs
index cd9abaa..7cb0bac 100644
--- a/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs
+++ b/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs
@@ -60,7 +60,7 @@
             <div class="description" >
                 <div class="panel panel-default">
                     <div class="panel-heading">
-                        <h3 class="panel-title">Details</h3>
+                        <h3 class="panel-title">Information</h3>
                     </div>
                     <div class="panel-body description-section">
 
@@ -72,7 +72,7 @@
             <div class="app-creator">
                 <div id="whiteboard">
                     <div id="applicationId" class="stepnode">
-                        App Id
+                        App
                     </div>
                 </div>
 


[2/8] stratos git commit: minor fixes for application editor

Posted by im...@apache.org.
minor fixes for application editor


Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/e161508a
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/e161508a
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/e161508a

Branch: refs/heads/4.1.0-test
Commit: e161508ae76d66fe2191d03a9f7960712b604aaa
Parents: 3bf8da1
Author: Dakshika Jayathilaka <si...@gmail.com>
Authored: Fri Dec 12 13:14:13 2014 +0530
Committer: Imesh Gunaratne <im...@apache.org>
Committed: Sat Dec 13 09:45:24 2014 +0530

----------------------------------------------------------------------
 .../theme0/css/custom/application_editor.css    | 26 +++++++++---
 .../theme0/js/custom/applications-editor.js     | 43 +++++++++++++++-----
 .../theme0/partials/applications_editor.hbs     |  7 ++--
 3 files changed, 58 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/e161508a/components/org.apache.stratos.manager.console/console/themes/theme0/css/custom/application_editor.css
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/css/custom/application_editor.css b/components/org.apache.stratos.manager.console/console/themes/theme0/css/custom/application_editor.css
index ee511fb..9b76099 100644
--- a/components/org.apache.stratos.manager.console/console/themes/theme0/css/custom/application_editor.css
+++ b/components/org.apache.stratos.manager.console/console/themes/theme0/css/custom/application_editor.css
@@ -14,7 +14,7 @@
 }
 
 .stepnode {
-    border: 1px solid black;
+    border: 1px solid silver;
     position: absolute !important;
     width: 5em;
     height: 5em;
@@ -29,24 +29,30 @@
 }
 
 .block-cartridge {
+    border: 1px solid silver;
+    border-radius: 0.5em;
     width: 80px;
     height: 80px;
-    background-color: rgb(109, 123, 112);
+    background-color:#CCC;
     float: left;
     margin: 5px;
     padding: 5px;
     word-wrap: break-word;
+    padding-top: 24px;
     cursor: pointer;
 }
 
 .block-group {
+    border: 1px solid silver;
+    border-radius: 0.5em;
     width: 80px;
     height: 80px;
-    background-color: rgb(109, 123, 112);
+    background-color: #CCC;
     float: left;
     margin: 5px;
     padding: 5px;
     word-wrap: break-word;
+    padding-top: 24px;
     cursor: pointer;
 }
 
@@ -57,7 +63,6 @@
     border-radius: 4px;
     margin-left: 10px;
     position: relative;
-    background-image: url("../images/grid.png");
 }
 
 #whiteboard{
@@ -122,4 +127,15 @@
     background-color: #CCC;
     border-color: #ddd;
     border-width: 1px;
-}
\ No newline at end of file
+}
+
+#component-data>div>h3{
+    display: none;
+}
+
+#component-info-update{
+    margin-top:-5px;margin-bottom: 20px;
+    float: right;
+}
+
+#component-data{margin-top: 20px}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/stratos/blob/e161508a/components/org.apache.stratos.manager.console/console/themes/theme0/js/custom/applications-editor.js
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/js/custom/applications-editor.js b/components/org.apache.stratos.manager.console/console/themes/theme0/js/custom/applications-editor.js
index 89b0af8..5298114 100644
--- a/components/org.apache.stratos.manager.console/console/themes/theme0/js/custom/applications-editor.js
+++ b/components/org.apache.stratos.manager.console/console/themes/theme0/js/custom/applications-editor.js
@@ -350,7 +350,7 @@ function deleteNode(endPoint){
 
 //genrate context menu for nodes
 $(function(){
-    $.contextMenu({
+    /*$.contextMenu({
         selector: '.stepnode',
         callback: function(key, options) {
             var m = "clicked: " + key + $(this);
@@ -359,8 +359,6 @@ $(function(){
             }else if(key == 'edit'){
 
             }
-
-            window.console && console.log($(this));
         },
         items: {
             "edit": {name: "Edit", icon: "edit"},
@@ -368,7 +366,7 @@ $(function(){
             "sep1": "---------",
             "quit": {name: "Quit", icon: "quit"}
         }
-    });
+    });*/
 
 });
 
@@ -469,9 +467,8 @@ function generateJsplumbTree(collector, connections){
     }
 
     traverse(collector);
-    console.log(collector)
-    console.log(JSON.stringify(collector));
-    $('#messages').html(JSON.stringify(collector, null, 4))
+
+    return collector;
 }
 
 //setting up schema and defaults
@@ -639,9 +636,34 @@ function generateGroups(data){
 // Document ready events
 $(document).ready(function(){
 
-    $('#app-generate').on('click', function(){
-        generateJsplumbTree(applicationJson, jsPlumb.getConnections());
+    $('#deploy').attr('disabled','disabled');
+
+    $('#deploy').on('click', function(){
+        var appJSON = generateJsplumbTree(applicationJson, jsPlumb.getConnections());
+        var btn = $(this);
+        var formtype = 'applications';
+        btn.html("<i class='fa fa-spinner fa-spin'></i> Deploying...");
+        $.ajax({
+            type: "POST",
+            url: caramel.context + "/controllers/applications/application_requests.jag",
+            dataType: 'json',
+            data: { "formPayload": JSON.stringify(appJSON), "formtype": formtype },
+            success: function (data) {
+                if (data.status == 'error') {
+                    var n = noty({text: data.message, layout: 'bottomRight', type: 'error'});
+                } else if (data.status == 'warning') {
+                    var n = noty({text: data.message, layout: 'bottomRight', type: 'warning'});
+                } else {
+                    var n = noty({text: data.message, layout: 'bottomRight', type: 'success'});
+                }
+            }
+        })
+            .always(function () {
+                btn.html('Deploy Application Definition');
+            });
+
     });
+
     //*******************Adding JSON editor *************//
     JSONEditor.defaults.theme = 'bootstrap3';
     JSONEditor.defaults.iconlib = 'fontawesome4';
@@ -658,6 +680,7 @@ $(document).ready(function(){
             activateTab('general');
         }else{
             activateTab('components');
+            $('#component-info-update').prop("disabled", false);
         }
 
         blockId = $(this).attr('id');
@@ -714,7 +737,7 @@ $(document).ready(function(){
     $('#component-info-update').on('click', function(){
         $('#'+blockId).attr('data-generated', encodeURIComponent(JSON.stringify(editor.getValue())));
         $('#'+blockId).removeClass('input-false');
-
+        $('#deploy').prop("disabled", false);
     });
 
     //get create cartridge list

http://git-wip-us.apache.org/repos/asf/stratos/blob/e161508a/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs b/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs
index 9abc1dc..cd9abaa 100644
--- a/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs
+++ b/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs
@@ -125,10 +125,11 @@
 
                         </div>
                         <div role="tabpanel" class="tab-pane components" id="components">
-                            <button type="button" class="btn btn-primary" id="component-info-update">Update</button>
-                            <button type="button" class="btn btn-primary" id="app-generate">Generate</button>
+                            <button type="button" class="btn btn-primary" id="component-info-update" disabled="disabled">Update</button>
+                            <br/>
                             <div id="component-data">
-
+                                <h4>Click on each node to get group or cartridge related information. Once you
+                                fill all required fileds click on "Update" button.</h4>
                             </div>
                         </div>
                     </div>


[7/8] stratos git commit: Jquery.contextMenu lib added to application editor

Posted by im...@apache.org.
Jquery.contextMenu lib added to application editor


Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/3cf81a89
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/3cf81a89
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/3cf81a89

Branch: refs/heads/4.1.0-test
Commit: 3cf81a89252eac241e1deeb60b98a2070a91c1e3
Parents: f72d80f
Author: Dakshika Jayathilaka <si...@gmail.com>
Authored: Thu Dec 11 23:33:11 2014 +0530
Committer: Imesh Gunaratne <im...@apache.org>
Committed: Sat Dec 13 09:45:24 2014 +0530

----------------------------------------------------------------------
 .../js/jquery.contextMenu/jquery.contextMenu.js | 1686 ++++++++++++++++++
 .../js/jquery.contextMenu/jquery.ui.position.js |  497 ++++++
 2 files changed, 2183 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/3cf81a89/components/org.apache.stratos.manager.console/console/themes/theme0/js/jquery.contextMenu/jquery.contextMenu.js
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/js/jquery.contextMenu/jquery.contextMenu.js b/components/org.apache.stratos.manager.console/console/themes/theme0/js/jquery.contextMenu/jquery.contextMenu.js
new file mode 100755
index 0000000..103a585
--- /dev/null
+++ b/components/org.apache.stratos.manager.console/console/themes/theme0/js/jquery.contextMenu/jquery.contextMenu.js
@@ -0,0 +1,1686 @@
+/*!
+ * jQuery contextMenu - Plugin for simple contextMenu handling
+ *
+ * Version: git-master
+ *
+ * Authors: Rodney Rehm, Addy Osmani (patches for FF)
+ * Web: http://medialize.github.com/jQuery-contextMenu/
+ *
+ * Licensed under
+ *   MIT License http://www.opensource.org/licenses/mit-license
+ *   GPL v3 http://opensource.org/licenses/GPL-3.0
+ *
+ */
+
+(function($, undefined){
+    
+    // TODO: -
+        // ARIA stuff: menuitem, menuitemcheckbox und menuitemradio
+        // create <menu> structure if $.support[htmlCommand || htmlMenuitem] and !opt.disableNative
+
+// determine html5 compatibility
+$.support.htmlMenuitem = ('HTMLMenuItemElement' in window);
+$.support.htmlCommand = ('HTMLCommandElement' in window);
+$.support.eventSelectstart = ("onselectstart" in document.documentElement);
+/* // should the need arise, test for css user-select
+$.support.cssUserSelect = (function(){
+    var t = false,
+        e = document.createElement('div');
+    
+    $.each('Moz|Webkit|Khtml|O|ms|Icab|'.split('|'), function(i, prefix) {
+        var propCC = prefix + (prefix ? 'U' : 'u') + 'serSelect',
+            prop = (prefix ? ('-' + prefix.toLowerCase() + '-') : '') + 'user-select';
+            
+        e.style.cssText = prop + ': text;';
+        if (e.style[propCC] == 'text') {
+            t = true;
+            return false;
+        }
+        
+        return true;
+    });
+    
+    return t;
+})();
+*/
+
+if (!$.ui || !$.ui.widget) {
+    // duck punch $.cleanData like jQueryUI does to get that remove event
+    // https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js#L16-24
+    var _cleanData = $.cleanData;
+    $.cleanData = function( elems ) {
+        for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+            try {
+                $( elem ).triggerHandler( "remove" );
+                // http://bugs.jquery.com/ticket/8235
+            } catch( e ) {}
+        }
+        _cleanData( elems );
+    };
+}
+
+var // currently active contextMenu trigger
+    $currentTrigger = null,
+    // is contextMenu initialized with at least one menu?
+    initialized = false,
+    // window handle
+    $win = $(window),
+    // number of registered menus
+    counter = 0,
+    // mapping selector to namespace
+    namespaces = {},
+    // mapping namespace to options
+    menus = {},
+    // custom command type handlers
+    types = {},
+    // default values
+    defaults = {
+        // selector of contextMenu trigger
+        selector: null,
+        // where to append the menu to
+        appendTo: null,
+        // method to trigger context menu ["right", "left", "hover"]
+        trigger: "right",
+        // hide menu when mouse leaves trigger / menu elements
+        autoHide: false,
+        // ms to wait before showing a hover-triggered context menu
+        delay: 200,
+        // flag denoting if a second trigger should simply move (true) or rebuild (false) an open menu
+        // as long as the trigger happened on one of the trigger-element's child nodes
+        reposition: true,
+        // determine position to show menu at
+        determinePosition: function($menu) {
+            // position to the lower middle of the trigger element
+            if ($.ui && $.ui.position) {
+                // .position() is provided as a jQuery UI utility
+                // (...and it won't work on hidden elements)
+                $menu.css('display', 'block').position({
+                    my: "center top",
+                    at: "center bottom",
+                    of: this,
+                    offset: "0 5",
+                    collision: "fit"
+                }).css('display', 'none');
+            } else {
+                // determine contextMenu position
+                var offset = this.offset();
+                offset.top += this.outerHeight();
+                offset.left += this.outerWidth() / 2 - $menu.outerWidth() / 2;
+                $menu.css(offset);
+            }
+        },
+        // position menu
+        position: function(opt, x, y) {
+            var $this = this,
+                offset;
+            // determine contextMenu position
+            if (!x && !y) {
+                opt.determinePosition.call(this, opt.$menu);
+                return;
+            } else if (x === "maintain" && y === "maintain") {
+                // x and y must not be changed (after re-show on command click)
+                offset = opt.$menu.position();
+            } else {
+                // x and y are given (by mouse event)
+                offset = {top: y, left: x};
+            }
+            
+            // correct offset if viewport demands it
+            var bottom = $win.scrollTop() + $win.height(),
+                right = $win.scrollLeft() + $win.width(),
+                height = opt.$menu.height(),
+                width = opt.$menu.width();
+            
+            if (offset.top + height > bottom) {
+                offset.top -= height;
+            }
+            
+            if (offset.left + width > right) {
+                offset.left -= width;
+            }
+            
+            opt.$menu.css(offset);
+        },
+        // position the sub-menu
+        positionSubmenu: function($menu) {
+            if ($.ui && $.ui.position) {
+                // .position() is provided as a jQuery UI utility
+                // (...and it won't work on hidden elements)
+                $menu.css('display', 'block').position({
+                    my: "left top",
+                    at: "right top",
+                    of: this,
+                    collision: "flipfit fit"
+                }).css('display', '');
+            } else {
+                // determine contextMenu position
+                var offset = {
+                    top: 0,
+                    left: this.outerWidth()
+                };
+                $menu.css(offset);
+            }
+        },
+        // offset to add to zIndex
+        zIndex: 1,
+        // show hide animation settings
+        animation: {
+            duration: 50,
+            show: 'slideDown',
+            hide: 'slideUp'
+        },
+        // events
+        events: {
+            show: $.noop,
+            hide: $.noop
+        },
+        // default callback
+        callback: null,
+        // list of contextMenu items
+        items: {}
+    },
+    // mouse position for hover activation
+    hoveract = {
+        timer: null,
+        pageX: null,
+        pageY: null
+    },
+    // determine zIndex
+    zindex = function($t) {
+        var zin = 0,
+            $tt = $t;
+
+        while (true) {
+            zin = Math.max(zin, parseInt($tt.css('z-index'), 10) || 0);
+            $tt = $tt.parent();
+            if (!$tt || !$tt.length || "html body".indexOf($tt.prop('nodeName').toLowerCase()) > -1 ) {
+                break;
+            }
+        }
+        
+        return zin;
+    },
+    // event handlers
+    handle = {
+        // abort anything
+        abortevent: function(e){
+            e.preventDefault();
+            e.stopImmediatePropagation();
+        },
+        
+        // contextmenu show dispatcher
+        contextmenu: function(e) {
+            var $this = $(this);
+            
+            // disable actual context-menu
+            e.preventDefault();
+            e.stopImmediatePropagation();
+            
+            // abort native-triggered events unless we're triggering on right click
+            if (e.data.trigger != 'right' && e.originalEvent) {
+                return;
+            }
+            
+            // abort event if menu is visible for this trigger
+            if ($this.hasClass('context-menu-active')) {
+                return;
+            }
+            
+            if (!$this.hasClass('context-menu-disabled')) {
+                // theoretically need to fire a show event at <menu>
+                // http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#context-menus
+                // var evt = jQuery.Event("show", { data: data, pageX: e.pageX, pageY: e.pageY, relatedTarget: this });
+                // e.data.$menu.trigger(evt);
+                
+                $currentTrigger = $this;
+                if (e.data.build) {
+                    var built = e.data.build($currentTrigger, e);
+                    // abort if build() returned false
+                    if (built === false) {
+                        return;
+                    }
+                    
+                    // dynamically build menu on invocation
+                    e.data = $.extend(true, {}, defaults, e.data, built || {});
+
+                    // abort if there are no items to display
+                    if (!e.data.items || $.isEmptyObject(e.data.items)) {
+                        // Note: jQuery captures and ignores errors from event handlers
+                        if (window.console) {
+                            (console.error || console.log)("No items specified to show in contextMenu");
+                        }
+                        
+                        throw new Error('No Items specified');
+                    }
+                    
+                    // backreference for custom command type creation
+                    e.data.$trigger = $currentTrigger;
+                    
+                    op.create(e.data);
+                }
+                // show menu
+                op.show.call($this, e.data, e.pageX, e.pageY);
+            }
+        },
+        // contextMenu left-click trigger
+        click: function(e) {
+            e.preventDefault();
+            e.stopImmediatePropagation();
+            $(this).trigger($.Event("contextmenu", { data: e.data, pageX: e.pageX, pageY: e.pageY }));
+        },
+        // contextMenu right-click trigger
+        mousedown: function(e) {
+            // register mouse down
+            var $this = $(this);
+            
+            // hide any previous menus
+            if ($currentTrigger && $currentTrigger.length && !$currentTrigger.is($this)) {
+                $currentTrigger.data('contextMenu').$menu.trigger('contextmenu:hide');
+            }
+            
+            // activate on right click
+            if (e.button == 2) {
+                $currentTrigger = $this.data('contextMenuActive', true);
+            }
+        },
+        // contextMenu right-click trigger
+        mouseup: function(e) {
+            // show menu
+            var $this = $(this);
+            if ($this.data('contextMenuActive') && $currentTrigger && $currentTrigger.length && $currentTrigger.is($this) && !$this.hasClass('context-menu-disabled')) {
+                e.preventDefault();
+                e.stopImmediatePropagation();
+                $currentTrigger = $this;
+                $this.trigger($.Event("contextmenu", { data: e.data, pageX: e.pageX, pageY: e.pageY }));
+            }
+            
+            $this.removeData('contextMenuActive');
+        },
+        // contextMenu hover trigger
+        mouseenter: function(e) {
+            var $this = $(this),
+                $related = $(e.relatedTarget),
+                $document = $(document);
+            
+            // abort if we're coming from a menu
+            if ($related.is('.context-menu-list') || $related.closest('.context-menu-list').length) {
+                return;
+            }
+            
+            // abort if a menu is shown
+            if ($currentTrigger && $currentTrigger.length) {
+                return;
+            }
+            
+            hoveract.pageX = e.pageX;
+            hoveract.pageY = e.pageY;
+            hoveract.data = e.data;
+            $document.on('mousemove.contextMenuShow', handle.mousemove);
+            hoveract.timer = setTimeout(function() {
+                hoveract.timer = null;
+                $document.off('mousemove.contextMenuShow');
+                $currentTrigger = $this;
+                $this.trigger($.Event("contextmenu", { data: hoveract.data, pageX: hoveract.pageX, pageY: hoveract.pageY }));
+            }, e.data.delay );
+        },
+        // contextMenu hover trigger
+        mousemove: function(e) {
+            hoveract.pageX = e.pageX;
+            hoveract.pageY = e.pageY;
+        },
+        // contextMenu hover trigger
+        mouseleave: function(e) {
+            // abort if we're leaving for a menu
+            var $related = $(e.relatedTarget);
+            if ($related.is('.context-menu-list') || $related.closest('.context-menu-list').length) {
+                return;
+            }
+            
+            try {
+                clearTimeout(hoveract.timer);
+            } catch(e) {}
+            
+            hoveract.timer = null;
+        },
+        
+        // click on layer to hide contextMenu
+        layerClick: function(e) {
+            var $this = $(this),
+                root = $this.data('contextMenuRoot'),
+                mouseup = false,
+                button = e.button,
+                x = e.pageX,
+                y = e.pageY,
+                target, 
+                offset,
+                selectors;
+                
+            e.preventDefault();
+            e.stopImmediatePropagation();
+            
+            setTimeout(function() {
+                var $window, hideshow, possibleTarget;
+                var triggerAction = ((root.trigger == 'left' && button === 0) || (root.trigger == 'right' && button === 2));
+                
+                // find the element that would've been clicked, wasn't the layer in the way
+                if (document.elementFromPoint) {
+                    root.$layer.hide();
+                    target = document.elementFromPoint(x - $win.scrollLeft(), y - $win.scrollTop());
+                    root.$layer.show();
+                }
+                
+                if (root.reposition && triggerAction) {
+                    if (document.elementFromPoint) {
+                        if (root.$trigger.is(target) || root.$trigger.has(target).length) {
+                            root.position.call(root.$trigger, root, x, y);
+                            return;
+                        }
+                    } else {
+                        offset = root.$trigger.offset();
+                        $window = $(window);
+                        // while this looks kinda awful, it's the best way to avoid
+                        // unnecessarily calculating any positions
+                        offset.top += $window.scrollTop();
+                        if (offset.top <= e.pageY) {
+                            offset.left += $window.scrollLeft();
+                            if (offset.left <= e.pageX) {
+                                offset.bottom = offset.top + root.$trigger.outerHeight();
+                                if (offset.bottom >= e.pageY) {
+                                    offset.right = offset.left + root.$trigger.outerWidth();
+                                    if (offset.right >= e.pageX) {
+                                        // reposition
+                                        root.position.call(root.$trigger, root, x, y);
+                                        return;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                
+                if (target && triggerAction) {
+                    root.$trigger.one('contextmenu:hidden', function() {
+                        $(target).contextMenu({x: x, y: y});
+                    });
+                }
+
+                root.$menu.trigger('contextmenu:hide');
+            }, 50);
+        },
+        // key handled :hover
+        keyStop: function(e, opt) {
+            if (!opt.isInput) {
+                e.preventDefault();
+            }
+            
+            e.stopPropagation();
+        },
+        key: function(e) {
+            var opt = $currentTrigger.data('contextMenu') || {};
+
+            switch (e.keyCode) {
+                case 9:
+                case 38: // up
+                    handle.keyStop(e, opt);
+                    // if keyCode is [38 (up)] or [9 (tab) with shift]
+                    if (opt.isInput) {
+                        if (e.keyCode == 9 && e.shiftKey) {
+                            e.preventDefault();
+                            opt.$selected && opt.$selected.find('input, textarea, select').blur();
+                            opt.$menu.trigger('prevcommand');
+                            return;
+                        } else if (e.keyCode == 38 && opt.$selected.find('input, textarea, select').prop('type') == 'checkbox') {
+                            // checkboxes don't capture this key
+                            e.preventDefault();
+                            return;
+                        }
+                    } else if (e.keyCode != 9 || e.shiftKey) {
+                        opt.$menu.trigger('prevcommand');
+                        return;
+                    }
+                    // omitting break;
+                    
+                // case 9: // tab - reached through omitted break;
+                case 40: // down
+                    handle.keyStop(e, opt);
+                    if (opt.isInput) {
+                        if (e.keyCode == 9) {
+                            e.preventDefault();
+                            opt.$selected && opt.$selected.find('input, textarea, select').blur();
+                            opt.$menu.trigger('nextcommand');
+                            return;
+                        } else if (e.keyCode == 40 && opt.$selected.find('input, textarea, select').prop('type') == 'checkbox') {
+                            // checkboxes don't capture this key
+                            e.preventDefault();
+                            return;
+                        }
+                    } else {
+                        opt.$menu.trigger('nextcommand');
+                        return;
+                    }
+                    break;
+                
+                case 37: // left
+                    handle.keyStop(e, opt);
+                    if (opt.isInput || !opt.$selected || !opt.$selected.length) {
+                        break;
+                    }
+                
+                    if (!opt.$selected.parent().hasClass('context-menu-root')) {
+                        var $parent = opt.$selected.parent().parent();
+                        opt.$selected.trigger('contextmenu:blur');
+                        opt.$selected = $parent;
+                        return;
+                    }
+                    break;
+                    
+                case 39: // right
+                    handle.keyStop(e, opt);
+                    if (opt.isInput || !opt.$selected || !opt.$selected.length) {
+                        break;
+                    }
+                    
+                    var itemdata = opt.$selected.data('contextMenu') || {};
+                    if (itemdata.$menu && opt.$selected.hasClass('context-menu-submenu')) {
+                        opt.$selected = null;
+                        itemdata.$selected = null;
+                        itemdata.$menu.trigger('nextcommand');
+                        return;
+                    }
+                    break;
+                
+                case 35: // end
+                case 36: // home
+                    if (opt.$selected && opt.$selected.find('input, textarea, select').length) {
+                        return;
+                    } else {
+                        (opt.$selected && opt.$selected.parent() || opt.$menu)
+                            .children(':not(.disabled, .not-selectable)')[e.keyCode == 36 ? 'first' : 'last']()
+                            .trigger('contextmenu:focus');
+                        e.preventDefault();
+                        return;
+                    }
+                    break;
+                    
+                case 13: // enter
+                    handle.keyStop(e, opt);
+                    if (opt.isInput) {
+                        if (opt.$selected && !opt.$selected.is('textarea, select')) {
+                            e.preventDefault();
+                            return;
+                        }
+                        break;
+                    }
+                    opt.$selected && opt.$selected.trigger('mouseup');
+                    return;
+                    
+                case 32: // space
+                case 33: // page up
+                case 34: // page down
+                    // prevent browser from scrolling down while menu is visible
+                    handle.keyStop(e, opt);
+                    return;
+                    
+                case 27: // esc
+                    handle.keyStop(e, opt);
+                    opt.$menu.trigger('contextmenu:hide');
+                    return;
+                    
+                default: // 0-9, a-z
+                    var k = (String.fromCharCode(e.keyCode)).toUpperCase();
+                    if (opt.accesskeys[k]) {
+                        // according to the specs accesskeys must be invoked immediately
+                        opt.accesskeys[k].$node.trigger(opt.accesskeys[k].$menu
+                            ? 'contextmenu:focus'
+                            : 'mouseup'
+                        );
+                        return;
+                    }
+                    break;
+            }
+            // pass event to selected item, 
+            // stop propagation to avoid endless recursion
+            e.stopPropagation();
+            opt.$selected && opt.$selected.trigger(e);
+        },
+
+        // select previous possible command in menu
+        prevItem: function(e) {
+            e.stopPropagation();
+            var opt = $(this).data('contextMenu') || {};
+
+            // obtain currently selected menu
+            if (opt.$selected) {
+                var $s = opt.$selected;
+                opt = opt.$selected.parent().data('contextMenu') || {};
+                opt.$selected = $s;
+            }
+            
+            var $children = opt.$menu.children(),
+                $prev = !opt.$selected || !opt.$selected.prev().length ? $children.last() : opt.$selected.prev(),
+                $round = $prev;
+            
+            // skip disabled
+            while ($prev.hasClass('disabled') || $prev.hasClass('not-selectable')) {
+                if ($prev.prev().length) {
+                    $prev = $prev.prev();
+                } else {
+                    $prev = $children.last();
+                }
+                if ($prev.is($round)) {
+                    // break endless loop
+                    return;
+                }
+            }
+            
+            // leave current
+            if (opt.$selected) {
+                handle.itemMouseleave.call(opt.$selected.get(0), e);
+            }
+            
+            // activate next
+            handle.itemMouseenter.call($prev.get(0), e);
+            
+            // focus input
+            var $input = $prev.find('input, textarea, select');
+            if ($input.length) {
+                $input.focus();
+            }
+        },
+        // select next possible command in menu
+        nextItem: function(e) {
+            e.stopPropagation();
+            var opt = $(this).data('contextMenu') || {};
+
+            // obtain currently selected menu
+            if (opt.$selected) {
+                var $s = opt.$selected;
+                opt = opt.$selected.parent().data('contextMenu') || {};
+                opt.$selected = $s;
+            }
+
+            var $children = opt.$menu.children(),
+                $next = !opt.$selected || !opt.$selected.next().length ? $children.first() : opt.$selected.next(),
+                $round = $next;
+
+            // skip disabled
+            while ($next.hasClass('disabled') || $next.hasClass('not-selectable')) {
+                if ($next.next().length) {
+                    $next = $next.next();
+                } else {
+                    $next = $children.first();
+                }
+                if ($next.is($round)) {
+                    // break endless loop
+                    return;
+                }
+            }
+            
+            // leave current
+            if (opt.$selected) {
+                handle.itemMouseleave.call(opt.$selected.get(0), e);
+            }
+            
+            // activate next
+            handle.itemMouseenter.call($next.get(0), e);
+            
+            // focus input
+            var $input = $next.find('input, textarea, select');
+            if ($input.length) {
+                $input.focus();
+            }
+        },
+        
+        // flag that we're inside an input so the key handler can act accordingly
+        focusInput: function(e) {
+            var $this = $(this).closest('.context-menu-item'),
+                data = $this.data(),
+                opt = data.contextMenu,
+                root = data.contextMenuRoot;
+
+            root.$selected = opt.$selected = $this;
+            root.isInput = opt.isInput = true;
+        },
+        // flag that we're inside an input so the key handler can act accordingly
+        blurInput: function(e) {
+            var $this = $(this).closest('.context-menu-item'),
+                data = $this.data(),
+                opt = data.contextMenu,
+                root = data.contextMenuRoot;
+
+            root.isInput = opt.isInput = false;
+        },
+        
+        // :hover on menu
+        menuMouseenter: function(e) {
+            var root = $(this).data().contextMenuRoot;
+            root.hovering = true;
+        },
+        // :hover on menu
+        menuMouseleave: function(e) {
+            var root = $(this).data().contextMenuRoot;
+            if (root.$layer && root.$layer.is(e.relatedTarget)) {
+                root.hovering = false;
+            }
+        },
+        
+        // :hover done manually so key handling is possible
+        itemMouseenter: function(e) {
+            var $this = $(this),
+                data = $this.data(),
+                opt = data.contextMenu,
+                root = data.contextMenuRoot;
+            
+            root.hovering = true;
+
+            // abort if we're re-entering
+            if (e && root.$layer && root.$layer.is(e.relatedTarget)) {
+                e.preventDefault();
+                e.stopImmediatePropagation();
+            }
+
+            // make sure only one item is selected
+            (opt.$menu ? opt : root).$menu
+                .children('.hover').trigger('contextmenu:blur');
+
+            if ($this.hasClass('disabled') || $this.hasClass('not-selectable')) {
+                opt.$selected = null;
+                return;
+            }
+            
+            $this.trigger('contextmenu:focus');
+        },
+        // :hover done manually so key handling is possible
+        itemMouseleave: function(e) {
+            var $this = $(this),
+                data = $this.data(),
+                opt = data.contextMenu,
+                root = data.contextMenuRoot;
+
+            if (root !== opt && root.$layer && root.$layer.is(e.relatedTarget)) {
+                root.$selected && root.$selected.trigger('contextmenu:blur');
+                e.preventDefault();
+                e.stopImmediatePropagation();
+                root.$selected = opt.$selected = opt.$node;
+                return;
+            }
+            
+            $this.trigger('contextmenu:blur');
+        },
+        // contextMenu item click
+        itemClick: function(e) {
+            var $this = $(this),
+                data = $this.data(),
+                opt = data.contextMenu,
+                root = data.contextMenuRoot,
+                key = data.contextMenuKey,
+                callback;
+
+            // abort if the key is unknown or disabled or is a menu
+            if (!opt.items[key] || $this.is('.disabled, .context-menu-submenu, .context-menu-separator, .not-selectable')) {
+                return;
+            }
+
+            e.preventDefault();
+            e.stopImmediatePropagation();
+
+            if ($.isFunction(root.callbacks[key]) && Object.prototype.hasOwnProperty.call(root.callbacks, key)) {
+                // item-specific callback
+                callback = root.callbacks[key];
+            } else if ($.isFunction(root.callback)) {
+                // default callback
+                callback = root.callback;                
+            } else {
+                // no callback, no action
+                return;
+            }
+
+            // hide menu if callback doesn't stop that
+            if (callback.call(root.$trigger, key, root) !== false) {
+                root.$menu.trigger('contextmenu:hide');
+            } else if (root.$menu.parent().length) {
+                op.update.call(root.$trigger, root);
+            }
+        },
+        // ignore click events on input elements
+        inputClick: function(e) {
+            e.stopImmediatePropagation();
+        },
+        
+        // hide <menu>
+        hideMenu: function(e, data) {
+            var root = $(this).data('contextMenuRoot');
+            op.hide.call(root.$trigger, root, data && data.force);
+        },
+        // focus <command>
+        focusItem: function(e) {
+            e.stopPropagation();
+            var $this = $(this),
+                data = $this.data(),
+                opt = data.contextMenu,
+                root = data.contextMenuRoot;
+
+            $this.addClass('hover')
+                .siblings('.hover').trigger('contextmenu:blur');
+            
+            // remember selected
+            opt.$selected = root.$selected = $this;
+            
+            // position sub-menu - do after show so dumb $.ui.position can keep up
+            if (opt.$node) {
+                root.positionSubmenu.call(opt.$node, opt.$menu);
+            }
+        },
+        // blur <command>
+        blurItem: function(e) {
+            e.stopPropagation();
+            var $this = $(this),
+                data = $this.data(),
+                opt = data.contextMenu,
+                root = data.contextMenuRoot;
+            
+            $this.removeClass('hover');
+            opt.$selected = null;
+        }
+    },
+    // operations
+    op = {
+        show: function(opt, x, y) {
+            var $trigger = $(this),
+                offset,
+                css = {};
+
+            // hide any open menus
+            $('#context-menu-layer').trigger('mousedown');
+
+            // backreference for callbacks
+            opt.$trigger = $trigger;
+
+            // show event
+            if (opt.events.show.call($trigger, opt) === false) {
+                $currentTrigger = null;
+                return;
+            }
+
+            // create or update context menu
+            op.update.call($trigger, opt);
+            
+            // position menu
+            opt.position.call($trigger, opt, x, y);
+
+            // make sure we're in front
+            if (opt.zIndex) {
+                css.zIndex = zindex($trigger) + opt.zIndex;
+            }
+            
+            // add layer
+            op.layer.call(opt.$menu, opt, css.zIndex);
+            
+            // adjust sub-menu zIndexes
+            opt.$menu.find('ul').css('zIndex', css.zIndex + 1);
+            
+            // position and show context menu
+            opt.$menu.css( css )[opt.animation.show](opt.animation.duration, function() {
+                $trigger.trigger('contextmenu:visible');
+            });
+            // make options available and set state
+            $trigger
+                .data('contextMenu', opt)
+                .addClass("context-menu-active");
+            
+            // register key handler
+            $(document).off('keydown.contextMenu').on('keydown.contextMenu', handle.key);
+            // register autoHide handler
+            if (opt.autoHide) {
+                // mouse position handler
+                $(document).on('mousemove.contextMenuAutoHide', function(e) {
+                    // need to capture the offset on mousemove,
+                    // since the page might've been scrolled since activation
+                    var pos = $trigger.offset();
+                    pos.right = pos.left + $trigger.outerWidth();
+                    pos.bottom = pos.top + $trigger.outerHeight();
+                    
+                    if (opt.$layer && !opt.hovering && (!(e.pageX >= pos.left && e.pageX <= pos.right) || !(e.pageY >= pos.top && e.pageY <= pos.bottom))) {
+                        // if mouse in menu...
+                        opt.$menu.trigger('contextmenu:hide');
+                    }
+                });
+            }
+        },
+        hide: function(opt, force) {
+            var $trigger = $(this);
+            if (!opt) {
+                opt = $trigger.data('contextMenu') || {};
+            }
+            
+            // hide event
+            if (!force && opt.events && opt.events.hide.call($trigger, opt) === false) {
+                return;
+            }
+            
+            // remove options and revert state
+            $trigger
+                .removeData('contextMenu')
+                .removeClass("context-menu-active");
+            
+            if (opt.$layer) {
+                // keep layer for a bit so the contextmenu event can be aborted properly by opera
+                setTimeout((function($layer) {
+                    return function(){
+                        $layer.remove();
+                    };
+                })(opt.$layer), 10);
+                
+                try {
+                    delete opt.$layer;
+                } catch(e) {
+                    opt.$layer = null;
+                }
+            }
+            
+            // remove handle
+            $currentTrigger = null;
+            // remove selected
+            opt.$menu.find('.hover').trigger('contextmenu:blur');
+            opt.$selected = null;
+            // unregister key and mouse handlers
+            //$(document).off('.contextMenuAutoHide keydown.contextMenu'); // http://bugs.jquery.com/ticket/10705
+            $(document).off('.contextMenuAutoHide').off('keydown.contextMenu');
+            // hide menu
+            opt.$menu && opt.$menu[opt.animation.hide](opt.animation.duration, function (){
+                // tear down dynamically built menu after animation is completed.
+                if (opt.build) {
+                    opt.$menu.remove();
+                    $.each(opt, function(key, value) {
+                        switch (key) {
+                            case 'ns':
+                            case 'selector':
+                            case 'build':
+                            case 'trigger':
+                                return true;
+
+                            default:
+                                opt[key] = undefined;
+                                try {
+                                    delete opt[key];
+                                } catch (e) {}
+                                return true;
+                        }
+                    });
+                }
+                
+                setTimeout(function() {
+                    $trigger.trigger('contextmenu:hidden');
+                }, 10);
+            });
+        },
+        create: function(opt, root) {
+            if (root === undefined) {
+                root = opt;
+            }
+            // create contextMenu
+            opt.$menu = $('<ul class="context-menu-list"></ul>').addClass(opt.className || "").data({
+                'contextMenu': opt,
+                'contextMenuRoot': root
+            });
+            
+            $.each(['callbacks', 'commands', 'inputs'], function(i,k){
+                opt[k] = {};
+                if (!root[k]) {
+                    root[k] = {};
+                }
+            });
+            
+            root.accesskeys || (root.accesskeys = {});
+            
+            // create contextMenu items
+            $.each(opt.items, function(key, item){
+                var $t = $('<li class="context-menu-item"></li>').addClass(item.className || ""),
+                    $label = null,
+                    $input = null;
+                
+                // iOS needs to see a click-event bound to an element to actually
+                // have the TouchEvents infrastructure trigger the click event
+                $t.on('click', $.noop);
+                
+                item.$node = $t.data({
+                    'contextMenu': opt,
+                    'contextMenuRoot': root,
+                    'contextMenuKey': key
+                });
+                
+                // register accesskey
+                // NOTE: the accesskey attribute should be applicable to any element, but Safari5 and Chrome13 still can't do that
+                if (item.accesskey) {
+                    var aks = splitAccesskey(item.accesskey);
+                    for (var i=0, ak; ak = aks[i]; i++) {
+                        if (!root.accesskeys[ak]) {
+                            root.accesskeys[ak] = item;
+                            item._name = item.name.replace(new RegExp('(' + ak + ')', 'i'), '<span class="context-menu-accesskey">$1</span>');
+                            break;
+                        }
+                    }
+                }
+                
+                if (typeof item == "string") {
+                    $t.addClass('context-menu-separator not-selectable');
+                } else if (item.type && types[item.type]) {
+                    // run custom type handler
+                    types[item.type].call($t, item, opt, root);
+                    // register commands
+                    $.each([opt, root], function(i,k){
+                        k.commands[key] = item;
+                        if ($.isFunction(item.callback)) {
+                            k.callbacks[key] = item.callback;
+                        }
+                    });
+                } else {
+                    // add label for input
+                    if (item.type == 'html') {
+                        $t.addClass('context-menu-html not-selectable');
+                    } else if (item.type) {
+                        $label = $('<label></label>').appendTo($t);
+                        $('<span></span>').html(item._name || item.name).appendTo($label);
+                        $t.addClass('context-menu-input');
+                        opt.hasTypes = true;
+                        $.each([opt, root], function(i,k){
+                            k.commands[key] = item;
+                            k.inputs[key] = item;
+                        });
+                    } else if (item.items) {
+                        item.type = 'sub';
+                    }
+                
+                    switch (item.type) {
+                        case 'text':
+                            $input = $('<input type="text" value="1" name="" value="">')
+                                .attr('name', 'context-menu-input-' + key)
+                                .val(item.value || "")
+                                .appendTo($label);
+                            break;
+                    
+                        case 'textarea':
+                            $input = $('<textarea name=""></textarea>')
+                                .attr('name', 'context-menu-input-' + key)
+                                .val(item.value || "")
+                                .appendTo($label);
+
+                            if (item.height) {
+                                $input.height(item.height);
+                            }
+                            break;
+
+                        case 'checkbox':
+                            $input = $('<input type="checkbox" value="1" name="" value="">')
+                                .attr('name', 'context-menu-input-' + key)
+                                .val(item.value || "")
+                                .prop("checked", !!item.selected)
+                                .prependTo($label);
+                            break;
+
+                        case 'radio':
+                            $input = $('<input type="radio" value="1" name="" value="">')
+                                .attr('name', 'context-menu-input-' + item.radio)
+                                .val(item.value || "")
+                                .prop("checked", !!item.selected)
+                                .prependTo($label);
+                            break;
+                    
+                        case 'select':
+                            $input = $('<select name="">')
+                                .attr('name', 'context-menu-input-' + key)
+                                .appendTo($label);
+                            if (item.options) {
+                                $.each(item.options, function(value, text) {
+                                    $('<option></option>').val(value).text(text).appendTo($input);
+                                });
+                                $input.val(item.selected);
+                            }
+                            break;
+                        
+                        case 'sub':
+                            // FIXME: shouldn't this .html() be a .text()?
+                            $('<span></span>').html(item._name || item.name).appendTo($t);
+                            item.appendTo = item.$node;
+                            op.create(item, root);
+                            $t.data('contextMenu', item).addClass('context-menu-submenu');
+                            item.callback = null;
+                            break;
+                        
+                        case 'html':
+                            $(item.html).appendTo($t);
+                            break;
+                        
+                        default:
+                            $.each([opt, root], function(i,k){
+                                k.commands[key] = item;
+                                if ($.isFunction(item.callback)) {
+                                    k.callbacks[key] = item.callback;
+                                }
+                            });
+                            // FIXME: shouldn't this .html() be a .text()?
+                            $('<span></span>').html(item._name || item.name || "").appendTo($t);
+                            break;
+                    }
+                    
+                    // disable key listener in <input>
+                    if (item.type && item.type != 'sub' && item.type != 'html') {
+                        $input
+                            .on('focus', handle.focusInput)
+                            .on('blur', handle.blurInput);
+                        
+                        if (item.events) {
+                            $input.on(item.events, opt);
+                        }
+                    }
+                
+                    // add icons
+                    if (item.icon) {
+                        $t.addClass("icon icon-" + item.icon);
+                    }
+                }
+                
+                // cache contained elements
+                item.$input = $input;
+                item.$label = $label;
+
+                // attach item to menu
+                $t.appendTo(opt.$menu);
+                
+                // Disable text selection
+                if (!opt.hasTypes && $.support.eventSelectstart) {
+                    // browsers support user-select: none, 
+                    // IE has a special event for text-selection
+                    // browsers supporting neither will not be preventing text-selection
+                    $t.on('selectstart.disableTextSelect', handle.abortevent);
+                }
+            });
+            // attach contextMenu to <body> (to bypass any possible overflow:hidden issues on parents of the trigger element)
+            if (!opt.$node) {
+                opt.$menu.css('display', 'none').addClass('context-menu-root');
+            }
+            opt.$menu.appendTo(opt.appendTo || document.body);
+        },
+        resize: function($menu, nested) {
+            // determine widths of submenus, as CSS won't grow them automatically
+            // position:absolute within position:absolute; min-width:100; max-width:200; results in width: 100;
+            // kinda sucks hard...
+
+            // determine width of absolutely positioned element
+            $menu.css({position: 'absolute', display: 'block'});
+            // don't apply yet, because that would break nested elements' widths
+            // add a pixel to circumvent word-break issue in IE9 - #80
+            $menu.data('width', Math.ceil($menu.width()) + 1);
+            // reset styles so they allow nested elements to grow/shrink naturally
+            $menu.css({
+                position: 'static',
+                minWidth: '0px',
+                maxWidth: '100000px'
+            });
+            // identify width of nested menus
+            $menu.find('> li > ul').each(function() {
+                op.resize($(this), true);
+            });
+            // reset and apply changes in the end because nested
+            // elements' widths wouldn't be calculatable otherwise
+            if (!nested) {
+                $menu.find('ul').andSelf().css({
+                    position: '', 
+                    display: '',
+                    minWidth: '',
+                    maxWidth: ''
+                }).width(function() {
+                    return $(this).data('width');
+                });
+            }
+        },
+        update: function(opt, root) {
+            var $trigger = this;
+            if (root === undefined) {
+                root = opt;
+                op.resize(opt.$menu);
+            }
+            // re-check disabled for each item
+            opt.$menu.children().each(function(){
+                var $item = $(this),
+                    key = $item.data('contextMenuKey'),
+                    item = opt.items[key],
+                    disabled = ($.isFunction(item.disabled) && item.disabled.call($trigger, key, root)) || item.disabled === true;
+
+                // dis- / enable item
+                $item[disabled ? 'addClass' : 'removeClass']('disabled');
+                
+                if (item.type) {
+                    // dis- / enable input elements
+                    $item.find('input, select, textarea').prop('disabled', disabled);
+                    
+                    // update input states
+                    switch (item.type) {
+                        case 'text':
+                        case 'textarea':
+                            item.$input.val(item.value || "");
+                            break;
+                            
+                        case 'checkbox':
+                        case 'radio':
+                            item.$input.val(item.value || "").prop('checked', !!item.selected);
+                            break;
+                            
+                        case 'select':
+                            item.$input.val(item.selected || "");
+                            break;
+                    }
+                }
+                
+                if (item.$menu) {
+                    // update sub-menu
+                    op.update.call($trigger, item, root);
+                }
+            });
+        },
+        layer: function(opt, zIndex) {
+            // add transparent layer for click area
+            // filter and background for Internet Explorer, Issue #23
+            var $layer = opt.$layer = $('<div id="context-menu-layer" style="position:fixed; z-index:' + zIndex + '; top:0; left:0; opacity: 0; filter: alpha(opacity=0); background-color: #000;"></div>')
+                .css({height: $win.height(), width: $win.width(), display: 'block'})
+                .data('contextMenuRoot', opt)
+                .insertBefore(this)
+                .on('contextmenu', handle.abortevent)
+                .on('mousedown', handle.layerClick);
+            
+            // IE6 doesn't know position:fixed;
+            if (!$.support.fixedPosition) {
+                $layer.css({
+                    'position' : 'absolute',
+                    'height' : $(document).height()
+                });
+            }
+            
+            return $layer;
+        }
+    };
+
+// split accesskey according to http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#assigned-access-key
+function splitAccesskey(val) {
+    var t = val.split(/\s+/),
+        keys = [];
+        
+    for (var i=0, k; k = t[i]; i++) {
+        k = k[0].toUpperCase(); // first character only
+        // theoretically non-accessible characters should be ignored, but different systems, different keyboard layouts, ... screw it.
+        // a map to look up already used access keys would be nice
+        keys.push(k);
+    }
+    
+    return keys;
+}
+
+// handle contextMenu triggers
+$.fn.contextMenu = function(operation) {
+    if (operation === undefined) {
+        this.first().trigger('contextmenu');
+    } else if (operation.x && operation.y) {
+        this.first().trigger($.Event("contextmenu", {pageX: operation.x, pageY: operation.y}));
+    } else if (operation === "hide") {
+        var $menu = this.data('contextMenu').$menu;
+        $menu && $menu.trigger('contextmenu:hide');
+    } else if (operation === "destroy") {
+        $.contextMenu("destroy", {context: this});
+    } else if ($.isPlainObject(operation)) {
+        operation.context = this;
+        $.contextMenu("create", operation);
+    } else if (operation) {
+        this.removeClass('context-menu-disabled');
+    } else if (!operation) {
+        this.addClass('context-menu-disabled');
+    }
+    
+    return this;
+};
+
+// manage contextMenu instances
+$.contextMenu = function(operation, options) {
+    if (typeof operation != 'string') {
+        options = operation;
+        operation = 'create';
+    }
+    
+    if (typeof options == 'string') {
+        options = {selector: options};
+    } else if (options === undefined) {
+        options = {};
+    }
+    
+    // merge with default options
+    var o = $.extend(true, {}, defaults, options || {});
+    var $document = $(document);
+    var $context = $document;
+    var _hasContext = false;
+    
+    if (!o.context || !o.context.length) {
+        o.context = document;
+    } else {
+        // you never know what they throw at you...
+        $context = $(o.context).first();
+        o.context = $context.get(0);
+        _hasContext = o.context !== document;
+    }
+    
+    switch (operation) {
+        case 'create':
+            // no selector no joy
+            if (!o.selector) {
+                throw new Error('No selector specified');
+            }
+            // make sure internal classes are not bound to
+            if (o.selector.match(/.context-menu-(list|item|input)($|\s)/)) {
+                throw new Error('Cannot bind to selector "' + o.selector + '" as it contains a reserved className');
+            }
+            if (!o.build && (!o.items || $.isEmptyObject(o.items))) {
+                throw new Error('No Items specified');
+            }
+            counter ++;
+            o.ns = '.contextMenu' + counter;
+            if (!_hasContext) {
+                namespaces[o.selector] = o.ns;
+            }
+            menus[o.ns] = o;
+            
+            // default to right click
+            if (!o.trigger) {
+                o.trigger = 'right';
+            }
+            
+            if (!initialized) {
+                // make sure item click is registered first
+                $document
+                    .on({
+                        'contextmenu:hide.contextMenu': handle.hideMenu,
+                        'prevcommand.contextMenu': handle.prevItem,
+                        'nextcommand.contextMenu': handle.nextItem,
+                        'contextmenu.contextMenu': handle.abortevent,
+                        'mouseenter.contextMenu': handle.menuMouseenter,
+                        'mouseleave.contextMenu': handle.menuMouseleave
+                    }, '.context-menu-list')
+                    .on('mouseup.contextMenu', '.context-menu-input', handle.inputClick)
+                    .on({
+                        'mouseup.contextMenu': handle.itemClick,
+                        'contextmenu:focus.contextMenu': handle.focusItem,
+                        'contextmenu:blur.contextMenu': handle.blurItem,
+                        'contextmenu.contextMenu': handle.abortevent,
+                        'mouseenter.contextMenu': handle.itemMouseenter,
+                        'mouseleave.contextMenu': handle.itemMouseleave
+                    }, '.context-menu-item');
+
+                initialized = true;
+            }
+            
+            // engage native contextmenu event
+            $context
+                .on('contextmenu' + o.ns, o.selector, o, handle.contextmenu);
+            
+            if (_hasContext) {
+                // add remove hook, just in case
+                $context.on('remove' + o.ns, function() {
+                    $(this).contextMenu("destroy");
+                });
+            }
+            
+            switch (o.trigger) {
+                case 'hover':
+                        $context
+                            .on('mouseenter' + o.ns, o.selector, o, handle.mouseenter)
+                            .on('mouseleave' + o.ns, o.selector, o, handle.mouseleave);                    
+                    break;
+                    
+                case 'left':
+                        $context.on('click' + o.ns, o.selector, o, handle.click);
+                    break;
+                /*
+                default:
+                    // http://www.quirksmode.org/dom/events/contextmenu.html
+                    $document
+                        .on('mousedown' + o.ns, o.selector, o, handle.mousedown)
+                        .on('mouseup' + o.ns, o.selector, o, handle.mouseup);
+                    break;
+                */
+            }
+            
+            // create menu
+            if (!o.build) {
+                op.create(o);
+            }
+            break;
+        
+        case 'destroy':
+            var $visibleMenu;
+            if (_hasContext) {
+                // get proper options 
+                var context = o.context;
+                $.each(menus, function(ns, o) {
+                    if (o.context !== context) {
+                        return true;
+                    }
+                    
+                    $visibleMenu = $('.context-menu-list').filter(':visible');
+                    if ($visibleMenu.length && $visibleMenu.data().contextMenuRoot.$trigger.is($(o.context).find(o.selector))) {
+                        $visibleMenu.trigger('contextmenu:hide', {force: true});
+                    }
+
+                    try {
+                        if (menus[o.ns].$menu) {
+                            menus[o.ns].$menu.remove();
+                        }
+
+                        delete menus[o.ns];
+                    } catch(e) {
+                        menus[o.ns] = null;
+                    }
+
+                    $(o.context).off(o.ns);
+                    
+                    return true;
+                });
+            } else if (!o.selector) {
+                $document.off('.contextMenu .contextMenuAutoHide');
+                $.each(menus, function(ns, o) {
+                    $(o.context).off(o.ns);
+                });
+                
+                namespaces = {};
+                menus = {};
+                counter = 0;
+                initialized = false;
+                
+                $('#context-menu-layer, .context-menu-list').remove();
+            } else if (namespaces[o.selector]) {
+                $visibleMenu = $('.context-menu-list').filter(':visible');
+                if ($visibleMenu.length && $visibleMenu.data().contextMenuRoot.$trigger.is(o.selector)) {
+                    $visibleMenu.trigger('contextmenu:hide', {force: true});
+                }
+                
+                try {
+                    if (menus[namespaces[o.selector]].$menu) {
+                        menus[namespaces[o.selector]].$menu.remove();
+                    }
+                    
+                    delete menus[namespaces[o.selector]];
+                } catch(e) {
+                    menus[namespaces[o.selector]] = null;
+                }
+                
+                $document.off(namespaces[o.selector]);
+            }
+            break;
+        
+        case 'html5':
+            // if <command> or <menuitem> are not handled by the browser,
+            // or options was a bool true,
+            // initialize $.contextMenu for them
+            if ((!$.support.htmlCommand && !$.support.htmlMenuitem) || (typeof options == "boolean" && options)) {
+                $('menu[type="context"]').each(function() {
+                    if (this.id) {
+                        $.contextMenu({
+                            selector: '[contextmenu=' + this.id +']',
+                            items: $.contextMenu.fromMenu(this)
+                        });
+                    }
+                }).css('display', 'none');
+            }
+            break;
+        
+        default:
+            throw new Error('Unknown operation "' + operation + '"');
+    }
+    
+    return this;
+};
+
+// import values into <input> commands
+$.contextMenu.setInputValues = function(opt, data) {
+    if (data === undefined) {
+        data = {};
+    }
+    
+    $.each(opt.inputs, function(key, item) {
+        switch (item.type) {
+            case 'text':
+            case 'textarea':
+                item.value = data[key] || "";
+                break;
+
+            case 'checkbox':
+                item.selected = data[key] ? true : false;
+                break;
+                
+            case 'radio':
+                item.selected = (data[item.radio] || "") == item.value ? true : false;
+                break;
+            
+            case 'select':
+                item.selected = data[key] || "";
+                break;
+        }
+    });
+};
+
+// export values from <input> commands
+$.contextMenu.getInputValues = function(opt, data) {
+    if (data === undefined) {
+        data = {};
+    }
+    
+    $.each(opt.inputs, function(key, item) {
+        switch (item.type) {
+            case 'text':
+            case 'textarea':
+            case 'select':
+                data[key] = item.$input.val();
+                break;
+
+            case 'checkbox':
+                data[key] = item.$input.prop('checked');
+                break;
+                
+            case 'radio':
+                if (item.$input.prop('checked')) {
+                    data[item.radio] = item.value;
+                }
+                break;
+        }
+    });
+    
+    return data;
+};
+
+// find <label for="xyz">
+function inputLabel(node) {
+    return (node.id && $('label[for="'+ node.id +'"]').val()) || node.name;
+}
+
+// convert <menu> to items object
+function menuChildren(items, $children, counter) {
+    if (!counter) {
+        counter = 0;
+    }
+    
+    $children.each(function() {
+        var $node = $(this),
+            node = this,
+            nodeName = this.nodeName.toLowerCase(),
+            label,
+            item;
+        
+        // extract <label><input>
+        if (nodeName == 'label' && $node.find('input, textarea, select').length) {
+            label = $node.text();
+            $node = $node.children().first();
+            node = $node.get(0);
+            nodeName = node.nodeName.toLowerCase();
+        }
+        
+        /*
+         * <menu> accepts flow-content as children. that means <embed>, <canvas> and such are valid menu items.
+         * Not being the sadistic kind, $.contextMenu only accepts:
+         * <command>, <menuitem>, <hr>, <span>, <p> <input [text, radio, checkbox]>, <textarea>, <select> and of course <menu>.
+         * Everything else will be imported as an html node, which is not interfaced with contextMenu.
+         */
+        
+        // http://www.whatwg.org/specs/web-apps/current-work/multipage/commands.html#concept-command
+        switch (nodeName) {
+            // http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#the-menu-element
+            case 'menu':
+                item = {name: $node.attr('label'), items: {}};
+                counter = menuChildren(item.items, $node.children(), counter);
+                break;
+            
+            // http://www.whatwg.org/specs/web-apps/current-work/multipage/commands.html#using-the-a-element-to-define-a-command
+            case 'a':
+            // http://www.whatwg.org/specs/web-apps/current-work/multipage/commands.html#using-the-button-element-to-define-a-command
+            case 'button':
+                item = {
+                    name: $node.text(),
+                    disabled: !!$node.attr('disabled'),
+                    callback: (function(){ return function(){ $node.click(); }; })()
+                };
+                break;
+            
+            // http://www.whatwg.org/specs/web-apps/current-work/multipage/commands.html#using-the-command-element-to-define-a-command
+
+            case 'menuitem':
+            case 'command':
+                switch ($node.attr('type')) {
+                    case undefined:
+                    case 'command':
+                    case 'menuitem':
+                        item = {
+                            name: $node.attr('label'),
+                            disabled: !!$node.attr('disabled'),
+                            callback: (function(){ return function(){ $node.click(); }; })()
+                        };
+                        break;
+                        
+                    case 'checkbox':
+                        item = {
+                            type: 'checkbox',
+                            disabled: !!$node.attr('disabled'),
+                            name: $node.attr('label'),
+                            selected: !!$node.attr('checked')
+                        };
+                        break;
+                        
+                    case 'radio':
+                        item = {
+                            type: 'radio',
+                            disabled: !!$node.attr('disabled'),
+                            name: $node.attr('label'),
+                            radio: $node.attr('radiogroup'),
+                            value: $node.attr('id'),
+                            selected: !!$node.attr('checked')
+                        };
+                        break;
+                        
+                    default:
+                        item = undefined;
+                }
+                break;
+ 
+            case 'hr':
+                item = '-------';
+                break;
+                
+            case 'input':
+                switch ($node.attr('type')) {
+                    case 'text':
+                        item = {
+                            type: 'text',
+                            name: label || inputLabel(node),
+                            disabled: !!$node.attr('disabled'),
+                            value: $node.val()
+                        };
+                        break;
+                        
+                    case 'checkbox':
+                        item = {
+                            type: 'checkbox',
+                            name: label || inputLabel(node),
+                            disabled: !!$node.attr('disabled'),
+                            selected: !!$node.attr('checked')
+                        };
+                        break;
+                        
+                    case 'radio':
+                        item = {
+                            type: 'radio',
+                            name: label || inputLabel(node),
+                            disabled: !!$node.attr('disabled'),
+                            radio: !!$node.attr('name'),
+                            value: $node.val(),
+                            selected: !!$node.attr('checked')
+                        };
+                        break;
+                    
+                    default:
+                        item = undefined;
+                        break;
+                }
+                break;
+                
+            case 'select':
+                item = {
+                    type: 'select',
+                    name: label || inputLabel(node),
+                    disabled: !!$node.attr('disabled'),
+                    selected: $node.val(),
+                    options: {}
+                };
+                $node.children().each(function(){
+                    item.options[this.value] = $(this).text();
+                });
+                break;
+                
+            case 'textarea':
+                item = {
+                    type: 'textarea',
+                    name: label || inputLabel(node),
+                    disabled: !!$node.attr('disabled'),
+                    value: $node.val()
+                };
+                break;
+            
+            case 'label':
+                break;
+            
+            default:
+                item = {type: 'html', html: $node.clone(true)};
+                break;
+        }
+        
+        if (item) {
+            counter++;
+            items['key' + counter] = item;
+        }
+    });
+    
+    return counter;
+}
+
+// convert html5 menu
+$.contextMenu.fromMenu = function(element) {
+    var $this = $(element),
+        items = {};
+        
+    menuChildren(items, $this.children());
+    
+    return items;
+};
+
+// make defaults accessible
+$.contextMenu.defaults = defaults;
+$.contextMenu.types = types;
+// export internal functions - undocumented, for hacking only!
+$.contextMenu.handle = handle;
+$.contextMenu.op = op;
+$.contextMenu.menus = menus;
+
+})(jQuery);

http://git-wip-us.apache.org/repos/asf/stratos/blob/3cf81a89/components/org.apache.stratos.manager.console/console/themes/theme0/js/jquery.contextMenu/jquery.ui.position.js
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/js/jquery.contextMenu/jquery.ui.position.js b/components/org.apache.stratos.manager.console/console/themes/theme0/js/jquery.contextMenu/jquery.ui.position.js
new file mode 100755
index 0000000..08ce445
--- /dev/null
+++ b/components/org.apache.stratos.manager.console/console/themes/theme0/js/jquery.contextMenu/jquery.ui.position.js
@@ -0,0 +1,497 @@
+/*!
+ * jQuery UI Position v1.10.0
+ * http://jqueryui.com
+ *
+ * Copyright 2013 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/position/
+ */
+(function( $, undefined ) {
+
+$.ui = $.ui || {};
+
+var cachedScrollbarWidth,
+	max = Math.max,
+	abs = Math.abs,
+	round = Math.round,
+	rhorizontal = /left|center|right/,
+	rvertical = /top|center|bottom/,
+	roffset = /[\+\-]\d+%?/,
+	rposition = /^\w+/,
+	rpercent = /%$/,
+	_position = $.fn.position;
+
+function getOffsets( offsets, width, height ) {
+	return [
+		parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
+		parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
+	];
+}
+
+function parseCss( element, property ) {
+	return parseInt( $.css( element, property ), 10 ) || 0;
+}
+
+function getDimensions( elem ) {
+	var raw = elem[0];
+	if ( raw.nodeType === 9 ) {
+		return {
+			width: elem.width(),
+			height: elem.height(),
+			offset: { top: 0, left: 0 }
+		};
+	}
+	if ( $.isWindow( raw ) ) {
+		return {
+			width: elem.width(),
+			height: elem.height(),
+			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
+		};
+	}
+	if ( raw.preventDefault ) {
+		return {
+			width: 0,
+			height: 0,
+			offset: { top: raw.pageY, left: raw.pageX }
+		};
+	}
+	return {
+		width: elem.outerWidth(),
+		height: elem.outerHeight(),
+		offset: elem.offset()
+	};
+}
+
+$.position = {
+	scrollbarWidth: function() {
+		if ( cachedScrollbarWidth !== undefined ) {
+			return cachedScrollbarWidth;
+		}
+		var w1, w2,
+			div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
+			innerDiv = div.children()[0];
+
+		$( "body" ).append( div );
+		w1 = innerDiv.offsetWidth;
+		div.css( "overflow", "scroll" );
+
+		w2 = innerDiv.offsetWidth;
+
+		if ( w1 === w2 ) {
+			w2 = div[0].clientWidth;
+		}
+
+		div.remove();
+
+		return (cachedScrollbarWidth = w1 - w2);
+	},
+	getScrollInfo: function( within ) {
+		var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
+			overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
+			hasOverflowX = overflowX === "scroll" ||
+				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
+			hasOverflowY = overflowY === "scroll" ||
+				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
+		return {
+			width: hasOverflowX ? $.position.scrollbarWidth() : 0,
+			height: hasOverflowY ? $.position.scrollbarWidth() : 0
+		};
+	},
+	getWithinInfo: function( element ) {
+		var withinElement = $( element || window ),
+			isWindow = $.isWindow( withinElement[0] );
+		return {
+			element: withinElement,
+			isWindow: isWindow,
+			offset: withinElement.offset() || { left: 0, top: 0 },
+			scrollLeft: withinElement.scrollLeft(),
+			scrollTop: withinElement.scrollTop(),
+			width: isWindow ? withinElement.width() : withinElement.outerWidth(),
+			height: isWindow ? withinElement.height() : withinElement.outerHeight()
+		};
+	}
+};
+
+$.fn.position = function( options ) {
+	if ( !options || !options.of ) {
+		return _position.apply( this, arguments );
+	}
+
+	// make a copy, we don't want to modify arguments
+	options = $.extend( {}, options );
+
+	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
+		target = $( options.of ),
+		within = $.position.getWithinInfo( options.within ),
+		scrollInfo = $.position.getScrollInfo( within ),
+		collision = ( options.collision || "flip" ).split( " " ),
+		offsets = {};
+
+	dimensions = getDimensions( target );
+	if ( target[0].preventDefault ) {
+		// force left top to allow flipping
+		options.at = "left top";
+	}
+	targetWidth = dimensions.width;
+	targetHeight = dimensions.height;
+	targetOffset = dimensions.offset;
+	// clone to reuse original targetOffset later
+	basePosition = $.extend( {}, targetOffset );
+
+	// force my and at to have valid horizontal and vertical positions
+	// if a value is missing or invalid, it will be converted to center
+	$.each( [ "my", "at" ], function() {
+		var pos = ( options[ this ] || "" ).split( " " ),
+			horizontalOffset,
+			verticalOffset;
+
+		if ( pos.length === 1) {
+			pos = rhorizontal.test( pos[ 0 ] ) ?
+				pos.concat( [ "center" ] ) :
+				rvertical.test( pos[ 0 ] ) ?
+					[ "center" ].concat( pos ) :
+					[ "center", "center" ];
+		}
+		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
+		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
+
+		// calculate offsets
+		horizontalOffset = roffset.exec( pos[ 0 ] );
+		verticalOffset = roffset.exec( pos[ 1 ] );
+		offsets[ this ] = [
+			horizontalOffset ? horizontalOffset[ 0 ] : 0,
+			verticalOffset ? verticalOffset[ 0 ] : 0
+		];
+
+		// reduce to just the positions without the offsets
+		options[ this ] = [
+			rposition.exec( pos[ 0 ] )[ 0 ],
+			rposition.exec( pos[ 1 ] )[ 0 ]
+		];
+	});
+
+	// normalize collision option
+	if ( collision.length === 1 ) {
+		collision[ 1 ] = collision[ 0 ];
+	}
+
+	if ( options.at[ 0 ] === "right" ) {
+		basePosition.left += targetWidth;
+	} else if ( options.at[ 0 ] === "center" ) {
+		basePosition.left += targetWidth / 2;
+	}
+
+	if ( options.at[ 1 ] === "bottom" ) {
+		basePosition.top += targetHeight;
+	} else if ( options.at[ 1 ] === "center" ) {
+		basePosition.top += targetHeight / 2;
+	}
+
+	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
+	basePosition.left += atOffset[ 0 ];
+	basePosition.top += atOffset[ 1 ];
+
+	return this.each(function() {
+		var collisionPosition, using,
+			elem = $( this ),
+			elemWidth = elem.outerWidth(),
+			elemHeight = elem.outerHeight(),
+			marginLeft = parseCss( this, "marginLeft" ),
+			marginTop = parseCss( this, "marginTop" ),
+			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
+			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
+			position = $.extend( {}, basePosition ),
+			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
+
+		if ( options.my[ 0 ] === "right" ) {
+			position.left -= elemWidth;
+		} else if ( options.my[ 0 ] === "center" ) {
+			position.left -= elemWidth / 2;
+		}
+
+		if ( options.my[ 1 ] === "bottom" ) {
+			position.top -= elemHeight;
+		} else if ( options.my[ 1 ] === "center" ) {
+			position.top -= elemHeight / 2;
+		}
+
+		position.left += myOffset[ 0 ];
+		position.top += myOffset[ 1 ];
+
+		// if the browser doesn't support fractions, then round for consistent results
+		if ( !$.support.offsetFractions ) {
+			position.left = round( position.left );
+			position.top = round( position.top );
+		}
+
+		collisionPosition = {
+			marginLeft: marginLeft,
+			marginTop: marginTop
+		};
+
+		$.each( [ "left", "top" ], function( i, dir ) {
+			if ( $.ui.position[ collision[ i ] ] ) {
+				$.ui.position[ collision[ i ] ][ dir ]( position, {
+					targetWidth: targetWidth,
+					targetHeight: targetHeight,
+					elemWidth: elemWidth,
+					elemHeight: elemHeight,
+					collisionPosition: collisionPosition,
+					collisionWidth: collisionWidth,
+					collisionHeight: collisionHeight,
+					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
+					my: options.my,
+					at: options.at,
+					within: within,
+					elem : elem
+				});
+			}
+		});
+
+		if ( options.using ) {
+			// adds feedback as second argument to using callback, if present
+			using = function( props ) {
+				var left = targetOffset.left - position.left,
+					right = left + targetWidth - elemWidth,
+					top = targetOffset.top - position.top,
+					bottom = top + targetHeight - elemHeight,
+					feedback = {
+						target: {
+							element: target,
+							left: targetOffset.left,
+							top: targetOffset.top,
+							width: targetWidth,
+							height: targetHeight
+						},
+						element: {
+							element: elem,
+							left: position.left,
+							top: position.top,
+							width: elemWidth,
+							height: elemHeight
+						},
+						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
+						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
+					};
+				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
+					feedback.horizontal = "center";
+				}
+				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
+					feedback.vertical = "middle";
+				}
+				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
+					feedback.important = "horizontal";
+				} else {
+					feedback.important = "vertical";
+				}
+				options.using.call( this, props, feedback );
+			};
+		}
+
+		elem.offset( $.extend( position, { using: using } ) );
+	});
+};
+
+$.ui.position = {
+	fit: {
+		left: function( position, data ) {
+			var within = data.within,
+				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
+				outerWidth = within.width,
+				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
+				overLeft = withinOffset - collisionPosLeft,
+				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
+				newOverRight;
+
+			// element is wider than within
+			if ( data.collisionWidth > outerWidth ) {
+				// element is initially over the left side of within
+				if ( overLeft > 0 && overRight <= 0 ) {
+					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
+					position.left += overLeft - newOverRight;
+				// element is initially over right side of within
+				} else if ( overRight > 0 && overLeft <= 0 ) {
+					position.left = withinOffset;
+				// element is initially over both left and right sides of within
+				} else {
+					if ( overLeft > overRight ) {
+						position.left = withinOffset + outerWidth - data.collisionWidth;
+					} else {
+						position.left = withinOffset;
+					}
+				}
+			// too far left -> align with left edge
+			} else if ( overLeft > 0 ) {
+				position.left += overLeft;
+			// too far right -> align with right edge
+			} else if ( overRight > 0 ) {
+				position.left -= overRight;
+			// adjust based on position and margin
+			} else {
+				position.left = max( position.left - collisionPosLeft, position.left );
+			}
+		},
+		top: function( position, data ) {
+			var within = data.within,
+				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
+				outerHeight = data.within.height,
+				collisionPosTop = position.top - data.collisionPosition.marginTop,
+				overTop = withinOffset - collisionPosTop,
+				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
+				newOverBottom;
+
+			// element is taller than within
+			if ( data.collisionHeight > outerHeight ) {
+				// element is initially over the top of within
+				if ( overTop > 0 && overBottom <= 0 ) {
+					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
+					position.top += overTop - newOverBottom;
+				// element is initially over bottom of within
+				} else if ( overBottom > 0 && overTop <= 0 ) {
+					position.top = withinOffset;
+				// element is initially over both top and bottom of within
+				} else {
+					if ( overTop > overBottom ) {
+						position.top = withinOffset + outerHeight - data.collisionHeight;
+					} else {
+						position.top = withinOffset;
+					}
+				}
+			// too far up -> align with top
+			} else if ( overTop > 0 ) {
+				position.top += overTop;
+			// too far down -> align with bottom edge
+			} else if ( overBottom > 0 ) {
+				position.top -= overBottom;
+			// adjust based on position and margin
+			} else {
+				position.top = max( position.top - collisionPosTop, position.top );
+			}
+		}
+	},
+	flip: {
+		left: function( position, data ) {
+			var within = data.within,
+				withinOffset = within.offset.left + within.scrollLeft,
+				outerWidth = within.width,
+				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
+				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
+				overLeft = collisionPosLeft - offsetLeft,
+				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
+				myOffset = data.my[ 0 ] === "left" ?
+					-data.elemWidth :
+					data.my[ 0 ] === "right" ?
+						data.elemWidth :
+						0,
+				atOffset = data.at[ 0 ] === "left" ?
+					data.targetWidth :
+					data.at[ 0 ] === "right" ?
+						-data.targetWidth :
+						0,
+				offset = -2 * data.offset[ 0 ],
+				newOverRight,
+				newOverLeft;
+
+			if ( overLeft < 0 ) {
+				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
+				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
+					position.left += myOffset + atOffset + offset;
+				}
+			}
+			else if ( overRight > 0 ) {
+				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
+				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
+					position.left += myOffset + atOffset + offset;
+				}
+			}
+		},
+		top: function( position, data ) {
+			var within = data.within,
+				withinOffset = within.offset.top + within.scrollTop,
+				outerHeight = within.height,
+				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
+				collisionPosTop = position.top - data.collisionPosition.marginTop,
+				overTop = collisionPosTop - offsetTop,
+				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
+				top = data.my[ 1 ] === "top",
+				myOffset = top ?
+					-data.elemHeight :
+					data.my[ 1 ] === "bottom" ?
+						data.elemHeight :
+						0,
+				atOffset = data.at[ 1 ] === "top" ?
+					data.targetHeight :
+					data.at[ 1 ] === "bottom" ?
+						-data.targetHeight :
+						0,
+				offset = -2 * data.offset[ 1 ],
+				newOverTop,
+				newOverBottom;
+			if ( overTop < 0 ) {
+				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
+				if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
+					position.top += myOffset + atOffset + offset;
+				}
+			}
+			else if ( overBottom > 0 ) {
+				newOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
+				if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
+					position.top += myOffset + atOffset + offset;
+				}
+			}
+		}
+	},
+	flipfit: {
+		left: function() {
+			$.ui.position.flip.left.apply( this, arguments );
+			$.ui.position.fit.left.apply( this, arguments );
+		},
+		top: function() {
+			$.ui.position.flip.top.apply( this, arguments );
+			$.ui.position.fit.top.apply( this, arguments );
+		}
+	}
+};
+
+// fraction support test
+(function () {
+	var testElement, testElementParent, testElementStyle, offsetLeft, i,
+		body = document.getElementsByTagName( "body" )[ 0 ],
+		div = document.createElement( "div" );
+
+	//Create a "fake body" for testing based on method used in jQuery.support
+	testElement = document.createElement( body ? "div" : "body" );
+	testElementStyle = {
+		visibility: "hidden",
+		width: 0,
+		height: 0,
+		border: 0,
+		margin: 0,
+		background: "none"
+	};
+	if ( body ) {
+		$.extend( testElementStyle, {
+			position: "absolute",
+			left: "-1000px",
+			top: "-1000px"
+		});
+	}
+	for ( i in testElementStyle ) {
+		testElement.style[ i ] = testElementStyle[ i ];
+	}
+	testElement.appendChild( div );
+	testElementParent = body || document.documentElement;
+	testElementParent.insertBefore( testElement, testElementParent.firstChild );
+
+	div.style.cssText = "position: absolute; left: 10.7432222px;";
+
+	offsetLeft = $( div ).offset().left;
+	$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
+
+	testElement.innerHTML = "";
+	testElementParent.removeChild( testElement );
+})();
+
+}( jQuery ) );


[4/8] stratos git commit: basic application editor setup

Posted by im...@apache.org.
basic application editor setup


Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/3bf8da14
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/3bf8da14
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/3bf8da14

Branch: refs/heads/4.1.0-test
Commit: 3bf8da14642ec8286edec39ec1945d92bf2a7d40
Parents: 3cf81a8
Author: Dakshika Jayathilaka <si...@gmail.com>
Authored: Fri Dec 12 11:28:43 2014 +0530
Committer: Imesh Gunaratne <im...@apache.org>
Committed: Sat Dec 13 09:45:24 2014 +0530

----------------------------------------------------------------------
 .../console/applications_form.jag               |  11 +-
 .../theme0/css/custom/application_editor.css    | 125 +++
 .../theme0/helpers/applications_editor.js       |   7 +
 .../theme0/js/custom/applications-editor.js     | 755 +++++++++++++++++++
 .../theme0/partials/applications_editor.hbs     | 147 ++++
 .../theme0/renderers/applications_form.js       |   8 +-
 6 files changed, 1045 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/3bf8da14/components/org.apache.stratos.manager.console/console/applications_form.jag
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/applications_form.jag b/components/org.apache.stratos.manager.console/console/applications_form.jag
index 91d01b3..91805ab 100644
--- a/components/org.apache.stratos.manager.console/console/applications_form.jag
+++ b/components/org.apache.stratos.manager.console/console/applications_form.jag
@@ -32,23 +32,25 @@ var log = new Log("apachestratos.applications_form"),
         uriMatcher = new URIMatcher(request.getRequestURI()),
         elements = uriMatcher.match('/{context}/applications/{formtype}/'),
         breadcrumbPathLevelOne = 'applications',
-        formDataEdit = topology_data = '',
+        formDataEdit = topology_data = editorGroups = editorCartridges = '',
         isEdit = applicationView = applicationEditor= isForm = false,
         userPermissions = session.get('PERMISSIONS');
 
 //create left menu
 var leftMenu = menuGenerator(context, menuJson.menu, userPermissions);
 
+
 if (!elements) {
     elements = uriMatcher.match('/{context}/applications/{formtype}/{action}/');
     isForm = true;
 
-
     if (elements.formtype == 'applications' && elements.action != 'new') {
         applicationView = true;
         topology_data = util.RESTCalls.getApplicationTopology(elements.action);
     }else if(elements.formtype == 'applications' && elements.action == 'new'){
         applicationEditor = true;
+        editorGroups =  util.RESTCalls.getGroups();
+        editorCartridges = util.RESTCalls.getCartridges();
     }else  if(elements.action != 'new'){
         isEdit = true;
     }
@@ -69,7 +71,6 @@ var formtype = elements.formtype;
 switch (formtype) {
     case "groups":
         list_data = util.RESTCalls.getGroups();
-            log.info(list_data)
         if (list_data.groups && list_data.groups.length === 0) {
             list_data = null;
         }else{
@@ -114,9 +115,11 @@ var caramelData = {
     isEdit: isEdit,
     appName: elements.action,
     topology_data: JSON.stringify(topology_data),
+    editorGroups: JSON.stringify(editorGroups),
+    editorCartridges: JSON.stringify(editorCartridges),
     applicationView: applicationView,
     applicationEditor: applicationEditor,
-formTitle: formTitle,
+    formTitle: formTitle,
     formDataRaw: JSON.stringify(formDataRaw),
     //formDataRaw: JSON.stringify(partition_data.partition[0]),
     formDataEdit: JSON.stringify(formDataEdit),

http://git-wip-us.apache.org/repos/asf/stratos/blob/3bf8da14/components/org.apache.stratos.manager.console/console/themes/theme0/css/custom/application_editor.css
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/css/custom/application_editor.css b/components/org.apache.stratos.manager.console/console/themes/theme0/css/custom/application_editor.css
new file mode 100644
index 0000000..ee511fb
--- /dev/null
+++ b/components/org.apache.stratos.manager.console/console/themes/theme0/css/custom/application_editor.css
@@ -0,0 +1,125 @@
+.left-side{
+    float: left;
+    width: 20%;
+}
+
+.right-side{
+    float: left;
+    width: 79%;
+    margin-top:20px;
+}
+#applicationId{
+    left: 318px;
+    top: 33px;
+}
+
+.stepnode {
+    border: 1px solid black;
+    position: absolute !important;
+    width: 5em;
+    height: 5em;
+    padding: 0.5em;
+    z-index: 1;
+    border-radius: 0.5em;
+    box-shadow: 2px 2px 19px #aaa;
+    background: white;
+    word-wrap: break-word;
+    padding-top: 24px;
+    text-align: center;
+}
+
+.block-cartridge {
+    width: 80px;
+    height: 80px;
+    background-color: rgb(109, 123, 112);
+    float: left;
+    margin: 5px;
+    padding: 5px;
+    word-wrap: break-word;
+    cursor: pointer;
+}
+
+.block-group {
+    width: 80px;
+    height: 80px;
+    background-color: rgb(109, 123, 112);
+    float: left;
+    margin: 5px;
+    padding: 5px;
+    word-wrap: break-word;
+    cursor: pointer;
+}
+
+.app-creator {
+    height: 600px;
+    background-color: rgb(244, 244, 244);
+    border: 1px solid #ddd;
+    border-radius: 4px;
+    margin-left: 10px;
+    position: relative;
+    background-image: url("../images/grid.png");
+}
+
+#whiteboard{
+    width: 800px;
+    height: 600px;
+    position: absolute;
+}
+
+.description{
+    min-height: 300px;
+    max-height: 400px;
+}
+
+.component-section{
+    max-height: 200px;
+    overflow: auto;
+    min-height: 200px;
+}
+
+.description-section{
+    min-height: 260px;
+    max-height: 400px;
+    overflow: auto;
+}
+
+.app-details {
+    margin: 10px;
+}
+
+.app-details-tab-content{
+    border: 1px solid #ddd;
+    border-top: transparent;
+    min-height: 233px;
+    padding: 20px;
+    border-radius:  0 0 4px 4px;
+}
+.dragActive {
+    border: 2px dotted orange;
+
+}
+
+.node-disable{
+    background-color: #bdc3c7;
+}
+
+
+.node circle {
+    fill: #fff;
+    stroke: steelblue;
+    stroke-width: 3px;
+}
+
+.node text { font: 12px sans-serif; }
+
+.link {
+    fill: none;
+    stroke: #ccc;
+    stroke-width: 2px;
+}
+
+.input-false{
+    background-color: #CCC;
+    border-color: #ddd;
+    border-width: 1px;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/stratos/blob/3bf8da14/components/org.apache.stratos.manager.console/console/themes/theme0/helpers/applications_editor.js
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/helpers/applications_editor.js b/components/org.apache.stratos.manager.console/console/themes/theme0/helpers/applications_editor.js
new file mode 100644
index 0000000..2af9bc9
--- /dev/null
+++ b/components/org.apache.stratos.manager.console/console/themes/theme0/helpers/applications_editor.js
@@ -0,0 +1,7 @@
+var resources = function (page, meta) {
+    return {
+        js: ['JSONEditor-0.7.12/jsoneditor-0.7.12.js','bootstrap-switch-3.0.2/bootstrap-switch.min.js', 'custom/script.js','custom/form.js', 'd3js-v3/d3.v3.min.js',
+            'jquery.contextMenu/jquery.contextMenu.js', 'jquery.contextMenu/jquery.ui.position.js', 'jsplumb-1.7.2/dom.jsPlumb-1.7.2-min.js','custom/applications-editor.js'],
+        css: ['bootstrap-switch-3.0.2/bootstrap-switch.min.css', 'custom/style.css', 'custom/application_editor.css']
+    };
+};

http://git-wip-us.apache.org/repos/asf/stratos/blob/3bf8da14/components/org.apache.stratos.manager.console/console/themes/theme0/js/custom/applications-editor.js
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/js/custom/applications-editor.js b/components/org.apache.stratos.manager.console/console/themes/theme0/js/custom/applications-editor.js
new file mode 100644
index 0000000..89b0af8
--- /dev/null
+++ b/components/org.apache.stratos.manager.console/console/themes/theme0/js/custom/applications-editor.js
@@ -0,0 +1,755 @@
+// repaint
+function Repaint(){
+    $("#whiteboard").resize(function(){
+        jsPlumb.repaintEverything();
+    });
+}
+// drag
+function DragEl(el){
+    jsPlumb.draggable($(el) ,{
+        containment:"#whiteboard"
+    });
+}
+
+
+// JsPlumb Config
+var color = "gray",
+    exampleColor = "#00f",
+    arrowCommon = { foldback:0.7, fillStyle:color, width:14 };
+
+jsPlumb.importDefaults({
+    Connector : [ "Bezier", { curviness:63 } ],
+    /*Overlays: [
+     [ "Arrow", { location:0.7 }, arrowCommon ],
+     ]*/
+});
+
+
+var nodeDropOptions = {
+    activeClass:"dragActive"
+};
+
+var bottomConnectorOptions = {
+    endpoint:"Rectangle",
+    paintStyle:{ width:25, height:21, fillStyle:'#666' },
+    isSource:true,
+    connectorStyle : { strokeStyle:"#666" },
+    isTarget:false,
+    maxConnections:5
+};
+
+var endpointOptions = {
+    isTarget:true,
+    endpoint:"Dot",
+    paintStyle:{
+        fillStyle:"gray"
+    },
+    dropOptions: nodeDropOptions,
+    maxConnections:1
+};
+
+var groupOptions = {
+    isTarget:true,
+    endpoint:"Dot",
+    paintStyle:{
+        fillStyle:"gray"
+    },
+    dropOptions: nodeDropOptions,
+    maxConnections:1
+};
+
+var generatedCartridgeEndpointOptions = {
+    isTarget:false,
+    endpoint:"Dot",
+    paintStyle:{
+        fillStyle:"gray"
+    },
+    dropOptions: '',
+    maxConnections:1
+};
+
+var generatedGroupOptions = {
+    isTarget:false,
+    endpoint:"Dot",
+    paintStyle:{
+        fillStyle:"gray"
+    },
+    dropOptions: nodeDropOptions,
+    maxConnections:1
+};
+
+jsPlumb.ready(function() {
+    //create application level block
+    jsPlumb.addEndpoint('applicationId', {
+        anchor:"BottomCenter"
+    }, bottomConnectorOptions);
+});
+
+var cartridgeCounter=0;
+//add cartridge to editor
+function addJsplumbCartridge(idname, cartridgeCounter) {
+
+    var Div = $('<div>').attr({'id':cartridgeCounter+'-'+idname, 'data-type':'cartridge', 'data-ctype':idname } )
+        .text(idname)
+        .addClass('input-false')
+        .appendTo('#whiteboard');
+    $(Div).addClass('stepnode');
+    jsPlumb.addEndpoint($(Div), {
+        anchor: "TopCenter"
+    }, endpointOptions);
+    // jsPlumb.addEndpoint($(Div), sourceEndpoint);
+    DragEl($(Div));
+    Repaint();
+}
+
+//add group to editor
+function addJsplumbGroup(groupJSON, cartridgeCounter){
+
+    var divRoot = $('<div>').attr({'id':cartridgeCounter+'-'+groupJSON.name,'data-type':'group','data-ctype':groupJSON.name})
+        .text(groupJSON.name)
+        .addClass('input-false')
+        .addClass('stepnode')
+        .appendTo('#whiteboard');
+    jsPlumb.addEndpoint($(divRoot), {
+        anchor:"BottomCenter"
+    }, bottomConnectorOptions);
+
+    jsPlumb.addEndpoint($(divRoot), {
+        anchor: "TopCenter"
+    }, groupOptions);
+    DragEl($(divRoot));
+
+    for (var prop in groupJSON) {
+        if(prop == 'cartridges'){
+            genJsplumbCartridge(groupJSON[prop], divRoot, groupJSON.name)
+        }
+        if(prop == 'groups'){
+            genJsplumbGroups(groupJSON[prop], divRoot, groupJSON.name)
+        }
+    }
+
+    function genJsplumbCartridge(item, currentParent, parentName){
+        for (var i = 0; i < item.length; i++) {
+            var id = item[i];
+            var divCartridge = $('<div>').attr({'id':cartridgeCounter+'-'+parentName+'-'+item[i],'data-type':'cartridge','data-ctype':item[i]} )
+                .text(item[i])
+                .addClass('input-false')
+                .addClass('stepnode')
+                .appendTo('#whiteboard');
+
+            jsPlumb.addEndpoint($(divCartridge), {
+                anchor: "TopCenter"
+            }, generatedCartridgeEndpointOptions);
+
+            //add connection options
+            jsPlumb.connect({
+                source:$(currentParent),
+                target:$(divCartridge),
+                paintStyle:{strokeStyle:"blue", lineWidth:1 },
+                Connector : [ "Bezier", { curviness:63 } ],
+                anchors:["BottomCenter", "TopCenter"],
+                endpoint:"Dot"
+            });
+
+            DragEl($(divCartridge));
+        }
+    }
+
+    function genJsplumbGroups(item, currentParent, parentName) {
+        for (var prop in item) {
+            var divGroup = $('<div>').attr({'id':cartridgeCounter+'-'+parentName+'-'+item[prop]['name'],'data-type':'group','data-ctype':item[prop]['name'] })
+                .text(item[prop]['name'])
+                .addClass('stepnode')
+                .addClass('input-false')
+                .appendTo('#whiteboard');
+            jsPlumb.addEndpoint($(divGroup), {
+                anchor:"BottomCenter"
+            }, bottomConnectorOptions);
+
+            jsPlumb.addEndpoint($(divGroup), {
+                anchor: "TopCenter"
+            }, generatedGroupOptions);
+
+            //add connection options
+            jsPlumb.connect({
+                source:$(currentParent),
+                target:$(divGroup),
+                paintStyle:{strokeStyle:"blue", lineWidth:1 },
+                Connector : [ "Bezier", { curviness:63 } ],
+                anchors:["BottomCenter", "TopCenter"],
+                endpoint:"Dot"
+            });
+
+            DragEl($(divGroup));
+
+            if(item[prop].hasOwnProperty('cartridges')) {
+                genJsplumbCartridge(item[prop].cartridges, divGroup, parentName+'-'+item[prop]['name'] );
+            }
+            if(item[prop].hasOwnProperty('groups')) {
+                genJsplumbGroups(item[prop].groups, divGroup, parentName+'-'+item[prop]['name'])
+            }
+        }
+    }
+
+
+
+}
+//use to activate tab
+function activateTab(tab){
+    $('.nav-tabs a[href="#' + tab + '"]').tab('show');
+};
+//generate treefor Groups
+function generateGroupTree(groupJSON){
+
+    var rawout = [];
+    //create initial node for tree
+    var rootnode ={};
+    rootnode.name = groupJSON.name;
+    rootnode.parent = null;
+    rootnode.type = 'groups';
+    rawout.push(rootnode);
+
+    for (var prop in groupJSON) {
+        if(prop == 'cartridges'){
+            getCartridges(groupJSON[prop],rawout, rootnode.name)
+        }
+        if(prop == 'groups'){
+            getGroups(groupJSON[prop], rawout, rootnode.name)
+        }
+    }
+
+    function getCartridges(item, collector, parent){
+        for (var i = 0; i < item.length; i++) {
+            var type = 'cartridges';
+            var cur_name = item[i];
+            collector.push({"name": cur_name, "parent": parent, "type": type});
+        }
+    }
+
+    function getGroups(item, collector, parent){
+        for (var prop in item) {
+            var cur_name = item[prop]['name'];
+            var type = 'groups';
+            collector.push({"name": cur_name, "parent": parent, "type": type});
+            if(item[prop].hasOwnProperty('cartridges')) {
+                getCartridges(item[prop].cartridges, collector, cur_name);
+            }
+            if(item[prop].hasOwnProperty('groups')) {
+                getGroups(item[prop].groups, collector, cur_name)
+            }
+        }
+    }
+
+    return rawout;
+
+}
+
+// ************** Generate the tree diagram	 *****************
+function generateGroupPreview(data) {
+    //clean current graph and text
+    $(".description-section").html('');
+
+    //mapping data
+    var dataMap = data.reduce(function(map, node) {
+        map[node.name] = node;
+        return map;
+    }, {});
+    var treeData = [];
+    data.forEach(function(node) {
+        // add to parent
+        var parent = dataMap[node.parent];
+        if (parent) {
+            // create child array if it doesn't exist
+            (parent.children || (parent.children = []))
+                // add node to child array
+                .push(node);
+        } else {
+            // parent is null or missing
+            treeData.push(node);
+        }
+    });
+
+    var source = treeData[0];
+
+//generate position for tree view
+    var margin = {top: 25, right: 5, bottom: 5, left: 5},
+        width = 320 - margin.right - margin.left,
+        height = 500 - margin.top - margin.bottom;
+
+    var i = 0;
+
+    var tree = d3.layout.tree()
+        .size([height, width]);
+
+    var diagonal = d3.svg.diagonal()
+        .projection(function(d) { return [d.x, d.y]; });
+
+    var svg = d3.select(".description-section").append("svg")
+        .attr("width", width)
+        .attr("height", height)
+        .append("g")
+        .attr("transform", "translate(" + -90+ "," + margin.top + ")");
+
+    // Compute the new tree layout.
+    var nodes = tree.nodes(source).reverse(),
+        links = tree.links(nodes);
+
+    // Normalize for fixed-depth.
+    nodes.forEach(function(d) { d.y = d.depth * 100; });
+
+    // Declare the nodes…
+    var node = svg.selectAll("g.node")
+        .data(nodes, function(d) { return d.id || (d.id = ++i); });
+
+    // Enter the nodes.
+    var nodeEnter = node.enter().append("g")
+        .attr("class", "node")
+        .attr("transform", function(d) {
+            return "translate(" + d.x + "," + d.y + ")"; });
+
+    nodeEnter.append("circle")
+        .attr("r", 4)
+        .style("fill", "#fff");
+
+    nodeEnter.append("text")
+        .attr("y", function(d) {
+            return d.children || d._children ? -20 : 20; })
+        .attr("dy", ".35em")
+        .attr("text-anchor", "middle")
+        .text(function(d) { return d.name; })
+        .style("fill-opacity", 1);
+
+    // Declare the links
+    var link = svg.selectAll("path.link")
+        .data(links, function(d) { return d.target.id; });
+
+    // Enter the links.
+    link.enter().insert("path", "g")
+        .attr("class", "link")
+        .attr("d", diagonal);
+
+}
+
+// ************* Add context menu for nodes ******************
+//remove nodes from workarea
+function deleteNode(endPoint){
+    if(endPoint.attr('id') != 'applicationId'){
+        var that=endPoint;      //get all of your DIV tags having endpoints
+        for (var i=0;i<that.length;i++) {
+            var endpoints = jsPlumb.getEndpoints($(that[i])); //get all endpoints of that DIV
+            for (var m=0;m<endpoints.length;m++) {
+                // if(endpoints[m].anchor.type=="TopCenter") //Endpoint on right side
+                jsPlumb.deleteEndpoint(endpoints[m]);  //remove endpoint
+            }
+        }
+        jsPlumb.detachAllConnections(endPoint);
+        endPoint.remove();
+    }
+
+}
+
+//genrate context menu for nodes
+$(function(){
+    $.contextMenu({
+        selector: '.stepnode',
+        callback: function(key, options) {
+            var m = "clicked: " + key + $(this);
+            if(key == 'delete'){
+                deleteNode($(this));
+            }else if(key == 'edit'){
+
+            }
+
+            window.console && console.log($(this));
+        },
+        items: {
+            "edit": {name: "Edit", icon: "edit"},
+            "delete": {name: "Delete", icon: "delete"},
+            "sep1": "---------",
+            "quit": {name: "Quit", icon: "quit"}
+        }
+    });
+
+});
+
+var applicationJson = {};
+//Definition JSON builder
+function generateJsplumbTree(collector, connections){
+
+    //get general data
+    $('input.level-root').each(function(){
+        var inputId = $(this).attr('id');
+        collector[inputId] = $(this).val();
+    });
+    collector['components']={};
+    collector['components']['dependencies']={};
+    collector['components']['groups']=[];
+    collector['components']['cartridges']=[];
+    collector['components']['dependencies']['startupOrders']=[];
+    collector['components']['dependencies']['scalingDependents']=[];
+    var startupOrders = $('input#startupOrders').val().split(' ').join('').split(/["][,]+/g);
+    for (var i = 0; i < startupOrders.length; i++) {
+        startupOrders[i] = startupOrders[i].replace(/"/g, "");
+    }
+
+    var scalingDependents = $('input#scalingDependents').val().split(' ').join('').split(/["][,]+/g);
+    for (var i = 0; i < scalingDependents.length; i++) {
+        scalingDependents[i] = scalingDependents[i].replace(/"/g, "");
+    }
+    collector['components']['dependencies']['startupOrders'] = startupOrders;
+    collector['components']['dependencies']['scalingDependents'] = scalingDependents;
+    collector['components']['dependencies']['terminationBehaviour']=$('select#terminationBehaviour').val();
+
+    //generate raw data tree from connections
+    var rawtree = [];
+    $.each(jsPlumb.getConnections(), function (idx, connection) {
+        var dataType = $('#'+connection.targetId).attr('data-type');
+        var jsonContent = JSON.parse(decodeURIComponent($('#'+connection.targetId).attr('data-generated')));
+        rawtree.push({
+            parent: connection.sourceId,
+            content: jsonContent,
+            dtype:dataType,
+            id: connection.targetId
+        });
+    });
+
+    //generate heirache by adding json and extra info
+    var nodes = [];
+    var toplevelNodes = [];
+    var lookupList = {};
+
+    for (var i = 0; i < rawtree.length; i++) {
+        var n = rawtree[i].content;
+        if(rawtree[i].dtype == 'cartridge'){
+            n.id =  rawtree[i].id;
+            n.parent_id = ((rawtree[i].parent == 'applicationId') ? 'applicationId': rawtree[i].parent);
+            n.dtype =rawtree[i].dtype;
+        }else if(rawtree[i].dtype == 'group'){
+            n.id =  rawtree[i].id;
+            n.parent_id = ((rawtree[i].parent == 'applicationId') ? 'applicationId': rawtree[i].parent);
+            n.dtype =rawtree[i].dtype;
+            n.groups = [];
+            n.cartridges =[];
+        }
+
+        lookupList[n.id] = n;
+        nodes.push(n);
+
+        if (n.parent_id == 'applicationId' && rawtree[i].dtype == 'cartridge') {
+            collector['components']['cartridges'].push(n);
+        }else if(n.parent_id == 'applicationId' && rawtree[i].dtype == 'group'){
+            collector['components']['groups'].push(n);
+        }
+
+    }
+
+    //merge any root level stuffs
+    for (var i = 0; i < nodes.length; i++) {
+        var n = nodes[i];
+        if (!(n.parent_id == 'applicationId') && n.dtype == 'cartridge') {
+            lookupList[n.parent_id]['cartridges'] = lookupList[n.parent_id]['cartridges'].concat([n]);
+        }else if(!(n.parent_id == 'applicationId') && n.dtype == 'group'){
+            lookupList[n.parent_id]['groups'] = lookupList[n.parent_id]['groups'].concat([n]);
+        }
+    }
+
+    //cleanup JSON, remove extra items added to object level
+    function traverse(o) {
+        for (var i in o) {
+            if(i == 'id' || i == 'parent_id' || i == 'dtype'){
+                delete o[i];
+            }else if(i == 'groups' && o[i].length == 0){
+                delete o[i];
+            }
+            if (o[i] !== null && typeof(o[i])=="object") {
+                //going on step down in the object tree!!
+                traverse(o[i]);
+            }
+        }
+    }
+
+    traverse(collector);
+    console.log(collector)
+    console.log(JSON.stringify(collector));
+    $('#messages').html(JSON.stringify(collector, null, 4))
+}
+
+//setting up schema and defaults
+var cartridgeBlockTemplate = {
+    "type":"object",
+    "$schema": "http://json-schema.org/draft-03/schema",
+    "id": "root",
+    "format":"grid",
+    "properties":{
+        "type": {
+            "type":"string",
+            "id": "root/type",
+            "default": "name",
+            "required":false
+        },
+        "cartridgeMax": {
+            "type":"number",
+            "id": "root/cartridgeMax",
+            "default":2,
+            "required":false
+        },
+        "cartridgeMin": {
+            "type":"number",
+            "id": "root/cartridgeMin",
+            "default":1,
+            "required":false
+        },
+        "subscribableInfo": {
+            "type":"object",
+            "id": "root/subscribableInfo",
+            "required":false,
+            "properties":{
+                "alias": {
+                    "type":"string",
+                    "id": "root/subscribableInfo/alias",
+                    "default": "alias2",
+                    "required":false
+                },
+                "autoscalingPolicy": {
+                    "type":"string",
+                    "id": "root/subscribableInfo/autoscalingPolicy",
+                    "default": "autoscale_policy_1",
+                    "required":false
+                },
+                "privateRepo": {
+                    "type":"string",
+                    "id": "root/subscribableInfo/privateRepo",
+                    "default": "true",
+                    "required":false
+                },
+                "repoPassword": {
+                    "type":"string",
+                    "id": "root/subscribableInfo/repoPassword",
+                    "default": "password",
+                    "required":false
+                },
+                "repoURL": {
+                    "type":"string",
+                    "id": "root/subscribableInfo/repoURL",
+                    "default": "http://xxx:10080/git/default.git",
+                    "required":false
+                },
+                "repoUsername": {
+                    "type":"string",
+                    "id": "root/subscribableInfo/repoUsername",
+                    "default": "user",
+                    "required":false
+                }
+            }
+        }
+    }
+};
+
+var cartridgeBlockDefault = {
+    "type":"tomcat",
+    "cartridgeMin":1,
+    "cartridgeMax":2,
+    "subscribableInfo":{
+        "alias":"alias2",
+        "autoscalingPolicy":"autoscale_policy_1",
+        "privateRepo":"true",
+        "repoPassword":"password",
+        "repoURL":"http://xxx:10080/git/default.git",
+        "repoUsername":"user"
+    }
+};
+
+var groupBlockTemplate = {
+    "type":"object",
+    "$schema": "http://json-schema.org/draft-03/schema",
+    "id": "root",
+    "required":false,
+    "properties":{
+        "name": {
+            "type":"string",
+            "id": "root/name",
+            "default": "name",
+            "required":false
+        },
+        "alias": {
+            "type":"string",
+            "id": "root/alias",
+            "default": "alias",
+            "required":false
+        },
+        "groupMaxInstances": {
+            "type":"number",
+            "id": "root/groupMaxInstances",
+            "default":2,
+            "required":false
+        },
+        "groupMinInstances": {
+            "type":"number",
+            "id": "root/groupMinInstances",
+            "default":1,
+            "required":false
+        },
+        "isGroupScalingEnabled": {
+            "type":"boolean",
+            "id": "root/isGroupScalingEnabled",
+            "default": "false",
+            "required":false
+        }
+    }
+};
+
+var groupBlockDefault = {
+    "name":"group2",
+    "alias":"group2alias",
+    "groupMinInstances":1,
+    "groupMaxInstances":2,
+    "isGroupScalingEnabled":"false"
+};
+
+//create cartridge list
+var cartridgeListHtml='';
+function generateCartridges(data){
+    for(var cartridge in data){
+        var cartridgeData = data[cartridge];
+        cartridgeListHtml += '<div class="block-cartridge" ' +
+            'data-info="'+cartridgeData.description+ '"'+
+            'data-toggle="tooltip" data-placement="bottom" title="Single Click to view details. Double click to add"'+
+            'id="'+cartridgeData.cartridgeType+'">'
+            + cartridgeData.displayName+
+            '</div>'
+    }
+    //append cartridge into html content
+    $('#cartridge-list').append(cartridgeListHtml);
+}
+
+//create group list
+var groupListHtml='';
+function generateGroups(data){
+    for(var group in data){
+        var groupData = data[group];
+        groupListHtml += '<div class="block-group" ' +
+            ' data-info="'+encodeURIComponent(JSON.stringify(groupData))+'"'+
+            'id="'+groupData.name+'">'
+            + groupData.name+
+            '</div>'
+    }
+    //append cartridge into html content
+    $('#group-list').append(groupListHtml);
+}
+// Document ready events
+$(document).ready(function(){
+
+    $('#app-generate').on('click', function(){
+        generateJsplumbTree(applicationJson, jsPlumb.getConnections());
+    });
+    //*******************Adding JSON editor *************//
+    JSONEditor.defaults.theme = 'bootstrap3';
+    JSONEditor.defaults.iconlib = 'fontawesome4';
+    JSONEditor.defaults.show_errors = "always";
+    var editor, blockId;
+
+
+    DragEl(".stepnode");
+    Repaint();
+
+    $('#whiteboard').on('dblclick', '.stepnode', function(){
+        //get tab activated
+        if($(this).attr('id') == 'applicationId'){
+            activateTab('general');
+        }else{
+            activateTab('components');
+        }
+
+        blockId = $(this).attr('id');
+        var blockType = $(this).attr('data-type');
+        var startval;
+        var ctype = $(this).attr('data-ctype');
+        if(blockType == 'cartridge' || blockType == 'group-cartridge'){
+            startval = cartridgeBlockDefault;
+            startval['type'] = ctype;
+        }else{
+            startval = groupBlockDefault;
+            startval['name'] = ctype;
+        }
+
+        if($(this).attr('data-generated')) {
+            startval = JSON.parse(decodeURIComponent($(this).attr('data-generated')));
+        }
+        $('#component-data').html('');
+
+        switch (blockType){
+            case 'cartridge':
+                generateHtmlBlock(cartridgeBlockTemplate, startval);
+                break;
+
+            case 'group':
+                generateHtmlBlock(groupBlockTemplate, startval);
+                break;
+
+            case 'group-cartridge':
+                generateHtmlBlock(cartridgeBlockTemplate, startval);
+                break;
+        }
+
+    });
+
+    function generateHtmlBlock(schema, startval){
+        // Initialize the editor
+        editor = new JSONEditor(document.getElementById('component-data'), {
+            ajax: false,
+            disable_edit_json: true,
+            schema: schema,
+            format: "grid",
+            startval: startval
+        });
+        if(editor.getEditor('root.type')){
+            editor.getEditor('root.type').disable();
+        }else{
+            editor.getEditor('root.name').disable();
+        }
+
+    }
+
+    //get component JSON data
+    $('#component-info-update').on('click', function(){
+        $('#'+blockId).attr('data-generated', encodeURIComponent(JSON.stringify(editor.getValue())));
+        $('#'+blockId).removeClass('input-false');
+
+    });
+
+    //get create cartridge list
+    generateCartridges(cartridgeList.cartridge);
+    //get group JSON
+    generateGroups(groupList.groups);
+
+    //handle single click for cartridge
+    $('#cartridge-list').on('click', ".block-cartridge", function(){
+        $('.description-section').html($(this).attr('data-info'));
+    });
+    //handle double click for cartridge
+    $('#cartridge-list').on('dblclick', ".block-cartridge", function(){
+        addJsplumbCartridge($(this).attr('id'),cartridgeCounter);
+        //increase global count for instances
+        cartridgeCounter++;
+    });
+
+    //handle single click for groups
+    $('#group-list').on('click', ".block-group", function(){
+        var groupJSON = JSON.parse(decodeURIComponent($(this).attr('data-info')));
+        mydata = generateGroupTree(groupJSON);
+        generateGroupPreview(mydata);
+
+
+    });
+    //handle double click event for groups
+    $('#group-list').on('dblclick', ".block-group", function(){
+        var groupJSON = JSON.parse(decodeURIComponent($(this).attr('data-info')));
+        addJsplumbGroup(groupJSON,cartridgeCounter);
+        //increase global count for instances
+        cartridgeCounter++;
+    });
+
+
+});
+
+

http://git-wip-us.apache.org/repos/asf/stratos/blob/3bf8da14/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs b/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs
index e69de29..9abc1dc 100644
--- a/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs
+++ b/components/org.apache.stratos.manager.console/console/themes/theme0/partials/applications_editor.hbs
@@ -0,0 +1,147 @@
+<div id="centered">
+    <div class="row title">
+        <div class="title-main text-center">
+                <h1>Create Your Application</h1>
+        </div>
+    </div>
+    <div class='container' id='content'>
+        <div class='row'>
+            <div class='container text-center form-toolbar'>
+                    <div class='col-md-5'>
+                        <div class="editor-button">
+
+                        </div>
+
+                    </div>
+                    <div class='col-md-7'>
+                        <button class='btn btn-info btn-lg pull-right' type='button' id='deploy' data-form='{{formContext}}'> Deploy {{formTitle}}</button>
+                        <button class='btn btn-default btn-lg pull-right button-gap' type='button' onclick='window.location.replace(document.referrer)'> Cancel</button>
+
+                    </div>
+            </div>
+        </div>
+        <div class="left-side">
+            <div class="components">
+                <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
+                    <div class="panel panel-default">
+                        <div class="panel-heading" role="tab" id="headingOne">
+                            <h4 class="panel-title">
+                                <a data-toggle="collapse" data-parent="#accordion" href="#collapseOne"
+                                   aria-expanded="true" aria-controls="collapseOne">
+                                    Cartridges
+                                </a>
+                            </h4>
+                        </div>
+                        <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel"
+                             aria-labelledby="headingOne">
+                            <div class="panel-body component-section" id="cartridge-list">
+                                <!-- Automatic content will be added -->
+                            </div>
+                        </div>
+                    </div>
+                    <div class="panel panel-default ">
+                        <div class="panel-heading" role="tab" id="headingTwo">
+                            <h4 class="panel-title">
+                                <a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo"
+                                   aria-expanded="false" aria-controls="collapseTwo">
+                                    Groups
+                                </a>
+                            </h4>
+                        </div>
+                        <div id="collapseTwo" class="panel-collapse collapse" role="tabpanel"
+                             aria-labelledby="headingTwo">
+                            <div class="panel-body component-section" id="group-list">
+                                <!-- group will automatically added -->
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="description" >
+                <div class="panel panel-default">
+                    <div class="panel-heading">
+                        <h3 class="panel-title">Details</h3>
+                    </div>
+                    <div class="panel-body description-section">
+
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="right-side">
+            <div class="app-creator">
+                <div id="whiteboard">
+                    <div id="applicationId" class="stepnode">
+                        App Id
+                    </div>
+                </div>
+
+            </div>
+            <div class="app-details">
+                <div role="tabpanel app-details-tab" >
+
+                    <!-- Nav tabs -->
+                    <ul class="nav nav-tabs" role="tablist">
+                        <li role="presentation" class="active"><a href="#general" aria-controls="general" role="tab"
+                                                                  data-toggle="tab">General Details</a></li>
+                        <li role="presentation"><a href="#components" aria-controls="components"
+                                                   role="tab" data-toggle="tab">Components</a></li>
+
+                    </ul>
+
+                    <!-- Tab panes -->
+                    <div class="tab-content app-details-tab-content">
+                        <div role="tabpanel" class="tab-pane active" id="general">
+
+                            <div class="form-group">
+                                <label class="control-label" for="applicationId">Application Id:</label>
+                                <input type="text" class="form-control level-root" placeholder="" id="applicationId">
+                            </div>
+                            <div class="form-group">
+                                <label class="control-label" for="alias">Alias:</label>
+                                <input type="text" class="form-control level-root" placeholder="" id="alias">
+                            </div>
+                            <div class="panel panel-default">
+                                <div class="panel-heading">Dependencies</div>
+                                <div class="panel-body">
+                                    <div class="form-group">
+                                        <label class="control-label" for="alias">Startup Orders:</label>
+                                        <input type="text" class="form-control level-components" placeholder="" id="startupOrders">
+                                    </div>
+                                    <div class="form-group">
+                                        <label class="control-label" for="alias">Scaling Dependents:</label>
+                                        <input type="text" class="form-control level-components" placeholder="" id="scalingDependents">
+                                    </div>
+                                    <div class="form-group">
+                                        <label class="control-label" for="alias">Termination Behaviour:</label>
+                                        <select class="form-control level-components" id="terminationBehaviour">
+                                            <option value="terminate-none">terminate-none</option>
+                                            <option value="terminate-dependents">terminate-dependents</option>
+                                            <option value="terminate-all">terminate-all</option>
+                                        </select>
+                                    </div>
+                                </div>
+                            </div>
+
+                        </div>
+                        <div role="tabpanel" class="tab-pane components" id="components">
+                            <button type="button" class="btn btn-primary" id="component-info-update">Update</button>
+                            <button type="button" class="btn btn-primary" id="app-generate">Generate</button>
+                            <div id="component-data">
+
+                            </div>
+                        </div>
+                    </div>
+
+                </div>
+            </div>
+        </div>
+    </div>
+
+    </div>
+
+<script>
+    //use for application generation;
+    var cartridgeList = {{{editorCartridges}}};
+    var groupList = {{{editorGroups}}};
+</script>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/stratos/blob/3bf8da14/components/org.apache.stratos.manager.console/console/themes/theme0/renderers/applications_form.js
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/renderers/applications_form.js b/components/org.apache.stratos.manager.console/console/themes/theme0/renderers/applications_form.js
index 2a7d8fe..d5ec8be 100644
--- a/components/org.apache.stratos.manager.console/console/themes/theme0/renderers/applications_form.js
+++ b/components/org.apache.stratos.manager.console/console/themes/theme0/renderers/applications_form.js
@@ -136,7 +136,8 @@ var render = function (theme, data, meta, require) {
                         context: {
                             formContext: data.breadcrumbPathLevelTwo,
                             appName: data.appName,
-                            topology_data: data.topology_data,
+                            editorCartridges: data.editorCartridges,
+                            editorGroups:data.editorGroups,
                             form_action: data.form_action,
                             formHtml: data.formHtml,
                             formData: data.formData,
@@ -144,9 +145,8 @@ var render = function (theme, data, meta, require) {
                             formDataEdit: data.formDataEdit,
                             isForm: data.isForm,
                             isEdit: data.isEdit,
-                            formTitle: data.formTitle,
-                            content_body: {sections: data.list_data
-                            }
+                            formTitle: data.formTitle
+
                         }
                     }
 


[5/8] stratos git commit: jsPlumb lib added to application editor

Posted by im...@apache.org.
http://git-wip-us.apache.org/repos/asf/stratos/blob/f72d80fd/components/org.apache.stratos.manager.console/console/themes/theme0/js/jsplumb-1.7.2/dom.jsPlumb-1.7.2-min.js
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager.console/console/themes/theme0/js/jsplumb-1.7.2/dom.jsPlumb-1.7.2-min.js b/components/org.apache.stratos.manager.console/console/themes/theme0/js/jsplumb-1.7.2/dom.jsPlumb-1.7.2-min.js
new file mode 100644
index 0000000..5e22a63
--- /dev/null
+++ b/components/org.apache.stratos.manager.console/console/themes/theme0/js/jsplumb-1.7.2/dom.jsPlumb-1.7.2-min.js
@@ -0,0 +1,6 @@
+!function(){"undefined"==typeof Math.sgn&&(Math.sgn=function(a){return 0==a?0:a>0?1:-1});var a={subtract:function(a,b){return{x:a.x-b.x,y:a.y-b.y}},dotProduct:function(a,b){return a.x*b.x+a.y*b.y},square:function(a){return Math.sqrt(a.x*a.x+a.y*a.y)},scale:function(a,b){return{x:a.x*b,y:a.y*b}}},b=64,c=Math.pow(2,-b-1),d=function(b,c){for(var d=[],e=f(b,c),h=c.length-1,i=2*h-1,j=g(e,i,d,0),k=a.subtract(b,c[0]),m=a.square(k),n=0,o=0;j>o;o++){k=a.subtract(b,l(c,h,d[o],null,null));var p=a.square(k);m>p&&(m=p,n=d[o])}return k=a.subtract(b,c[h]),p=a.square(k),m>p&&(m=p,n=1),{location:n,distance:m}},e=function(a,b){var c=d(a,b);return{point:l(b,b.length-1,c.location,null,null),location:c.location}},f=function(b,c){for(var d=c.length-1,e=2*d-1,f=[],g=[],h=[],i=[],k=[[1,.6,.3,.1],[.4,.6,.6,.4],[.1,.3,.6,1]],l=0;d>=l;l++)f[l]=a.subtract(c[l],b);for(var l=0;d-1>=l;l++)g[l]=a.subtract(c[l+1],c[l]),g[l]=a.scale(g[l],3);for(var m=0;d-1>=m;m++)for(var n=0;d>=n;n++)h[m]||(h[m]=[]),h[m][n]=a.dotPro
 duct(g[m],f[n]);for(l=0;e>=l;l++)i[l]||(i[l]=[]),i[l].y=0,i[l].x=parseFloat(l)/e;for(var o=d,p=d-1,q=0;o+p>=q;q++){var r=Math.max(0,q-p),s=Math.min(q,o);for(l=r;s>=l;l++)j=q-l,i[l+j].y+=h[j][l]*k[j][l]}return i},g=function(a,c,d,e){var f,j,m=[],n=[],o=[],p=[];switch(h(a,c)){case 0:return 0;case 1:if(e>=b)return d[0]=(a[0].x+a[c].x)/2,1;if(i(a,c))return d[0]=k(a,c),1}l(a,c,.5,m,n),f=g(m,c,o,e+1),j=g(n,c,p,e+1);for(var q=0;f>q;q++)d[q]=o[q];for(var q=0;j>q;q++)d[q+f]=p[q];return f+j},h=function(a,b){var c,d,e=0;c=d=Math.sgn(a[0].y);for(var f=1;b>=f;f++)c=Math.sgn(a[f].y),c!=d&&e++,d=c;return e},i=function(a,b){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;i=a[0].y-a[b].y,j=a[b].x-a[0].x,k=a[0].x*a[b].y-a[b].x*a[0].y;for(var t=max_distance_below=0,u=1;b>u;u++){var v=i*a[u].x+j*a[u].y+k;v>t?t=v:max_distance_below>v&&(max_distance_below=v)}return n=0,o=1,p=0,q=i,r=j,s=k-t,l=n*r-q*o,m=1/l,e=(o*s-r*p)*m,q=i,r=j,s=k-max_distance_below,l=n*r-q*o,m=1/l,f=(o*s-r*p)*m,g=Math.min(e,f),h=Math.max(e,f),d=h-
 g,c>d?1:0},k=function(a,b){var c=1,d=0,e=a[b].x-a[0].x,f=a[b].y-a[0].y,g=a[0].x-0,h=a[0].y-0,i=e*d-f*c,j=1/i,k=(e*h-f*g)*j;return 0+c*k},l=function(a,b,c,d,e){for(var f=[[]],g=0;b>=g;g++)f[0][g]=a[g];for(var h=1;b>=h;h++)for(var g=0;b-h>=g;g++)f[h]||(f[h]=[]),f[h][g]||(f[h][g]={}),f[h][g].x=(1-c)*f[h-1][g].x+c*f[h-1][g+1].x,f[h][g].y=(1-c)*f[h-1][g].y+c*f[h-1][g+1].y;if(null!=d)for(g=0;b>=g;g++)d[g]=f[g][0];if(null!=e)for(g=0;b>=g;g++)e[g]=f[b-g][g];return f[b][0]},m={},n=function(a){var b=m[a];if(!b){b=[];var c=function(){return function(b){return Math.pow(b,a)}},d=function(){return function(b){return Math.pow(1-b,a)}},e=function(a){return function(){return a}},f=function(){return function(a){return a}},g=function(){return function(a){return 1-a}},h=function(a){return function(b){for(var c=1,d=0;d<a.length;d++)c*=a[d](b);return c}};b.push(new c);for(var i=1;a>i;i++){for(var j=[new e(a)],k=0;a-i>k;k++)j.push(new f);for(var k=0;i>k;k++)j.push(new g);b.push(new h(j))}b.push(new d),m[a
 ]=b}return b},o=function(a,b){for(var c=n(a.length-1),d=0,e=0,f=0;f<a.length;f++)d+=a[f].x*c[f](b),e+=a[f].y*c[f](b);return{x:d,y:e}},p=function(a,b){return Math.sqrt(Math.pow(a.x-b.x,2)+Math.pow(a.y-b.y,2))},q=function(a){return a[0].x==a[1].x&&a[0].y==a[1].y},r=function(a,b,c){if(q(a))return{point:a[0],location:b};for(var d=o(a,b),e=0,f=b,g=c>0?1:-1,h=null;e<Math.abs(c);)f+=.005*g,h=o(a,f),e+=p(h,d),d=h;return{point:h,location:f}},s=function(a){if(q(a))return 0;for(var b=o(a,0),c=0,d=0,e=1,f=null;1>d;)d+=.005*e,f=o(a,d),c+=p(f,b),b=f;return c},t=function(a,b,c){return r(a,b,c).point},u=function(a,b,c){return r(a,b,c).location},v=function(a,b){var c=o(a,b),d=o(a.slice(0,a.length-1),b),e=d.y-c.y,f=d.x-c.x;return 0==e?1/0:Math.atan(e/f)},w=function(a,b,c){var d=r(a,b,c);return d.location>1&&(d.location=1),d.location<0&&(d.location=0),v(a,d.location)},x=function(a,b,c,d){d=null==d?0:d;var e=r(a,b,d),f=v(a,e.location),g=Math.atan(-1/f),h=c/2*Math.sin(g),i=c/2*Math.cos(g);return[{x:e.po
 int.x+i,y:e.point.y+h},{x:e.point.x-i,y:e.point.y-h}]};window.jsBezier={distanceFromCurve:d,gradientAtPoint:v,gradientAtPointAlongCurveFrom:w,nearestPointOnCurve:e,pointOnCurve:o,pointAlongCurveFrom:t,perpendicularToCurveAt:x,locationAlongCurveFrom:u,getLength:s}}(),function(){"use strict";var a=this.Biltong={},b=function(a){return"[object Array]"===Object.prototype.toString.call(a)},c=function(a,c,d){return a=b(a)?a:[a.x,a.y],c=b(c)?c:[c.x,c.y],d(a,c)},d=a.gradient=function(a,b){return c(a,b,function(a,b){return b[0]==a[0]?b[1]>a[1]?1/0:-1/0:b[1]==a[1]?b[0]>a[0]?0:-0:(b[1]-a[1])/(b[0]-a[0])})},e=(a.normal=function(a,b){return-1/d(a,b)},a.lineLength=function(a,b){return c(a,b,function(a,b){return Math.sqrt(Math.pow(b[1]-a[1],2)+Math.pow(b[0]-a[0],2))})},a.quadrant=function(a,b){return c(a,b,function(a,b){return b[0]>a[0]?b[1]>a[1]?2:1:b[0]==a[0]?b[1]>a[1]?2:1:b[1]>a[1]?3:4})}),f=(a.theta=function(a,b){return c(a,b,function(a,b){var c=d(a,b),f=Math.atan(c),g=e(a,b);return(4==g||3==g)
 &&(f+=Math.PI),0>f&&(f+=2*Math.PI),f})},a.intersects=function(a,b){var c=a.x,d=a.x+a.w,e=a.y,f=a.y+a.h,g=b.x,h=b.x+b.w,i=b.y,j=b.y+b.h;return g>=c&&d>=g&&i>=e&&f>=i||h>=c&&d>=h&&i>=e&&f>=i||g>=c&&d>=g&&j>=e&&f>=j||h>=c&&d>=g&&j>=e&&f>=j||c>=g&&h>=c&&e>=i&&j>=e||d>=g&&h>=d&&e>=i&&j>=e||c>=g&&h>=c&&f>=i&&j>=f||d>=g&&h>=c&&f>=i&&j>=f},a.encloses=function(a,b,c){var d=a.x,e=a.x+a.w,f=a.y,g=a.y+a.h,h=b.x,i=b.x+b.w,j=b.y,k=b.y+b.h,l=function(a,b,d,e){return c?b>=a&&d>=e:b>a&&d>e};return l(d,h,e,i)&&l(f,j,g,k)},[null,[1,-1],[1,1],[-1,1],[-1,-1]]),g=[null,[-1,-1],[-1,1],[1,1],[1,-1]];a.pointOnLine=function(a,b,c){var h=d(a,b),i=e(a,b),j=c>0?f[i]:g[i],k=Math.atan(h),l=Math.abs(c*Math.sin(k))*j[1],m=Math.abs(c*Math.cos(k))*j[0];return{x:a.x+m,y:a.y+l}},a.perpendicularLineTo=function(a,b,c){var e=d(a,b),f=Math.atan(-1/e),g=c/2*Math.sin(f),h=c/2*Math.cos(f);return[{x:b.x+h,y:b.y+g},{x:b.x-h,y:b.y-g}]}}.call(this),function(){"use strict";var a={android:navigator.userAgent.toLowerCase().indexOf("
 android")>-1},b=function(a,b,c){c=c||a.parentNode;for(var d=c.querySelectorAll(b),e=0;e<d.length;e++)if(d[e]===a)return!0;return!1},c=function(a){return"string"==typeof a?document.getElementById(a):a},d=function(a){return a.srcElement||a.target},e=function(a,b){for(var c=0,d=a.length;d>c&&a[c]!=b;c++);c<a.length&&a.splice(c,1)},f=1,g=function(a,b,c){var d=f++;return a.__ta=a.__ta||{},a.__ta[b]=a.__ta[b]||{},a.__ta[b][d]=c,c.__tauid=d,d},h=function(a,b,c){if(a.__ta&&a.__ta[b]&&delete a.__ta[b][c.__tauid],c.__taExtra){for(var d=0;d<c.__taExtra.length;d++)D(a,c.__taExtra[d][0],c.__taExtra[d][1]);c.__taExtra.length=0}c.__taUnstore&&c.__taUnstore()},i=function(a,c,e,f){if(null==a)return e;var g=a.split(","),h=function(a){h.__tauid=e.__tauid;for(var f=d(a),i=0;i<g.length;i++)b(f,g[i],c)&&e.apply(f,arguments)};return j(e,f,h),h},j=function(a,b,c){a.__taExtra=a.__taExtra||[],a.__taExtra.push([b,c])},k=function(a,b,c,d){q&&s[b]?C(a,s[b],i(d,a,c,s[b]),c):C(a,b,i(d,a,c,b),c)},l=function(a,b,c,
 f){if(null==a.__taSmartClicks){var g=function(b){a.__tad=w(b)},h=function(b){a.__tau=w(b)},i=function(b){if(a.__tad&&a.__tau&&a.__tad[0]===a.__tau[0]&&a.__tad[1]===a.__tau[1])for(var c=0;c<a.__taSmartClicks.length;c++)a.__taSmartClicks[c].apply(d(b),[b])};k(a,"mousedown",g,f),k(a,"mouseup",h,f),k(a,"click",i,f),a.__taSmartClicks=[]}a.__taSmartClicks.push(c),c.__taUnstore=function(){e(a.__taSmartClicks,c)}},m={tap:{touches:1,taps:1},dbltap:{touches:1,taps:2},contextmenu:{touches:2,taps:1}},n=function(a,c){return function(f,g,h,i){if("contextmenu"==g&&r)k(f,g,h,i);else{if(null==f.__taTapHandler){var j=f.__taTapHandler={tap:[],dbltap:[],contextmenu:[],down:!1,taps:0,downSelectors:[]},l=function(d){for(var e=d.srcElement||d.target,g=0;g<j.downSelectors.length;g++)if(null==j.downSelectors[g]||b(e,j.downSelectors[g],f)){j.down=!0,setTimeout(o,a),setTimeout(p,c);break}},n=function(a){if(j.down){var c=a.srcElement||a.target;j.taps++;var e=B(a);for(var g in m){var h=m[g];if(h.touches===e&&(1
 ===h.taps||h.taps===j.taps))for(var i=0;i<j[g].length;i++)(null==j[g][i][1]||b(c,j[g][i][1],f))&&j[g][i][0].apply(d(a),[a])}}},o=function(){j.down=!1},p=function(){j.taps=0};k(f,"mousedown",l),k(f,"mouseup",n)}f.__taTapHandler.downSelectors.push(i),f.__taTapHandler[g].push([h,i]),h.__taUnstore=function(){e(f.__taTapHandler[g],h)}}}},o=function(a,b,c,d){for(var e in c.__tamee[a])c.__tamee[a][e].apply(d,[b])},p=function(){var a=[];return function(c,e,f,h){if(!c.__tamee){c.__tamee={over:!1,mouseenter:[],mouseexit:[]};var j=function(e){var f=d(e);(null==h&&f==c&&!c.__tamee.over||b(f,h,c)&&(null==f.__tamee||!f.__tamee.over))&&(o("mouseenter",e,c,f),f.__tamee=f.__tamee||{},f.__tamee.over=!0,a.push(f))},k=function(e){for(var f=d(e),g=0;g<a.length;g++)f!=a[g]||b(e.relatedTarget||e.toElement,"*",f)||(f.__tamee.over=!1,a.splice(g,1),o("mouseexit",e,c,f))};C(c,"mouseover",i(h,c,j,"mouseover"),j),C(c,"mouseout",i(h,c,k,"mouseout"),k)}f.__taUnstore=function(){delete c.__tamee[e][f.__tauid]},g(c,
 e,f),c.__tamee[e][f.__tauid]=f}},q="ontouchstart"in document.documentElement,r="onmousedown"in document.documentElement,s={mousedown:"touchstart",mouseup:"touchend",mousemove:"touchmove"},t=function(){var a=-1;if("Microsoft Internet Explorer"==navigator.appName){var b=navigator.userAgent,c=new RegExp("MSIE ([0-9]{1,}[.0-9]{0,})");null!=c.exec(b)&&(a=parseFloat(RegExp.$1))}return a}(),u=t>-1&&9>t,v=function(a,b){if(null==a)return[0,0];var c=A(a),d=z(c,0);return[d[b+"X"],d[b+"Y"]]},w=function(a){return null==a?[0,0]:u?[a.clientX+document.documentElement.scrollLeft,a.clientY+document.documentElement.scrollTop]:v(a,"page")},x=function(a){return v(a,"screen")},y=function(a){return v(a,"client")},z=function(a,b){return a.item?a.item(b):a[b]},A=function(a){return a.touches&&a.touches.length>0?a.touches:a.changedTouches&&a.changedTouches.length>0?a.changedTouches:a.targetTouches&&a.targetTouches.length>0?a.targetTouches:[a]},B=function(a){return A(a).length},C=function(a,b,c,d){if(g(a,b,c),
 d.__tauid=c.__tauid,a.addEventListener)a.addEventListener(b,c,!1);else if(a.attachEvent){var e=b+c.__tauid;a["e"+e]=c,a[e]=function(){a["e"+e]&&a["e"+e](window.event)},a.attachEvent("on"+b,a[e])}},D=function(a,b,d){null!=d&&E(a,function(){var a=c(this);if(h(a,b,d),null!=d.__tauid)if(a.removeEventListener)a.removeEventListener(b,d,!1);else if(this.detachEvent){var e=b+d.__tauid;a[e]&&a.detachEvent("on"+b,a[e]),a[e]=null,a["e"+e]=null}})},E=function(a,b){if(null!=a){a="string"!=typeof a&&null==a.tagName&&null!=a.length?a:"string"==typeof a?document.querySelectorAll(a):[a];for(var c=0;c<a.length;c++)b.apply(a[c])}};this.Mottle=function(b){b=b||{};var d=b.clickThreshold||150,e=b.dblClickThreshold||350,f=new p,g=new n(d,e),h=b.smartClicks,i=function(a,b,d,e){null!=d&&E(a,function(){var a=c(this);h&&"click"===b?l(a,b,d,e):"tap"===b||"dbltap"===b||"contextmenu"===b?g(a,b,d,e):"mouseenter"===b||"mouseexit"==b?f(a,b,d,e):k(a,b,d,e)})};this.remove=function(a){return E(a,function(){var a=c(thi
 s);if(a.__ta)for(var b in a.__ta)for(var d in a.__ta[b])D(a,b,a.__ta[b][d]);a.parentNode&&a.parentNode.removeChild(a)}),this},this.on=function(){var a=arguments[0],b=4==arguments.length?arguments[2]:null,c=arguments[1],d=arguments[arguments.length-1];return i(a,c,d,b),this},this.off=function(a,b,c){return D(a,b,c),this},this.trigger=function(b,d,e,f){var g=q&&s[d]?s[d]:d,h=w(e),i=x(e),j=y(e);return E(b,function(){var b,k=c(this);e=e||{screenX:i[0],screenY:i[1],clientX:j[0],clientY:j[1]};var l=function(a){f&&(a.payload=f)},m={TouchEvent:function(a){var b=document.createTouch(window,k,0,h[0],h[1],i[0],i[1],j[0],j[1],0,0,0,0);a.initTouchEvent(g,!0,!0,window,0,i[0],i[1],j[0],j[1],!1,!1,!1,!1,document.createTouchList(b))},MouseEvents:function(b){if(b.initMouseEvent(g,!0,!0,window,0,i[0],i[1],j[0],j[1],!1,!1,!1,!1,1,k),a.android){var c=document.createTouch(window,k,0,h[0],h[1],i[0],i[1],j[0],j[1],0,0,0,0);b.touches=b.targetTouches=b.changedTouches=document.createTouchList(c)}}};if(documen
 t.createEvent){var n=q&&s[d]&&!a.android,o=n?"TouchEvent":"MouseEvents";b=document.createEvent(o),m[o](b),l(b),k.dispatchEvent(b)}else document.createEventObject&&(b=document.createEventObject(),b.eventType=b.eventName=g,b.screenX=i[0],b.screenY=i[1],b.clientX=j[0],b.clientY=j[1],l(b),k.fireEvent("on"+g,b))}),this}},Mottle.consume=function(a,b){a.stopPropagation?a.stopPropagation():a.returnValue=!1,!b&&a.preventDefault&&a.preventDefault()},Mottle.pageLocation=w}.call(this),function(){"use strict";var a=function(a){var b=a.getBoundingClientRect(),c=document.body,d=document.documentElement,e=window.pageYOffset||d.scrollTop||c.scrollTop,f=window.pageXOffset||d.scrollLeft||c.scrollLeft,g=d.clientTop||c.clientTop||0,h=d.clientLeft||c.clientLeft||0,i=b.top+e-g,j=b.left+f-h;return{top:Math.round(i),left:Math.round(j)}},b=function(a,b,c){c=c||a.parentNode;for(var d=c.querySelectorAll(b),e=0;e<d.length;e++)if(d[e]===a)return!0;return!1},c=function(){var a=-1;if("Microsoft Internet Explorer"=
 =navigator.appName){var b=navigator.userAgent,c=new RegExp("MSIE ([0-9]{1,}[.0-9]{0,})");null!=c.exec(b)&&(a=parseFloat(RegExp.$1))}return a}(),d=c>-1&&9>c,e=function(a){if(d)return[a.clientX+document.documentElement.scrollLeft,a.clientY+document.documentElement.scrollTop];var b=g(a),c=f(b,0);return[c.pageX,c.pageY]},f=function(a,b){return a.item?a.item(b):a[b]},g=function(a){return a.touches&&a.touches.length>0?a.touches:a.changedTouches&&a.changedTouches.length>0?a.changedTouches:a.targetTouches&&a.targetTouches.length>0?a.targetTouches:[a]},h={draggable:"katavorio-draggable",droppable:"katavorio-droppable",drag:"katavorio-drag",selected:"katavorio-drag-selected",active:"katavorio-drag-active",hover:"katavorio-drag-hover",noSelect:"katavorio-drag-no-select"},i="katavorio-drag-scope",j=["stop","start","drag","drop","over","out"],k=function(){},l=function(){return!0},m=function(a,b,c){for(var d=0;d<a.length;d++)a[d]!=c&&b(a[d])},n=function(a,b,c,d){m(a,function(a){a.setActive(b),b&&
 a.updatePosition(),c&&a.setHover(d,b)})},o=function(a,b){if(null!=a){a="string"!=typeof a&&null==a.tagName&&null!=a.length?a:[a];for(var c=0;c<a.length;c++)b.apply(a[c],[a[c]])}},p=function(a){a.stopPropagation?(a.stopPropagation(),a.preventDefault()):a.returnValue=!1},q="input,textarea,select,button",r=function(a,c,d){var e=a.srcElement||a.target;return!b(e,d.getInputFilterSelector(),c)},s=function(a,b,c,d){this.params=b||{},this.el=a,this.params.addClass(this.el,this._class);var e=!0;return this.setEnabled=function(a){e=a},this.isEnabled=function(){return e},this.toggleEnabled=function(){e=!e},this.setScope=function(a){this.scopes=a?a.split(/\s+/):[d]},this.addScope=function(a){var b={};o(this.scopes,function(a){b[a]=!0}),o(a?a.split(/\s+/):[],function(a){b[a]=!0}),this.scopes=[];for(var c in b)this.scopes.push(c)},this.removeScope=function(a){var b={};o(this.scopes,function(a){b[a]=!0}),o(a?a.split(/\s+/):[],function(a){delete b[a]}),this.scopes=[];for(var c in b)this.scopes.push
 (c)},this.toggleScope=function(a){var b={};o(this.scopes,function(a){b[a]=!0}),o(a?a.split(/\s+/):[],function(a){b[a]?delete b[a]:b[a]=!0}),this.scopes=[];for(var c in b)this.scopes.push(c)},this.setScope(b.scope),this.k=b.katavorio,b.katavorio},t=function(c,d,f){this._class=f.draggable;var g=s.apply(this,arguments);this.rightButtonCanDrag=this.params.rightButtonCanDrag;var h=[0,0],i=null,j=!1,k=this.params.consumeStartEvent!==!1,m=this.el,o=this.params.clone;this.toGrid=function(a){return null==this.params.grid?a:[this.params.grid[0]*Math.floor(a[0]/this.params.grid[0]),this.params.grid[1]*Math.floor(a[1]/this.params.grid[1])]},this.constrain="function"==typeof this.params.constrain?this.params.constrain:this.params.constrain||this.params.containment?function(a){return[Math.max(0,Math.min(w.w-this.size[0],a[0])),Math.max(0,Math.min(w.h-this.size[1],a[1]))]}:function(a){return a};var q=l,t="",u=this.params.filterExclude!==!1,v=this.setFilter=function(a,d){a&&(t=a,u=d!==!1,q=function
 (d){var e=d.srcElement||d.target,f=b(e,a,c);return u?!f:f})};this.canDrag=this.params.canDrag||l;var w,x=[],y=[];this.downListener=function(b){var c=this.rightButtonCanDrag||3!==b.which&&2!==b.button;if(c&&this.isEnabled()&&this.canDrag()){var d=q(b)&&r(b,this.el,this.k);if(d){if(o){m=this.el.cloneNode(!0),m.setAttribute("id",null),m.style.position="absolute";var i=a(this.el);m.style.left=i.left+"px",m.style.top=i.top+"px",document.body.appendChild(m)}else m=this.el;k&&p(b),h=e(b),this.params.bind(document,"mousemove",this.moveListener),this.params.bind(document,"mouseup",this.upListener),g.markSelection(this),this.params.addClass(document.body,f.noSelect)}else this.params.consumeFilteredEvents&&p(b)}}.bind(this),this.moveListener=function(a){if(h){j||(this.params.events.start({el:this.el,pos:i,e:a,drag:this}),this.mark(),j=!0),y.length=0;var b=e(a),c=b[0]-h[0],d=b[1]-h[1],f=this.params.ignoreZoom?1:g.getZoom();c/=f,d/=f,this.moveBy(c,d,a),g.updateSelection(c,d,this)}}.bind(this),th
 is.upListener=function(a){h=null,j=!1,this.params.unbind(document,"mousemove",this.moveListener),this.params.unbind(document,"mouseup",this.upListener),this.params.removeClass(document.body,f.noSelect),this.unmark(a),g.unmarkSelection(this,a),this.stop(a),g.notifySelectionDragStop(this,a),o&&(m&&m.parentNode&&m.parentNode.removeChild(m),m=null)}.bind(this),this.getFilter=function(){return t},this.isFilterExclude=function(){return u},this.abort=function(){null!=h&&this.upListener()},this.getDragElement=function(){return m||this.el},this.stop=function(a){this.params.events.stop({el:m,pos:this.params.getPosition(m),e:a,drag:this})},this.mark=function(){if(i=this.params.getPosition(m),this.size=this.params.getSize(m),x=g.getMatchingDroppables(this),n(x,!0,!1,this),this.params.addClass(m,this.params.dragClass||f.drag),this.params.constrain||this.params.containment){var a=this.params.getSize(m.parentNode);w={w:a[0],h:a[1]}}},this.unmark=function(a){n(x,!1,!0,this),x.length=0;for(var b=0;b
 <y.length;b++)y[b].drop(this,a)},this.moveBy=function(a,b,c){y.length=0;var d=this.constrain(this.toGrid([i[0]+a,i[1]+b]),m),e={x:d[0],y:d[1],w:this.size[0],h:this.size[1]};this.params.setPosition(m,d);for(var f=0;f<x.length;f++){var g={x:x[f].position[0],y:x[f].position[1],w:x[f].size[0],h:x[f].size[1]};this.params.intersects(e,g)&&x[f].canDrop(this)?(y.push(x[f]),x[f].setHover(this,!0,c)):x[f].el._katavorioDragHover&&x[f].setHover(this,!1,c)}this.params.events.drag({el:this.el,pos:d,e:c,drag:this})},this.destroy=function(){this.params.unbind(this.el,"mousedown",this.downListener),this.params.unbind(document,"mousemove",this.moveListener),this.params.unbind(document,"mouseup",this.upListener),this.downListener=null,this.upListener=null,this.moveListener=null},this.params.bind(this.el,"mousedown",this.downListener),this.params.handle?v(this.params.handle,!1):v(this.params.filter,this.params.filterExclude)},u=function(a,b,c){this._class=c.droppable,this.params=b||{},this._activeClass
 =b.activeClass||c.active,this._hoverClass=b.hoverClass||c.hover,s.apply(this,arguments);var d=!1;this.setActive=function(a){this.params[a?"addClass":"removeClass"](this.el,this._activeClass)},this.updatePosition=function(){this.position=this.params.getPosition(this.el),this.size=this.params.getSize(this.el)},this.canDrop=this.params.canDrop||function(){return!0},this.setHover=function(a,b,c){(b||null==this.el._katavorioDragHover||this.el._katavorioDragHover==a.el._katavorio)&&(this.params[b?"addClass":"removeClass"](this.el,this._hoverClass),this.el._katavorioDragHover=b?a.el._katavorio:null,d!==b&&this.params.events[b?"over":"out"]({el:this.el,e:c,drag:a,drop:this}),d=b)},this.drop=function(a,b){this.params.events.drop({drag:a,e:b,drop:this})},this.destroy=function(){this._class=null,this._activeClass=null,this._hoverClass=null,d=null}},v=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=0|16*Math.random(),c="x"==a?b:8|3&b;return c.toString(1
 6)})},w=function(a){return null==a?null:(a="string"==typeof a?document.getElementById(a):a,null==a?null:(a._katavorio=a._katavorio||v(),a))};this.Katavorio=function(a){var b=[],c={};this._dragsByScope={},this._dropsByScope={};var d=1,e=function(a,b){for(var c=0;c<a.scopes.length;c++)b[a.scopes[c]]=b[a.scopes[c]]||[],b[a.scopes[c]].push(a)},f=function(b,c){for(var d=0,e=0;e<b.scopes.length;e++)if(c[b.scopes[e]]){var f=a.indexOf(c[b.scopes[e]],b);-1!=f&&(c[b.scopes[e]].splice(f,1),d++)}return d>0},g=(this.getMatchingDroppables=function(a){for(var b=[],c={},d=0;d<a.scopes.length;d++){var e=this._dropsByScope[a.scopes[d]];if(e)for(var f=0;f<e.length;f++)e[f].canDrop(a)&&!c[e[f].el._katavorio]&&e[f].el!==a.el&&(c[e[f].el._katavorio]=!0,b.push(e[f]))}return b},function(b){b=b||{};var c={events:{}};for(var d in a)c[d]=a[d];for(var d in b)c[d]=b[d];for(var d=0;d<j.length;d++)c.events[j[d]]=b[j[d]]||k;return c.katavorio=this,c}.bind(this)),l={},n=a.css||{},p=a.scope||i;for(var r in h)l[r]=h[
 r];for(var r in n)l[r]=n[r];var s=a.inputFilterSelector||q;this.getInputFilterSelector=function(){return s},this.setInputFilterSelector=function(a){return s=a,this},this.draggable=function(b,c){var d=[];return o(b,function(b){if(b=w(b),null!=b){var f=g(c);b._katavorioDrag=new t(b,f,l,p),e(b._katavorioDrag,this._dragsByScope),d.push(b._katavorioDrag),a.addClass(b,l.draggable)}}.bind(this)),d},this.droppable=function(b,c){var d=[];return o(b,function(b){b=w(b),null!=b&&(b._katavorioDrop=new u(b,g(c),l,p),e(b._katavorioDrop,this._dropsByScope),d.push(b._katavorioDrop),a.addClass(b,l.droppable))}.bind(this)),d},this.select=function(d){return o(d,function(){var d=w(this);d&&d._katavorioDrag&&(c[d._katavorio]||(b.push(d._katavorioDrag),c[d._katavorio]=[d,b.length-1],a.addClass(d,l.selected)))}),this},this.deselect=function(d){return o(d,function(){var d=w(this);if(d&&d._katavorio){var e=c[d._katavorio];if(e){for(var f=[],g=0;g<b.length;g++)b[g].el!==d&&f.push(b[g]);b=f,delete c[d._katavor
 io],a.removeClass(d,l.selected)}}}),this},this.deselectAll=function(){for(var d in c){var e=c[d];a.removeClass(e[0],l.selected)}b.length=0,c={}},this.markSelection=function(a){m(b,function(a){a.mark()},a)},this.unmarkSelection=function(a,c){m(b,function(a){a.unmark(c)},a)},this.getSelection=function(){return b.slice(0)},this.updateSelection=function(a,c,d){m(b,function(b){b.moveBy(a,c)},d)},this.notifySelectionDragStop=function(a,c){m(b,function(a){a.stop(c)},a)},this.setZoom=function(a){d=a},this.getZoom=function(){return d};var v=function(a,b,c,d){null!=a&&(f(a,c),a[d](b),e(a,c))};o(["set","add","remove","toggle"],function(a){this[a+"Scope"]=function(b,c){v(b._katavorioDrag,c,this._dragsByScope,a+"Scope"),v(b._katavorioDrop,c,this._dropsByScope,a+"Scope")}.bind(this),this[a+"DragScope"]=function(b,c){v(b._katavorioDrag,c,this._dragsByScope,a+"Scope")}.bind(this),this[a+"DropScope"]=function(b,c){v(b._katavorioDrop,c,this._dropsByScope,a+"Scope")}.bind(this)}.bind(this)),this.getDr
 agsForScope=function(a){return this._dragsByScope[a]},this.getDropsForScope=function(a){return this._dropsByScope[a]};var x=function(a,b,c){a=w(a),a[b]&&(f(a[b],c)&&a[b].destroy(),a[b]=null)};this.elementRemoved=function(a){this.destroyDraggable(a),this.destroyDroppable(a)},this.destroyDraggable=function(a){x(a,"_katavorioDrag",this._dragsByScope)},this.destroyDroppable=function(a){x(a,"_katavorioDrop",this._dropsByScope)}}}.call(this),function(){var a=function(a){return"[object Array]"===Object.prototype.toString.call(a)},b=function(a){return"[object Number]"===Object.prototype.toString.call(a)},c=function(a){return"string"==typeof a},d=function(a){return"boolean"==typeof a},e=function(a){return null==a},f=function(a){return null==a?!1:"[object Object]"===Object.prototype.toString.call(a)},g=function(a){return"[object Date]"===Object.prototype.toString.call(a)},h=function(a){return"[object Function]"===Object.prototype.toString.call(a)},i=function(a){for(var b in a)if(a.hasOwnPrope
 rty(b))return!1;return!0},j=this,k=j.jsPlumbUtil={isArray:a,isString:c,isBoolean:d,isNull:e,isObject:f,isDate:g,isFunction:h,isEmpty:i,isNumber:b,clone:function(b){if(c(b))return""+b;if(d(b))return!!b;if(g(b))return new Date(b.getTime());if(h(b))return b;if(a(b)){for(var e=[],i=0;i<b.length;i++)e.push(this.clone(b[i]));return e}if(f(b)){var j={};for(var k in b)j[k]=this.clone(b[k]);return j}return b},merge:function(b,e,g){var h,i,j={};for(g=g||[],i=0;i<g.length;i++)j[g[i]]=!0;var k=this.clone(b);for(i in e)if(null==k[i])k[i]=e[i];else if(c(e[i])||d(e[i]))j[i]?(h=[],h.push.apply(h,a(k[i])?k[i]:[k[i]]),h.push.apply(h,a(e[i])?e[i]:[e[i]]),k[i]=h):k[i]=e[i];else if(a(e[i]))h=[],a(k[i])&&h.push.apply(h,k[i]),h.push.apply(h,e[i]),k[i]=h;else if(f(e[i])){f(k[i])||(k[i]={});for(var l in e[i])k[i][l]=e[i][l]}return k},replace:function(a,b,c){if(null!=a){var d=a,e=d;return b.replace(/([^\.])+/g,function(a,b,d,f){var g=a.match(/([^\[0-9]+){1}(\[)([0-9+])/),h=d+a.length>=f.length,i=function(){r
 eturn e[g[1]]||function(){return e[g[1]]=[],e[g[1]]}()};if(h)g?i()[g[3]]=c:e[a]=c;else if(g){var j=i();e=j[g[3]]||function(){return j[g[3]]={},j[g[3]]}()}else e=e[a]||function(){return e[a]={},e[a]}()}),a}},functionChain:function(a,b,c){for(var d=0;d<c.length;d++){var e=c[d][0][c[d][1]].apply(c[d][0],c[d][2]);if(e===b)return e}return a},populate:function(b,d){var e=function(a){var b=a.match(/(\${.*?})/g);if(null!=b)for(var c=0;c<b.length;c++){var e=d[b[c].substring(2,b[c].length-1)]||"";null!=e&&(a=a.replace(b[c],e))}return a},g=function(b){if(null!=b){if(c(b))return e(b);if(a(b)){for(var d=[],h=0;h<b.length;h++)d.push(g(b[h]));return d}if(f(b)){var i={};for(var j in b)i[j]=g(b[j]);return i}return b}};return g(b)},convertStyle:function(a,b){if("transparent"===a)return a;var c=a,d=function(a){return 1==a.length?"0"+a:a},e=function(a){return d(Number(a).toString(16))},f=/(rgb[a]?\()(.*)(\))/;if(a.match(f)){var g=a.match(f)[2].split(",");c="#"+e(g[0])+e(g[1])+e(g[2]),b||4!=g.length||(c
 +=e(g[3]))}return c},findWithFunction:function(a,b){if(a)for(var c=0;c<a.length;c++)if(b(a[c]))return c;return-1},indexOf:function(a,b){return a.indexOf?a.indexOf(b):k.findWithFunction(a,function(a){return a==b})},removeWithFunction:function(a,b){var c=k.findWithFunction(a,b);return c>-1&&a.splice(c,1),-1!=c},remove:function(a,b){var c=k.indexOf(a,b);return c>-1&&a.splice(c,1),-1!=c},addWithFunction:function(a,b,c){-1==k.findWithFunction(a,c)&&a.push(b)},addToList:function(a,b,c,d){var e=a[b];return null==e&&(e=[],a[b]=e),e[d?"unshift":"push"](c),e},extend:function(b,c){var d;for(c=a(c)?c:[c],d=0;d<c.length;d++)for(var e in c[d].prototype)c[d].prototype.hasOwnProperty(e)&&(b.prototype[e]=c[d].prototype[e]);var f=function(a,b){return function(){for(d=0;d<c.length;d++)c[d].prototype[a]&&c[d].prototype[a].apply(this,arguments);return b.apply(this,arguments)}},g=function(a){for(var c in a)b.prototype[c]=f(c,a[c])};if(arguments.length>2)for(d=2;d<arguments.length;d++)g(arguments[d]);retu
 rn b},uuid:function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=0|16*Math.random(),c="x"==a?b:8|3&b;return c.toString(16)})},logEnabled:!0,log:function(){if(k.logEnabled&&"undefined"!=typeof console)try{var a=arguments[arguments.length-1];console.log(a)}catch(b){}},wrap:function(a,b,c){return a=a||function(){},b=b||function(){},function(){var d=null;try{d=b.apply(this,arguments)}catch(e){k.log("jsPlumb function failed : "+e)}if(null==c||d!==c)try{d=a.apply(this,arguments)}catch(e){k.log("wrapped function failed : "+e)}return d}}};k.EventGenerator=function(){var a={},b=!1,c={ready:!0};this.bind=function(b,c,d){return k.addToList(a,b,c,d),this},this.fire=function(d,e,f){if(!b&&a[d]){var g=a[d].length,h=0,i=!1,j=null;if(!this.shouldFireEvent||this.shouldFireEvent(d,e,f))for(;!i&&g>h&&j!==!1;){if(c[d])a[d][h].apply(this,[e,f]);else try{j=a[d][h].apply(this,[e,f])}catch(l){k.log("jsPlumb: fire failed for event "+d+" : "+l)}h++,(null==a||null==a[d])&&(
 i=!0)}}return this},this.unbind=function(b){return b?delete a[b]:a={},this},this.getListener=function(b){return a[b]},this.setSuspendEvents=function(a){b=a},this.isSuspendEvents=function(){return b},this.cleanupListeners=function(){for(var b in a)a[b]=null}},k.EventGenerator.prototype={cleanup:function(){this.cleanupListeners()}},Function.prototype.bind||(Function.prototype.bind=function(a){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var b=Array.prototype.slice.call(arguments,1),c=this,d=function(){},e=function(){return c.apply(this instanceof d&&a?this:a,b.concat(Array.prototype.slice.call(arguments)))};return d.prototype=this.prototype,e.prototype=new d,e})}.call(this),function(){"use strict";var a=this,b=a.jsPlumbUtil;b.ieVersion=/MSIE\s([\d.]+)/.test(navigator.userAgent)?new Number(RegExp.$1):-1,b.oldIE=b.ieVersion>-1&&b.ieVersion<9,b.matchesSelector=function(a,b,c){c=c||a.parentNode;for(var d=c.querySele
 ctorAll(b),e=0;e<d.length;e++)if(d[e]===a)return!0;return!1},b.consume=function(a,b){a.stopPropagation?a.stopPropagation():a.returnValue=!1,!b&&a.preventDefault&&a.preventDefault()},b.sizeElement=function(a,b,c,d,e){a&&(a.style.height=e+"px",a.height=e,a.style.width=d+"px",a.width=d,a.style.left=b+"px",a.style.top=c+"px")}}.call(this),function(){var a=this,b=!!window.SVGAngle||document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1"),c=function(){if(void 0===c.vml){var a=document.body.appendChild(document.createElement("div"));a.innerHTML='<v:shape id="vml_flag1" adj="1" />';var b=a.firstChild;null!=b&&null!=b.style?(b.style.behavior="url(#default#VML)",c.vml=b?"object"==typeof b.adj:!0):c.vml=!1,a.parentNode.removeChild(a)}return c.vml},d=function(){var a=-1;if("Microsoft Internet Explorer"==navigator.appName){var b=navigator.userAgent,c=new RegExp("MSIE ([0-9]{1,}[.0-9]{0,})");null!=c.exec(b)&&(a=parseFloat(RegExp.$1))}return a}(),e=d>-1&&9>d,f=
 function(a,b){if(null==a)return[0,0];var c=k(a),d=j(c,0);return[d[b+"X"],d[b+"Y"]]},g=function(a){return null==a?[0,0]:e?[a.clientX+document.documentElement.scrollLeft,a.clientY+document.documentElement.scrollTop]:f(a,"page")},h=function(a){return f(a,"screen")},i=function(a){return f(a,"client")},j=function(a,b){return a.item?a.item(b):a[b]},k=function(a){return a.touches&&a.touches.length>0?a.touches:a.changedTouches&&a.changedTouches.length>0?a.changedTouches:a.targetTouches&&a.targetTouches.length>0?a.targetTouches:[a]},l=function(a){var b={},c=[],d={},e={},f={};this.register=function(g){var h=a.getId(g),i=jsPlumbAdapter.getOffset(g,a);b[h]||(b[h]=g,c.push(g),d[h]={});var j=function(b){if(b)for(var c=0;c<b.childNodes.length;c++)if(3!=b.childNodes[c].nodeType&&8!=b.childNodes[c].nodeType){var g=jsPlumb.getElementObject(b.childNodes[c]),k=a.getId(b.childNodes[c],null,!0);if(k&&e[k]&&e[k]>0){var l=jsPlumbAdapter.getOffset(g,a);d[h][k]={id:k,offset:{left:l.left-i.left,top:l.top-i.to
 p}},f[k]=h}j(b.childNodes[c])}};j(g)},this.updateOffsets=function(b){if(null!=b){var c=jsPlumb.getDOMElement(b),e=a.getId(c),g=d[e],h=jsPlumbAdapter.getOffset(c,a);if(g)for(var i in g){var j=jsPlumb.getElementObject(i),k=jsPlumbAdapter.getOffset(j,a);d[e][i]={id:i,offset:{left:k.left-h.left,top:k.top-h.top}},f[i]=e}}},this.endpointAdded=function(c,g){g=g||a.getId(c);var h=document.body,i=c.parentNode;for(e[g]=e[g]?e[g]+1:1;null!=i&&i!=h;){var j=a.getId(i,null,!0);if(j&&b[j]){var k=jsPlumbAdapter.getOffset(i,a);if(null==d[j][g]){var l=jsPlumbAdapter.getOffset(c,a);d[j][g]={id:g,offset:{left:l.left-k.left,top:l.top-k.top}},f[g]=j}break}i=i.parentNode}},this.endpointDeleted=function(a){if(e[a.elementId]&&(e[a.elementId]--,e[a.elementId]<=0))for(var b in d)d[b]&&(delete d[b][a.elementId],delete f[a.elementId])},this.changeId=function(a,b){d[b]=d[a],d[a]={},f[b]=f[a],f[a]=null},this.getElementsForDraggable=function(a){return d[a]},this.elementRemoved=function(a){var b=f[a];b&&(delete d[b
 ][a],delete f[a])},this.reset=function(){b={},c=[],d={},e={}},this.dragEnded=function(b){var c=a.getId(b),d=f[c];
+d&&this.updateOffsets(d)},this.setParent=function(b,c,e,g){var h=f[c];if(h){d[g]||(d[g]={}),d[g][c]=d[h][c],delete d[h][c];var i=jsPlumbAdapter.getOffset(e,a),j=jsPlumbAdapter.getOffset(b,a);d[g][c].offset={left:j.left-i.left,top:j.top-i.top},f[c]=g}},this.getDragAncestor=function(b){var c=jsPlumb.getDOMElement(b),d=a.getId(c),e=f[d];return e?jsPlumb.getDOMElement(e):null}};window.console||(window.console={time:function(){},timeEnd:function(){},group:function(){},groupEnd:function(){},log:function(){}});var m=function(a){return null==a?null:a.replace(/^\s\s*/,"").replace(/\s\s*$/,"")},n=function(a,b){b=m(b),"undefined"!=typeof a.className.baseVal?a.className.baseVal=b:a.className=b},o=function(a){return"undefined"==typeof a.className.baseVal?a.className:a.className.baseVal},p=function(a,b,c){b=null==b?[]:jsPlumbUtil.isArray(b)?b:b.split(/\s+/),c=null==c?[]:jsPlumbUtil.isArray(c)?c:c.split(/\s+/);var d=o(a),e=d.split(/\s+/),f=function(a,b){for(var c=0;c<b.length;c++)if(a)-1==jsPlumbU
 til.indexOf(e,b[c])&&e.push(b[c]);else{var d=jsPlumbUtil.indexOf(e,b[c]);-1!=d&&e.splice(d,1)}};f(!0,b),f(!1,c),n(a,e.join(" "))},q=function(a,b){if(null!=a)if("string"==typeof a)b(jsPlumb.getDOMElement(a));else if(null!=a.length)for(var c=0;c<a.length;c++)b(jsPlumb.getDOMElement(a[c]));else b(a)};window.jsPlumbAdapter={headless:!1,pageLocation:g,screenLocation:h,clientLocation:i,getAttribute:function(a,b){return a.getAttribute(b)},setAttribute:function(a,b,c){a.setAttribute(b,c)},appendToRoot:function(a){document.body.appendChild(a)},getRenderModes:function(){return["svg","vml"]},isRenderModeAvailable:function(a){return{svg:b,vml:c()}[a]},getDragManager:function(a){return new l(a)},setRenderMode:function(a){var b;if(a){a=a.toLowerCase();var c=this.isRenderModeAvailable("svg"),d=this.isRenderModeAvailable("vml");"svg"===a?c?b="svg":d&&(b="vml"):d&&(b="vml")}return b},addClass:function(a,b){q(a,function(a){p(a,b)})},hasClass:function(a,b){return a=jsPlumb.getDOMElement(a),a.classList
 ?a.classList.contains(b):-1!=o(a).indexOf(b)},removeClass:function(a,b){q(a,function(a){p(a,null,b)})},updateClasses:function(a,b,c){q(a,function(a){p(a,b,c)})},setClass:function(a,b){q(a,function(a){n(a,b)})},setPosition:function(a,b){a.style.left=b.left+"px",a.style.top=b.top+"px"},getPosition:function(a){var b=function(b){var c=a.style[b];return c?c.substring(0,c.length-2):0};return{left:b("left"),top:b("top")}},getOffset:function(a,b,c){a=jsPlumb.getDOMElement(a);for(var d=b.getContainer(),e=a.offsetLeft,f=a.offsetTop,g=c||null!=d&&a.offsetParent!=d?a.offsetParent:null;null!=g;)e+=g.offsetLeft,f+=g.offsetTop,g=c?g.offsetParent:g.offsetParent==d?null:g.offsetParent;return{left:e,top:f}},getPositionOnElement:function(a,b,c){var d="undefined"!=typeof b.getBoundingClientRect?b.getBoundingClientRect():{left:0,top:0,width:0,height:0},e=document.body,f=document.documentElement,g=(b.offsetParent,window.pageYOffset||f.scrollTop||e.scrollTop),h=window.pageXOffset||f.scrollLeft||e.scrollLe
 ft,i=f.clientTop||e.clientTop||0,j=f.clientLeft||e.clientLeft||0,k=0,l=0,m=d.top+g-i+k*c,n=d.left+h-j+l*c,o=jsPlumbAdapter.pageLocation(a),p=d.width||b.offsetWidth*c,q=d.height||b.offsetHeight*c,r=(o[0]-n)/p,s=(o[1]-m)/q;return[r,s]},getAbsolutePosition:function(a){var b=function(b){var c=a.style[b];return c?parseFloat(c.substring(0,c.length-2)):void 0};return[b("left"),b("top")]},setAbsolutePosition:function(b,c,d,e){d?a.jsPlumb.animate(b,{left:"+="+(c[0]-d[0]),top:"+="+(c[1]-d[1])},e):(b.style.left=c[0]+"px",b.style.top=c[1]+"px")}}}.call(this),function(){"use strict";var a=jsPlumbUtil,b=function(a,b,c){return jsPlumbAdapter.getOffset(a,b,c)},c=function(){return""+(new Date).getTime()},d=function(a){if(a._jsPlumb.paintStyle&&a._jsPlumb.hoverPaintStyle){var b={};t.extend(b,a._jsPlumb.paintStyle),t.extend(b,a._jsPlumb.hoverPaintStyle),delete a._jsPlumb.hoverPaintStyle,b.gradient&&a._jsPlumb.paintStyle.fillStyle&&delete b.gradient,a._jsPlumb.hoverPaintStyle=b}},e=["click","dblclick",
 "mouseover","mouseout","mousemove","mousedown","mouseup","contextmenu"],f=function(a,b,c,d){var e=a.getAttachedElements();if(e)for(var f=0,g=e.length;g>f;f++)d&&d==e[f]||e[f].setHover(b,!0,c)},g=function(a){return null==a?null:a.split(" ")},h=function(b,c,d){if(b.getDefaultType){for(var e=b.getTypeDescriptor(),f=a.merge({},b.getDefaultType()),g=0,h=b._jsPlumb.types.length;h>g;g++)f=a.merge(f,b._jsPlumb.instance.getType(b._jsPlumb.types[g],e),["cssClass"]);c&&(f=a.populate(f,c)),b.applyType(f,d),d||b.repaint()}},i=window.jsPlumbUIComponent=function(b){jsPlumbUtil.EventGenerator.apply(this,arguments);var c=this,d=arguments,e=c.idPrefix,f=e+(new Date).getTime();if(this._jsPlumb={instance:b._jsPlumb,parameters:b.parameters||{},paintStyle:null,hoverPaintStyle:null,paintStyleInUse:null,hover:!1,beforeDetach:b.beforeDetach,beforeDrop:b.beforeDrop,overlayPlacements:[],hoverClass:b.hoverClass||b._jsPlumb.Defaults.HoverClass,types:[]},this.getId=function(){return f},b.events)for(var g in b.ev
 ents)c.bind(g,b.events[g]);this.clone=function(){var a={};return this.constructor.apply(a,d),a}.bind(this),this.isDetachAllowed=function(b){var c=!0;if(this._jsPlumb.beforeDetach)try{c=this._jsPlumb.beforeDetach(b)}catch(d){a.log("jsPlumb: beforeDetach callback failed",d)}return c},this.isDropAllowed=function(b,c,d,e,f,g,h){var i=this._jsPlumb.instance.checkCondition("beforeDrop",{sourceId:b,targetId:c,scope:d,connection:e,dropEndpoint:f,source:g,target:h});if(this._jsPlumb.beforeDrop)try{i=this._jsPlumb.beforeDrop({sourceId:b,targetId:c,scope:d,connection:e,dropEndpoint:f,source:g,target:h})}catch(j){a.log("jsPlumb: beforeDrop callback failed",j)}return i};var h=[];this.setListenerComponent=function(a){for(var b=0;b<h.length;b++)h[b][3]=a}},j=function(a,b){var c=a._jsPlumb.types[b],d=a._jsPlumb.instance.getType(c,a.getTypeDescriptor());null!=d&&d.cssClass&&a.canvas&&a._jsPlumb.instance.removeClass(a.canvas,d.cssClass)};jsPlumbUtil.extend(i,jsPlumbUtil.EventGenerator,{getParameter:f
 unction(a){return this._jsPlumb.parameters[a]},setParameter:function(a,b){this._jsPlumb.parameters[a]=b},getParameters:function(){return this._jsPlumb.parameters},setParameters:function(a){this._jsPlumb.parameters=a},addClass:function(a){jsPlumbAdapter.addClass(this.canvas,a)},removeClass:function(a){jsPlumbAdapter.removeClass(this.canvas,a)},updateClasses:function(a,b){jsPlumbAdapter.updateClasses(this.canvas,a,b)},setType:function(a,b,c){this.clearTypes(),this._jsPlumb.types=g(a)||[],h(this,b,c)},getType:function(){return this._jsPlumb.types},reapplyTypes:function(a,b){h(this,a,b)},hasType:function(a){return-1!=jsPlumbUtil.indexOf(this._jsPlumb.types,a)},addType:function(a,b,c){var d=g(a),e=!1;if(null!=d){for(var f=0,i=d.length;i>f;f++)this.hasType(d[f])||(this._jsPlumb.types.push(d[f]),e=!0);e&&h(this,b,c)}},removeType:function(b,c){var d=g(b),e=!1,f=function(b){var c=a.indexOf(this._jsPlumb.types,b);return-1!=c?(j(this,c),this._jsPlumb.types.splice(c,1),!0):!1}.bind(this);if(nul
 l!=d){for(var i=0,k=d.length;k>i;i++)e=f(d[i])||e;e&&h(this,null,c)}},clearTypes:function(a){for(var b=this._jsPlumb.types.length,c=0;b>c;c++)j(this,0),this._jsPlumb.types.splice(0,1);h(this,{},a)},toggleType:function(a,b,c){var d=g(a);if(null!=d){for(var e=0,f=d.length;f>e;e++){var i=jsPlumbUtil.indexOf(this._jsPlumb.types,d[e]);-1!=i?(j(this,i),this._jsPlumb.types.splice(i,1)):this._jsPlumb.types.push(d[e])}h(this,b,c)}},applyType:function(a,b){if(this.setPaintStyle(a.paintStyle,b),this.setHoverPaintStyle(a.hoverPaintStyle,b),a.parameters)for(var c in a.parameters)this.setParameter(c,a.parameters[c])},setPaintStyle:function(a,b){this._jsPlumb.paintStyle=a,this._jsPlumb.paintStyleInUse=this._jsPlumb.paintStyle,d(this),b||this.repaint()},getPaintStyle:function(){return this._jsPlumb.paintStyle},setHoverPaintStyle:function(a,b){this._jsPlumb.hoverPaintStyle=a,d(this),b||this.repaint()},getHoverPaintStyle:function(){return this._jsPlumb.hoverPaintStyle},destroy:function(){this.cleanup
 Listeners(),this.clone=null,this._jsPlumb=null},isHover:function(){return this._jsPlumb.hover},setHover:function(a,b,d){if(this._jsPlumb&&!this._jsPlumb.instance.currentlyDragging&&!this._jsPlumb.instance.isHoverSuspended()){if(this._jsPlumb.hover=a,null!=this.canvas){if(null!=this._jsPlumb.instance.hoverClass){var e=a?"addClass":"removeClass";this._jsPlumb.instance[e](this.canvas,this._jsPlumb.instance.hoverClass)}null!=this._jsPlumb.hoverClass&&this._jsPlumb.instance[e](this.canvas,this._jsPlumb.hoverClass)}null!=this._jsPlumb.hoverPaintStyle&&(this._jsPlumb.paintStyleInUse=a?this._jsPlumb.hoverPaintStyle:this._jsPlumb.paintStyle,this._jsPlumb.instance.isSuspendDrawing()||(d=d||c(),this.repaint({timestamp:d,recalc:!1}))),this.getAttachedElements&&!b&&f(this,a,c(),this)}}});var k="__label",l=function(a,b){for(var c=-1,d=0,e=a._jsPlumb.overlays.length;e>d;d++)if(b===a._jsPlumb.overlays[d].id){c=d;break}return c},m=function(a,b){var c={cssClass:b.cssClass,labelStyle:a.labelStyle,id:k
 ,component:a,_jsPlumb:a._jsPlumb.instance},d=t.extend(c,b);return new(t.Overlays[a._jsPlumb.instance.getRenderMode()].Label)(d)},n=function(b,c){var d=null;if(a.isArray(c)){var e=c[0],f=t.extend({component:b,_jsPlumb:b._jsPlumb.instance},c[1]);3==c.length&&t.extend(f,c[2]),d=new(t.Overlays[b._jsPlumb.instance.getRenderMode()][e])(f)}else d=c.constructor==String?new(t.Overlays[b._jsPlumb.instance.getRenderMode()][c])({component:b,_jsPlumb:b._jsPlumb.instance}):c;b._jsPlumb.overlays.push(d)},o=function(a,b){var c=a.defaultOverlayKeys||[],d=b.overlays,e=function(b){return a._jsPlumb.instance.Defaults[b]||t.Defaults[b]||[]};d||(d=[]);for(var f=0,g=c.length;g>f;f++)d.unshift.apply(d,e(c[f]));return d},p=window.OverlayCapableJsPlumbUIComponent=function(a){i.apply(this,arguments),this._jsPlumb.overlays=[];var b=o(this,a);if(b)for(var c=0,d=b.length;d>c;c++)n(this,b[c]);if(a.label){var e=a.labelLocation||this.defaultLabelLocation||.5,f=a.labelStyle||this._jsPlumb.instance.Defaults.LabelStyl
 e;this._jsPlumb.overlays.push(m(this,{label:a.label,location:e,labelStyle:f}))}this.setListenerComponent=function(a){if(this._jsPlumb)for(var b=0;b<this._jsPlumb.overlays.length;b++)this._jsPlumb.overlays[b].setListenerComponent(a)}};jsPlumbUtil.extend(p,i,{applyType:function(a,b){if(this.removeAllOverlays(b),a.overlays)for(var c=0,d=a.overlays.length;d>c;c++)this.addOverlay(a.overlays[c],!0)},setHover:function(a){if(this._jsPlumb&&!this._jsPlumb.instance.isConnectionBeingDragged())for(var b=0,c=this._jsPlumb.overlays.length;c>b;b++)this._jsPlumb.overlays[b][a?"addClass":"removeClass"](this._jsPlumb.instance.hoverClass)},addOverlay:function(a,b){n(this,a),b||this.repaint()},getOverlay:function(a){var b=l(this,a);return b>=0?this._jsPlumb.overlays[b]:null},getOverlays:function(){return this._jsPlumb.overlays},hideOverlay:function(a){var b=this.getOverlay(a);b&&b.hide()},hideOverlays:function(){for(var a=0,b=this._jsPlumb.overlays.length;b>a;a++)this._jsPlumb.overlays[a].hide()},showO
 verlay:function(a){var b=this.getOverlay(a);b&&b.show()},showOverlays:function(){for(var a=0,b=this._jsPlumb.overlays.length;b>a;a++)this._jsPlumb.overlays[a].show()},removeAllOverlays:function(a){for(var b=0,c=this._jsPlumb.overlays.length;c>b;b++)this._jsPlumb.overlays[b].cleanup&&this._jsPlumb.overlays[b].cleanup();this._jsPlumb.overlays.splice(0,this._jsPlumb.overlays.length),this._jsPlumb.overlayPositions=null,a||this.repaint()},removeOverlay:function(a){var b=l(this,a);if(-1!=b){var c=this._jsPlumb.overlays[b];c.cleanup&&c.cleanup(),this._jsPlumb.overlays.splice(b,1),this._jsPlumb.overlayPositions&&delete this._jsPlumb.overlayPositions[a]}},removeOverlays:function(){for(var a=0,b=arguments.length;b>a;a++)this.removeOverlay(arguments[a])},moveParent:function(a){this.bgCanvas&&(this.bgCanvas.parentNode.removeChild(this.bgCanvas),a.appendChild(this.bgCanvas)),this.canvas.parentNode.removeChild(this.canvas),a.appendChild(this.canvas);for(var b=0;b<this._jsPlumb.overlays.length;b++
 )this._jsPlumb.overlays[b].isAppendedAtTopLevel&&(this._jsPlumb.overlays[b].canvas.parentNode.removeChild(this._jsPlumb.overlays[b].canvas),a.appendChild(this._jsPlumb.overlays[b].canvas))},getLabel:function(){var a=this.getOverlay(k);return null!=a?a.getLabel():null},getLabelOverlay:function(){return this.getOverlay(k)},setLabel:function(a){var b=this.getOverlay(k);if(b)a.constructor==String||a.constructor==Function?b.setLabel(a):(a.label&&b.setLabel(a.label),a.location&&b.setLocation(a.location));else{var c=a.constructor==String||a.constructor==Function?{label:a}:a;b=m(this,c),this._jsPlumb.overlays.push(b)}this._jsPlumb.instance.isSuspendDrawing()||this.repaint()},cleanup:function(){for(var a=0;a<this._jsPlumb.overlays.length;a++)this._jsPlumb.overlays[a].cleanup(),this._jsPlumb.overlays[a].destroy();this._jsPlumb.overlays.length=0,this._jsPlumb.overlayPositions=null},setVisible:function(a){this[a?"showOverlays":"hideOverlays"]()},setAbsoluteOverlayPosition:function(a,b){this._js
 Plumb.overlayPositions=this._jsPlumb.overlayPositions||{},this._jsPlumb.overlayPositions[a.id]=b},getAbsoluteOverlayPosition:function(a){return this._jsPlumb.overlayPositions?this._jsPlumb.overlayPositions[a.id]:null}});var q=0,r=function(){var a=q+1;return q++,a},s=window.jsPlumbInstance=function(d){this.Defaults={Anchor:"Bottom",Anchors:[null,null],ConnectionsDetachable:!0,ConnectionOverlays:[],Connector:"Bezier",Container:null,DoNotThrowErrors:!1,DragOptions:{},DropOptions:{},Endpoint:"Dot",EndpointOverlays:[],Endpoints:[null,null],EndpointStyle:{fillStyle:"#456"},EndpointStyles:[null,null],EndpointHoverStyle:null,EndpointHoverStyles:[null,null],HoverPaintStyle:null,LabelStyle:{color:"black"},LogEnabled:!1,Overlays:[],MaxConnections:1,PaintStyle:{lineWidth:4,strokeStyle:"#456"},ReattachConnections:!1,RenderMode:"svg",Scope:"jsPlumb_DefaultScope"},d&&t.extend(this.Defaults,d),this.logEnabled=this.Defaults.LogEnabled,this._connectionTypes={},this._endpointTypes={},jsPlumbUtil.Event
 Generator.apply(this);var f=this,g=r(),h=f.bind,j={},k=1,l=function(a){var b=f.getDOMElement(a);return{el:b,id:jsPlumbUtil.isString(a)&&null==b?a:X(b)}};this.getInstanceIndex=function(){return g},this.setZoom=function(a,b){return jsPlumbUtil.oldIE||(k=a,f.fire("zoom",k),b&&f.repaintEverything()),!jsPlumbUtil.oldIE},this.getZoom=function(){return k};for(var m in this.Defaults)j[m]=this.Defaults[m];var n;this.setContainer=function(a){a=this.getDOMElement(a),this.select().each(function(b){b.moveParent(a)}),this.selectEndpoints().each(function(b){b.moveParent(a)}),n=a;for(var b=function(a,b){var c=b.srcElement||b.target,d=(c&&c.parentNode?c.parentNode._jsPlumb:null)||(c?c._jsPlumb:null)||(c&&c.parentNode&&c.parentNode.parentNode?c.parentNode.parentNode._jsPlumb:null);d&&(d.fire(a,d,b),f.fire(a,d,b))},c=function(a){f.on(n,a,"._jsPlumb_connector, ._jsPlumb_connector > *",function(c){b(a,c)}),f.on(n,a,"._jsPlumb_endpoint, ._jsPlumb_endpoint > *, ._jsPlumb_endpoint svg *",function(c){b(a,c)
 }),f.on(n,a,"._jsPlumb_overlay, ._jsPlumb_overlay *",function(c){b(a,c)})},d=0;d<e.length;d++)c(e[d])},this.getContainer=function(){return n},this.bind=function(a,b){"ready"===a&&p?b():h.apply(f,[a,b])},f.importDefaults=function(a){for(var b in a)f.Defaults[b]=a[b];return a.Container&&f.setContainer(a.Container),f},f.restoreDefaults=function(){return f.Defaults=t.extend({},j),f};var o=null,p=!1,q=[],s={},u={},v={},w={},x={},y={},z=!1,A=[],B=!1,C=null,D=this.Defaults.Scope,E=null,F=1,G=function(){return""+F++},H=function(a,b){n?n.appendChild(a):b?this.getDOMElement(b).appendChild(a):this.appendToRoot(a)}.bind(this),I=function(a,b,d,e){if(!jsPlumbAdapter.headless&&!B){var g=X(a),h=f.dragManager.getElementsForDraggable(g);null==d&&(d=c());var i=tb({elId:g,offset:b,recalc:!1,timestamp:d});if(h)for(var j in h)tb({elId:h[j].id,offset:{left:i.o.left+h[j].offset.left,top:i.o.top+h[j].offset.top},recalc:!1,timestamp:d});if(f.anchorManager.redraw(g,b,d,null,e),h)for(var k in h)f.anchorManager
 .redraw(h[k].id,b,d,h[k].offset,e,!0)}},J=function(b,c){var d,e,g,h=null;if(a.isArray(b)){h=[];for(var i=0,j=b.length;j>i;i++)d=f.getElementObject(b[i]),g=f.getDOMElement(d),e=f.getAttribute(g,"id"),h.push(c.apply(f,[g,e]))}else d=f.getDOMElement(b),e=f.getId(d),h=c.apply(f,[d,e]);return h},K=function(a){return u[a]},L=function(b,c,d,e){if(!jsPlumbAdapter.headless){var g=null==c?!1:c;if(g&&t.isDragSupported(b,f)&&!t.isAlreadyDraggable(b,f)){var h=d||f.Defaults.DragOptions;h=t.extend({},h);var i=t.dragEvents.drag,j=t.dragEvents.stop,k=t.dragEvents.start,l=f.getDOMElement(b),m=f.dragManager.getDragAncestor(l),n={left:0,top:0},o=n,p=!1;rb(e,b),h[k]=a.wrap(h[k],function(){return o=null!=m?jsPlumbAdapter.getOffset(m,f):n,f.setHoverSuspended(!0),f.select({source:b}).addClass(f.elementDraggingClass+" "+f.sourceElementDraggingClass,!0),f.select({target:b}).addClass(f.elementDraggingClass+" "+f.targetElementDraggingClass,!0),f.setConnectionBeingDragged(!0),h.canDrag?d.canDrag():void 0},!1),h
 [i]=a.wrap(h[i],function(){var a=f.getUIPosition(arguments,f.getZoom());a.left+=o.left,a.top+=o.top,I(b,a,null,!0),p&&f.addClass(b,"jsPlumb_dragged"),p=!0}),h[j]=a.wrap(h[j],function(){var a=f.getUIPosition(arguments,f.getZoom(),!0);I(b,a),p=!1,f.removeClass(b,"jsPlumb_dragged"),f.setHoverSuspended(!1),f.select({source:b}).removeClass(f.elementDraggingClass+" "+f.sourceElementDraggingClass,!0),f.select({target:b}).removeClass(f.elementDraggingClass+" "+f.targetElementDraggingClass,!0),f.setConnectionBeingDragged(!1),f.dragManager.dragEnded(b)});var q=X(b);y[q]=!0;var r=y[q];h.disabled=null==r?!1:!r,f.initDraggable(b,h),f.dragManager.register(b)}}},M=function(a,b){for(var c=a.scope.split(/\s/),d=b.scope.split(/\s/),e=0;e<c.length;e++)for(var f=0;f<d.length;f++)if(d[f]==c[e])return!0;return!1},N=function(b,c){var d=t.extend({},b);if(c&&t.extend(d,c),d.source&&(d.source.endpoint?d.sourceEndpoint=d.source:d.source=f.getDOMElement(d.source)),d.target&&(d.target.endpoint?d.targetEndpoint=
 d.target:d.target=f.getDOMElement(d.target)),b.uuids&&(d.sourceEndpoint=K(b.uuids[0]),d.targetEndpoint=K(b.uuids[1])),d.sourceEndpoint&&d.sourceEndpoint.isFull())return a.log(f,"could not add connection; source endpoint is full"),void 0;if(d.targetEndpoint&&d.targetEndpoint.isFull())return a.log(f,"could not add connection; target endpoint is full"),void 0;if(!d.type&&d.sourceEndpoint&&(d.type=d.sourceEndpoint.connectionType),d.sourceEndpoint&&d.sourceEndpoint.connectorOverlays){d.overlays=d.overlays||[];for(var e=0,g=d.sourceEndpoint.connectorOverlays.length;g>e;e++)d.overlays.push(d.sourceEndpoint.connectorOverlays[e])}!d["pointer-events"]&&d.sourceEndpoint&&d.sourceEndpoint.connectorPointerEvents&&(d["pointer-events"]=d.sourceEndpoint.connectorPointerEvents);var h=function(a,b){var c=t.extend({},a);for(var d in b)b[d]&&(c[d]=b[d]);return c},i=function(a,b,c){return f.addEndpoint(a,h(b,{anchor:d.anchors?d.anchors[c]:d.anchor,endpoint:d.endpoints?d.endpoints[c]:d.endpoint,paintStyl
 e:d.endpointStyles?d.endpointStyles[c]:d.endpointStyle,hoverPaintStyle:d.endpointHoverStyles?d.endpointHoverStyles[c]:d.endpointHoverStyle}))},j=function(a,b,c){if(d[a]&&!d[a].endpoint&&!d[a+"Endpoint"]&&!d.newConnection){var e=X(d[a]),f=c[e];if(f){if(!f.enabled)return!1;var g=null!=f.endpoint&&f.endpoint._jsPlumb?f.endpoint:i(d[a],f.def,b);if(f.uniqueEndpoint&&(f.endpoint=g),g.isFull())return!1;d[a+"Endpoint"]=g,g._doNotDeleteOnDetach=!1,g._deleteOnDetach=!0}}};return j("source",0,this.sourceEndpointDefinitions)!==!1&&j("target",1,this.targetEndpointDefinitions)!==!1?(d.sourceEndpoint&&d.targetEndpoint&&(M(d.sourceEndpoint,d.targetEndpoint)||(d=null)),d):void 0}.bind(f),O=function(a){var b=f.Defaults.ConnectionType||f.getDefaultConnectionType();a._jsPlumb=f,a.newConnection=O,a.newEndpoint=Q,a.endpointsByUUID=u,a.endpointsByElement=s,a.finaliseConnection=P;var c=new b(a);return c.id="con_"+G(),c.isDetachable()&&(c.endpoints[0].initDraggable(),c.endpoints[1].initDraggable()),c},P=f.f
 inaliseConnection=function(a,b,c,d){if(b=b||{},a.suspendedEndpoint||q.push(a),a.endpoints[0].isTemporarySource=!1,(null==a.suspendedEndpoint||d)&&f.anchorManager.newConnection(a),I(a.source),!b.doNotFireConnectionEvent&&b.fireEvent!==!1){var e={connection:a,source:a.source,target:a.target,sourceId:a.sourceId,targetId:a.targetId,sourceEndpoint:a.endpoints[0],targetEndpoint:a.endpoints[1]};f.fire("connection",e,c)}},Q=function(a,b){var c=f.Defaults.EndpointType||t.Endpoint,d=t.extend({},a);d._jsPlumb=f,d.newConnection=O,d.newEndpoint=Q,d.endpointsByUUID=u,d.endpointsByElement=s,d.fireDetachEvent=$,d.elementId=b||X(d.source);var e=new c(d);return e.id="ep_"+G(),rb(d.elementId,d.source),jsPlumbAdapter.headless||f.dragManager.endpointAdded(d.source,b),e},R=function(a,b,c){var d=s[a];if(d&&d.length)for(var e=0,f=d.length;f>e;e++){for(var g=0,h=d[e].connections.length;h>g;g++){var i=b(d[e].connections[g]);if(i)return}c&&c(d[e])}},S=function(a,b){return J(a,function(a,c){y[c]=b,this.isDragS
 upported(a)&&this.setElementDraggable(a,b)})},T=function(a,b,c){b="block"===b;var d=null;c&&(d=b?function(a){a.setVisible(!0,!0,!0)}:function(a){a.setVisible(!1,!0,!0)});var e=l(a);R(e.id,function(a){if(b&&c){var d=a.sourceId===e.id?1:0;a.endpoints[d].isVisible()&&a.setVisible(!0)}else a.setVisible(b)},d)},U=function(a){return J(a,function(a,b){var c=null==y[b]?!1:y[b];return c=!c,y[b]=c,this.setDraggable(a,c),c}.bind(this))},V=function(a,b){var c=null;b&&(c=function(a){var b=a.isVisible();a.setVisible(!b)}),R(a,function(a){var b=a.isVisible();a.setVisible(!b)},c)},W=function(a){var b=w[a];return b?{o:b,s:A[a]}:tb({elId:a})},X=function(a,b,c){if(jsPlumbUtil.isString(a))return a;if(null==a)return null;var d=f.getAttribute(a,"id");return d&&"undefined"!==d||(2==arguments.length&&void 0!==arguments[1]?d=b:(1==arguments.length||3==arguments.length&&!arguments[2])&&(d="jsPlumb_"+g+"_"+G()),c||f.setAttribute(a,"id",d)),d};this.setConnectionBeingDragged=function(a){z=a},this.isConnectionBe
 ingDragged=function(){return z},this.connectorClass="_jsPlumb_connector",this.hoverClass="_jsPlumb_hover",this.endpointClass="_jsPlumb_endpoint",this.endpointConnectedClass="_jsPlumb_endpoint_connected",this.endpointFullClass="_jsPlumb_endpoint_full",this.endpointDropAllowedClass="_jsPlumb_endpoint_drop_allowed",this.endpointDropForbiddenClass="_jsPlumb_endpoint_drop_forbidden",this.overlayClass="_jsPlumb_overlay",this.draggingClass="_jsPlumb_dragging",this.elementDraggingClass="_jsPlumb_element_dragging",this.sourceElementDraggingClass="_jsPlumb_source_element_dragging",this.targetElementDraggingClass="_jsPlumb_target_element_dragging",this.endpointAnchorClassPrefix="_jsPlumb_endpoint_anchor",this.hoverSourceClass="_jsPlumb_source_hover",this.hoverTargetClass="_jsPlumb_target_hover",this.dragSelectClass="_jsPlumb_drag_select",this.Anchors={},this.Connectors={svg:{},vml:{}},this.Endpoints={svg:{},vml:{}},this.Overlays={svg:{},vml:{}},this.ConnectorRenderers={},this.SVG="svg",this.VM
 L="vml",this.addEndpoint=function(b,c,d){d=d||{};var e=t.extend({},d);t.extend(e,c),e.endpoint=e.endpoint||f.Defaults.Endpoint,e.paintStyle=e.paintStyle||f.Defaults.EndpointStyle;for(var g=[],h=a.isArray(b)||null!=b.length&&!a.isString(b)?b:[b],i=0,j=h.length;j>i;i++){e.source=f.getDOMElement(h[i]),pb(e.source);var k=X(e.source),l=Q(e,k),m=rb(k,e.source).info.o;a.addToList(s,k,l),B||l.paint({anchorLoc:l.anchor.compute({xy:[m.left,m.top],wh:A[k],element:l,timestamp:C}),timestamp:C}),g.push(l),l._doNotDeleteOnDetach=!0}return 1==g.length?g[0]:g},this.addEndpoints=function(b,c,d){for(var e=[],g=0,h=c.length;h>g;g++){var i=f.addEndpoint(b,c[g],d);a.isArray(i)?Array.prototype.push.apply(e,i):e.push(i)}return e},this.animate=function(b,c,d){d=d||{};var e=f.getElementObject(b),g=f.getDOMElement(b),h=X(g),i=t.animEvents.step,j=t.animEvents.complete;d[i]=a.wrap(d[i],function(){f.revalidate(h)}),d[j]=a.wrap(d[j],function(){f.revalidate(h)}),f.doAnimate(e,c,d)},this.checkCondition=function(b,c
 ){var d=f.getListener(b),e=!0;if(d&&d.length>0)try{for(var g=0,h=d.length;h>g;g++)e=e&&d[g](c)}catch(i){a.log(f,"cannot check condition ["+b+"]"+i)}return e},this.connect=function(a,b){var c,d=N(a,b);if(d){if(null==d.source&&null==d.sourceEndpoint)return jsPlumbUtil.log("Cannot establish connection - source does not exist"),void 0;if(null==d.target&&null==d.targetEndpoint)return jsPlumbUtil.log("Cannot establish connection - target does not exist"),void 0;pb(d.source),c=O(d),P(c,d)}return c};var Y=[{el:"source",elId:"sourceId",epDefs:"sourceEndpointDefinitions"},{el:"target",elId:"targetId",epDefs:"targetEndpointDefinitions"}],Z=function(a,b,c,d){var e,f,g,h=Y[c],i=a[h.elId],j=(a[h.el],a.endpoints[c]),k={index:c,originalSourceId:0===c?i:a.sourceId,newSourceId:a.sourceId,originalTargetId:1==c?i:a.targetId,newTargetId:a.targetId,connection:a};if(b.constructor==t.Endpoint)e=b,e.addConnection(a);else if(f=X(b),g=this[h.epDefs][f],f===a[h.elId])e=null;else if(g){if(!g.enabled)return;e=nu
 ll!=g.endpoint&&g.endpoint._jsPlumb?g.endpoint:this.addEndpoint(b,g.def),g.uniqueEndpoint&&(g.endpoint=e),e._doNotDeleteOnDetach=!1,e._deleteOnDetach=!0,e.addConnection(a)}else e=a.makeEndpoint(0===c,b,f),e._doNotDeleteOnDetach=!1,e._deleteOnDetach=!0;return null!=e&&(j.detachFromConnection(a),a.endpoints[c]=e,a[h.el]=e.element,a[h.elId]=e.elementId,k[0===c?"newSourceId":"newTargetId"]=e.elementId,_(k),d||a.repaint()),k}.bind(this);this.setSource=function(a,b,c){var d=Z(a,b,0,c);this.anchorManager.sourceChanged(d.originalSourceId,d.newSourceId,a)},this.setTarget=function(a,b,c){var d=Z(a,b,1,c);this.anchorManager.updateOtherEndpoint(d.originalSourceId,d.originalTargetId,d.newTargetId,a)},this.deleteEndpoint=function(a,b){var c="string"==typeof a?u[a]:a;return c&&f.deleteObject({endpoint:c,dontUpdateHover:b}),f},this.deleteEveryEndpoint=function(){var a=f.setSuspendDrawing(!0);for(var b in s){var c=s[b];if(c&&c.length)for(var d=0,e=c.length;e>d;d++)f.deleteEndpoint(c[d],!0)}return s=
 {},v={},u={},f.anchorManager.reset(),f.dragManager.reset(),a||f.setSuspendDrawing(!1),f};var $=function(a,b,c){var d=f.Defaults.ConnectionType||f.getDefaultConnectionType(),e=a.constructor==d,g=e?{connection:a,source:a.source,target:a.target,sourceId:a.sourceId,targetId:a.targetId,sourceEndpoint:a.endpoints[0],targetEndpoint:a.endpoints[1]}:a;b&&f.fire("connectionDetached",g,c),f.anchorManager.connectionDetached(g)},_=f.fireMoveEvent=function(a,b){f.fire("connectionMoved",a,b)};this.unregisterEndpoint=function(a){a._jsPlumb.uuid&&(u[a._jsPlumb.uuid]=null),f.anchorManager.deleteEndpoint(a);for(var b in s){var c=s[b];if(c){for(var d=[],e=0,g=c.length;g>e;e++)c[e]!=a&&d.push(c[e]);s[b]=d}s[b].length<1&&delete s[b]}},this.detach=function(){if(0!==arguments.length){var a=f.Defaults.ConnectionType||f.getDefaultConnectionType(),b=arguments[0].constructor==a,c=2==arguments.length?b?arguments[1]||{}:arguments[0]:arguments[0],d=c.fireEvent!==!1,e=c.forceDetach,g=b?arguments[0]:c.connection;if
 (g)(e||jsPlumbUtil.functionChain(!0,!1,[[g.endpoints[0],"isDetachAllowed",[g]],[g.endpoints[1],"isDetachAllowed",[g]],[g,"isDetachAllowed",[g]],[f,"checkCondition",["beforeDetach",g]]]))&&g.endpoints[0].detach(g,!1,!0,d);else{var h=t.extend({},c);if(h.uuids)K(h.uuids[0]).detachFrom(K(h.uuids[1]),d);else if(h.sourceEndpoint&&h.targetEndpoint)h.sourceEndpoint.detachFrom(h.targetEndpoint);else{var i=X(f.getDOMElement(h.source)),j=X(f.getDOMElement(h.target));R(i,function(a){(a.sourceId==i&&a.targetId==j||a.targetId==i&&a.sourceId==j)&&f.checkCondition("beforeDetach",a)&&a.endpoints[0].detach(a,!1,!0,d)})}}}},this.detachAllConnections=function(a,b){b=b||{},a=f.getDOMElement(a);var c=X(a),d=s[c];if(d&&d.length)for(var e=0,g=d.length;g>e;e++)d[e].detachAll(b.fireEvent!==!1);return f},this.detachEveryConnection=function(a){return a=a||{},f.doWhileSuspended(function(){for(var b in s){var c=s[b];if(c&&c.length)for(var d=0,e=c.length;e>d;d++)c[d].detachAll(a.fireEvent!==!1)}q.length=0}),f},th
 is.deleteObject=function(a){var b={endpoints:{},connections:{},endpointCount:0,connectionCount:0},c=a.fireEvent!==!1,d=a.deleteAttachedObjects!==!1,e=function(c){if(null!=c&&null==b.connections[c.id]&&(a.dontUpdateHover||null==c._jsPlumb||c.setHover(!1),b.connections[c.id]=c,b.connectionCount++,d))for(var e=0;e<c.endpoints.length;e++)c.endpoints[e]._deleteOnDetach&&g(c.endpoints[e])},g=function(c){if(null!=c&&null==b.endpoints[c.id]&&(a.dontUpdateHover||null==c._jsPlumb||c.setHover(!1),b.endpoints[c.id]=c,b.endpointCount++,d))for(var f=0;f<c.connections.length;f++){var g=c.connections[f];e(g)}};a.connection?e(a.connection):g(a.endpoint);for(var h in b.connections){var i=b.connections[h];i._jsPlumb&&(jsPlumbUtil.removeWithFunction(q,function(a){return i.id==a.id}),$(i,c,a.originalEvent),i.endpoints[0].detachFromConnection(i),i.endpoints[1].detachFromConnection(i),i.cleanup(),i.destroy())}for(var j in b.endpoints){var k=b.endpoints[j];k._jsPlumb&&(f.unregisterEndpoint(k),k.cleanup(),k
 .destroy())}return b},this.draggable=function(a,b){var c,d,e;if("object"==typeof a&&a.length)for(c=0,d=a.length;d>c;c++)e=l(a[c]),e.el&&L(e.el,!0,b,e.id);else e=l(a),e.el&&L(e.el,!0,b,e.id);return f};var ab=function(a,b,c,d){for(var e=0,f=a.length;f>e;e++)a[e][b].apply(a[e],c);return d(a)},bb=function(a,b,c){for(var d=[],e=0,f=a.length;f>e;e++)d.push([a[e][b].apply(a[e],c),a[e]]);return d},cb=function(a,b,c){return function(){return ab(a,b,arguments,c)}},db=function(a,b){return function(){return bb(a,b,arguments)}},eb=function(a,b){var c=[];if(a)if("string"==typeof a){if("*"===a)return a;c.push(a)}else if(b)c=a;else if(a.length)for(var d=0,e=a.length;e>d;d++)c.push(l(a[d]).id);else c.push(l(a).id);return c},fb=function(a,b,c){return"*"===a?!0:a.length>0?-1!=jsPlumbUtil.indexOf(a,b):!c};this.getConnections=function(a,b){a?a.constructor==String&&(a={scope:a}):a={};for(var c=a.scope||f.getDefaultScope(),d=eb(c,!0),e=eb(a.source),g=eb(a.target),h=!b&&d.length>1?{}:[],i=function(a,c){if(
 !b&&d.length>1){var e=h[a];null==e&&(e=h[a]=[]),e.push(c)}else h.push(c)},j=0,k=q.length;k>j;j++){var l=q[j];fb(d,l.scope)&&fb(e,l.sourceId)&&fb(g,l.targetId)&&i(l.scope,l)}return h};var gb=function(a,b){return function(c){for(var d=0,e=a.length;e>d;d++)c(a[d]);return b(a)}},hb=function(a){return function(b){return a[b]}},ib=function(a,b){var c,d,e={length:a.length,each:gb(a,b),get:hb(a)},f=["setHover","removeAllOverlays","setLabel","addClass","addOverlay","removeOverlay","removeOverlays","showOverlay","hideOverlay","showOverlays","hideOverlays","setPaintStyle","setHoverPaintStyle","setSuspendEvents","setParameter","setParameters","setVisible","repaint","addType","toggleType","removeType","removeClass","setType","bind","unbind"],g=["getLabel","getOverlay","isHover","getParameter","getParameters","getPaintStyle","getHoverPaintStyle","isVisible","hasType","getType","isSuspendEvents"];for(c=0,d=f.length;d>c;c++)e[f[c]]=cb(a,f[c],b);for(c=0,d=g.length;d>c;c++)e[g[c]]=db(a,g[c]);return e
 },jb=function(a){var b=ib(a,jb);return t.extend(b,{setDetachable:cb(a,"setDetachable",jb),setReattach:cb(a,"setReattach",jb),setConnector:cb(a,"setConnector",jb),detach:function(){for(var b=0,c=a.length;c>b;b++)f.detach(a[b])},isDetachable:db(a,"isDetachable"),isReattach:db(a,"isReattach")})},kb=function(a){var b=ib(a,kb);return t.extend(b,{setEnabled:cb(a,"setEnabled",kb),setAnchor:cb(a,"setAnchor",kb),isEnabled:db(a,"isEnabled"),detachAll:function(){for(var b=0,c=a.length;c>b;b++)a[b].detachAll()},remove:function(){for(var b=0,c=a.length;c>b;b++)f.deleteObject({endpoint:a[b]})}})};this.select=function(a){return a=a||{},a.scope=a.scope||"*",jb(a.connections||f.getConnections(a,!0))},this.selectEndpoints=function(a){a=a||{},a.scope=a.scope||"*";var b=!a.element&&!a.source&&!a.target,c=b?"*":eb(a.element),d=b?"*":eb(a.source),e=b?"*":eb(a.target),f=eb(a.scope,!0),g=[];for(var h in s){var i=fb(c,h,!0),j=fb(d,h,!0),k="*"!=d,l=fb(e,h,!0),m="*"!=e;if(i||j||l)a:for(var n=0,o=s[h].length;o
 >n;n++){var p=s[h][n];if(fb(f,p.scope,!0)){var q=k&&d.length>0&&!p.isSource,r=m&&e.length>0&&!p.isTarget;
+if(q||r)continue a;g.push(p)}}}return kb(g)},this.getAllConnections=function(){return q},this.getDefaultScope=function(){return D},this.getEndpoint=K,this.getEndpoints=function(a){return s[l(a).id]},this.getDefaultEndpointType=function(){return t.Endpoint},this.getDefaultConnectionType=function(){return t.Connection},this.getId=X,this.getOffset=function(a){return tb({elId:a}).o},this.appendElement=H;var lb=!1;this.isHoverSuspended=function(){return lb},this.setHoverSuspended=function(a){lb=a};var mb=function(a){return function(){return jsPlumbAdapter.isRenderModeAvailable(a)}};this.isSVGAvailable=mb("svg"),this.isVMLAvailable=mb("vml"),this.hide=function(a,b){return T(a,"none",b),f},this.idstamp=G,this.connectorsInitialized=!1;var nb=[],ob=["svg","vml"];this.registerConnectorType=function(a,b){nb.push([a,b])};var pb=function(a){if(!n&&a){var b=f.getDOMElement(a);b.offsetParent&&f.setContainer(b.offsetParent)}},qb=function(){f.Defaults.Container&&f.setContainer(f.Defaults.Container)}
 ,rb=f.manage=function(a,b){return v[a]||(v[a]={el:b,endpoints:[],connections:[]},v[a].info=tb({elId:a,timestamp:C})),v[a]},sb=function(a){delete v[a]},tb=this.updateOffset=function(a){var c,d=a.timestamp,e=a.recalc,g=a.offset,h=a.elId;return B&&!d&&(d=C),!e&&d&&d===x[h]?{o:a.offset||w[h],s:A[h]}:(e||!g&&null==w[h]?(c=v[h]?v[h].el:null,null!=c&&(A[h]=f.getSize(c),w[h]=b(c,f),x[h]=d)):(w[h]=g||w[h],null==A[h]&&(c=v[h].el,null!=c&&(A[h]=f.getSize(c))),x[h]=d),w[h]&&!w[h].right&&(w[h].right=w[h].left+A[h][0],w[h].bottom=w[h].top+A[h][1],w[h].width=A[h][0],w[h].height=A[h][1],w[h].centerx=w[h].left+w[h].width/2,w[h].centery=w[h].top+w[h].height/2),{o:w[h],s:A[h]})};this.init=function(){var a=function(a,b,c){t.Connectors[a][b]=function(){c.apply(this,arguments),t.ConnectorRenderers[a].apply(this,arguments)},jsPlumbUtil.extend(t.Connectors[a][b],[c,t.ConnectorRenderers[a]])};if(!t.connectorsInitialized){for(var b=0;b<nb.length;b++)for(var c=0;c<ob.length;c++)a(ob[c],nb[b][1],nb[b][0]);t.co
 nnectorsInitialized=!0}p||(qb(),f.anchorManager=new t.AnchorManager({jsPlumbInstance:f}),f.setRenderMode(f.Defaults.RenderMode),p=!0,f.fire("ready",f))}.bind(this),this.log=o,this.jsPlumbUIComponent=i,this.makeAnchor=function(){var b,c=function(a,b){if(t.Anchors[a])return new t.Anchors[a](b);if(!f.Defaults.DoNotThrowErrors)throw{msg:"jsPlumb: unknown anchor type '"+a+"'"}};if(0===arguments.length)return null;var d=arguments[0],e=arguments[1],g=(arguments[2],null);if(d.compute&&d.getOrientation)return d;if("string"==typeof d)g=c(arguments[0],{elementId:e,jsPlumbInstance:f});else if(a.isArray(d))if(a.isArray(d[0])||a.isString(d[0]))2==d.length&&a.isObject(d[1])?a.isString(d[0])?(b=t.extend({elementId:e,jsPlumbInstance:f},d[1]),g=c(d[0],b)):(b=t.extend({elementId:e,jsPlumbInstance:f,anchors:d[0]},d[1]),g=new t.DynamicAnchor(b)):g=new t.DynamicAnchor({anchors:d,selector:null,elementId:e,jsPlumbInstance:f});else{var h={x:d[0],y:d[1],orientation:d.length>=4?[d[2],d[3]]:[0,0],offsets:d.len
 gth>=6?[d[4],d[5]]:[0,0],elementId:e,jsPlumbInstance:f,cssClass:7==d.length?d[6]:null};g=new t.Anchor(h),g.clone=function(){return new t.Anchor(h)}}return g.id||(g.id="anchor_"+G()),g},this.makeAnchors=function(b,c,d){for(var e=[],g=0,h=b.length;h>g;g++)"string"==typeof b[g]?e.push(t.Anchors[b[g]]({elementId:c,jsPlumbInstance:d})):a.isArray(b[g])&&e.push(f.makeAnchor(b[g],c,d));return e},this.makeDynamicAnchor=function(a,b){return new t.DynamicAnchor({anchors:a,selector:b,elementId:null,jsPlumbInstance:f})},this.targetEndpointDefinitions={};var ub=function(a,b,c){a.paintStyle=a.paintStyle||c.Defaults.EndpointStyles[b]||c.Defaults.EndpointStyle,a.hoverPaintStyle=a.hoverPaintStyle||c.Defaults.EndpointHoverStyles[b]||c.Defaults.EndpointHoverStyle,a.anchor=a.anchor||c.Defaults.Anchors[b]||c.Defaults.Anchor,a.endpoint=a.endpoint||c.Defaults.Endpoints[b]||c.Defaults.Endpoint};this.sourceEndpointDefinitions={};var vb=function(a,b,c,d,e){for(var f=a.target||a.srcElement,g=!1,h=d.getSelector
 (b,c),i=0;i<h.length;i++)if(h[i]==f){g=!0;break}return e?!g:g};this.makeTarget=function(c,d,e){var g=t.extend({_jsPlumb:this},e);t.extend(g,d),ub(g,1,this);for(var h=g.scope||f.Defaults.Scope,j=(!(g.deleteEndpointsOnDetach===!1),g.maxConnections||-1),k=g.onMaxConnections,m=function(c){var d=l(c),e=d.id,m=new i(g),n=t.extend({},g.dropOptions||{});pb(e);var o={def:g,uniqueEndpoint:g.uniqueEndpoint,maxConnections:j,enabled:!0};d.el._jsPlumbTarget=o,this.targetEndpointDefinitions[e]=o;var p=g._jsPlumb.EndpointDropHandler({jsPlumb:f,enabled:function(){return d.el._jsPlumbTarget.enabled},isFull:function(a){var b=f.select({target:e}).length,c=d.el._jsPlumbTarget,g=c.maxConnections>0&&b>=c.maxConnections;return g&&k&&k({element:d.el,connection:jpc},a),g},element:d.el,elementId:e,isSource:!1,isTarget:!0,addClass:function(a){f.addClass(d.el,a)},removeClass:function(a){f.removeClass(d.el,a)},onDrop:function(a){var b=a.endpoints[0];b.anchor.locked=!1},isDropAllowed:function(){return m.isDropAll
 owed.apply(m,arguments)},getEndpoint:function(a){var c=f.getElementObject(d.el),e=d.el._jsPlumbTarget,h=e.endpoint;if((null==h||null==h._jsPlumb)&&(h=f.addEndpoint(c,g)),g.uniqueEndpoint&&(e.endpoint=h),h._doNotDeleteOnDetach=!1,h._deleteOnDetach=!0,a.isDetachable()&&h.initDraggable(),null!=h.anchor.positionFinder){var i=f.getUIPosition(arguments,this.getZoom()),j=b(c,this),k=f.getSize(c),l=h.anchor.positionFinder(i,j,k,h.anchor.constructorParams);h.anchor.x=l[0],h.anchor.y=l[1]}return h}}),q=t.dragEvents.drop;n.scope=n.scope||h,n[q]=a.wrap(n[q],p),g.allowLoopback===!1&&(n.canDrop=function(a){var b=a.getDragElement()._jsPlumbRelatedElement;return b!=d.el}),this.initDroppable(this.getElementObject(d.el),n,"internal")}.bind(this),n=c.length&&c.constructor!=String?c:[c],o=0,p=n.length;p>o;o++)m(n[o]);return this},this.unmakeTarget=function(a,b){var c=l(a);return t.destroyDroppable(c.el),b||delete this.targetEndpointDefinitions[c.id],this},this.makeSource=function(c,d,e){var g=t.extend(
 {},e);t.extend(g,d),ub(g,0,this);for(var h=g.maxConnections||1,i=g.onMaxConnections,j=function(c){var d=c.id,e=this.getElementObject(c.el),j=this.getDOMElement(e),l=function(){return null==g.parent?null:"parent"===g.parent?c.el.parentNode:f.getDOMElement(g.parent)},m=null!=g.parent?this.getId(l()):d;pb(m),this.sourceEndpointDefinitions[m]={def:g,uniqueEndpoint:g.uniqueEndpoint,maxConnections:h,enabled:!0};var o=t.dragEvents.stop,p=t.dragEvents.drag,q=t.extend({},g.dragOptions||{}),r=q.drag,s=q.stop,u=null,v=!1;q.scope=q.scope||g.scope,q[p]=a.wrap(q[p],function(){r&&r.apply(this,arguments),v=!1}),q[o]=a.wrap(q[o],function(){if(s&&s.apply(this,arguments),this.currentlyDragging=!1,null!=u._jsPlumb){var a=g.anchor||this.Defaults.Anchor,c=u.anchor,e=u.connections[0],f=this.makeAnchor(a,d,this),h=u.element;if(null!=f.positionFinder){var i=b(h,this),j=this.getSize(h),k={left:i.left+c.x*j[0],top:i.top+c.y*j[1]},m=f.positionFinder(k,i,j,f.constructorParams);f.x=m[0],f.y=m[1]}if(u.setAnchor(f
 ,!0),g.parent){var o=l();if(o){var p=g.container||n;u.setElement(o,p)}}u.repaint(),this.repaint(u.elementId),this.repaint(e.targetId)}}.bind(this));var w=function(a){var b=this.getOriginalEvent(a);if(3!==a.which&&2!==a.button){var c=this.sourceEndpointDefinitions[m];if(d=this.getId(this.getDOMElement(e)),c.enabled){if(g.filter){var n=jsPlumbUtil.isString(g.filter)?vb(b,e,g.filter,this,g.filterExclude):g.filter(b,e);if(n===!1)return}var o=this.select({source:m}).length;if(c.maxConnections>=0&&c.uniqueEndpoint&&o>=c.maxConnections)return i&&i({element:e,maxConnections:h},a),!1;var p=jsPlumbAdapter.getPositionOnElement(b,j,k),r={};t.extend(r,g),r.isTemporarySource=!0,r.anchor=[p[0],p[1],0,0],r.dragOptions=q,u=this.addEndpoint(d,r),v=!0,u.endpointWillMoveTo=g.parent?l():null,c.uniqueEndpoint&&(c.endpoint?u.finalEndpoint=c.endpoint:c.endpoint=u),u._doNotDeleteOnDetach=!1,u._deleteOnDetach=!0;var s=function(){f.off(u.canvas,"mouseup",s),f.off(e,"mouseup",s),v&&(v=!1,f.deleteEndpoint(u))};
 f.on(u.canvas,"mouseup",s),f.on(e,"mouseup",s),f.trigger(u.canvas,"mousedown",a),jsPlumbUtil.consume(a)}}}.bind(this);this.on(e,"mousedown",w),this.sourceEndpointDefinitions[m].trigger=w,g.filter&&jsPlumbUtil.isString(g.filter)&&f.setDragFilter(e,g.filter)}.bind(this),m=c.length&&c.constructor!=String?c:[c],o=0,p=m.length;p>o;o++)j(l(m[o]));return this},this.unmakeSource=function(a,b){var c=l(a),d=this.sourceEndpointDefinitions[c.id].trigger;return d&&f.off(c.el,"mousedown",d),b||delete this.sourceEndpointDefinitions[c.id],this},this.unmakeEverySource=function(){for(var a in this.sourceEndpointDefinitions)f.unmakeSource(a,!0);return this.sourceEndpointDefinitions={},this};var wb=function(a,b){b=jsPlumbUtil.isArray(b)?b:[b];for(var c=X(a),d=0;d<b.length;d++){var e=this[b[d]][c];if(e)return e.def.scope||this.Defaults.Scope}}.bind(this),xb=function(a,b,c){c=jsPlumbUtil.isArray(c)?c:[c];for(var d=X(a),e=0;e<c.length;e++){var f=this[c[e]][d];f&&(f.def.scope=b,null!=this.scopeChange&&this
 .scopeChange(a,d,s[d],b,c[e]))}}.bind(this);this.getScope=function(a){return wb(a,["sourceEndpointDefinitions","targetEndpointDefinitions"])},this.getSourceScope=function(a){return wb(a,"sourceEndpointDefinitions")},this.getTargetScope=function(a){return wb(a,"targetEndpointDefinitions")},this.setScope=function(a,b){xb(a,b,["sourceEndpointDefinitions","targetEndpointDefinitions"])},this.setSourceScope=function(a,b){xb(a,b,"sourceEndpointDefinitions")},this.setTargetScope=function(a,b){xb(a,b,"targetEndpointDefinitions")},this.unmakeEveryTarget=function(){for(var a in this.targetEndpointDefinitions)f.unmakeTarget(a,!0);return this.targetEndpointDefinitions={},this};var yb=function(b,c,d,e){var f="source"==b?this.sourceEndpointDefinitions:this.targetEndpointDefinitions;if(a.isString(c))f[c].enabled=e?!f[c].enabled:d;else if(c.length)for(var g=0,h=c.length;h>g;g++){var i=l(c[g]);f[i.id]&&(f[i.id].enabled=e?!f[i.id].enabled:d)}else{var j=l(c).id;f[j].enabled=e?!f[j].enabled:d}return thi
 s}.bind(this),zb=function(b,c){return a.isString(b)||!b.length?c.apply(this,[b]):b.length?c.apply(this,[b[0]]):void 0}.bind(this);this.toggleSourceEnabled=function(a){return yb("source",a,null,!0),this.isSourceEnabled(a)},this.setSourceEnabled=function(a,b){return yb("source",a,b)},this.isSource=function(a){return zb(a,function(a){return null!=this.sourceEndpointDefinitions[l(a).id]}.bind(this))},this.isSourceEnabled=function(a){return zb(a,function(a){var b=this.sourceEndpointDefinitions[l(a).id];return b&&b.enabled===!0}.bind(this))},this.toggleTargetEnabled=function(a){return yb("target",a,null,!0),this.isTargetEnabled(a)},this.isTarget=function(a){return zb(a,function(a){return null!=this.targetEndpointDefinitions[l(a).id]}.bind(this))},this.isTargetEnabled=function(a){return zb(a,function(a){var b=this.targetEndpointDefinitions[l(a).id];return b&&b.enabled===!0}.bind(this))},this.setTargetEnabled=function(a,b){return yb("target",a,b)},this.ready=function(a){f.bind("ready",a)},t
 his.repaint=function(a,b,c){if("object"==typeof a&&a.length)for(var d=0,e=a.length;e>d;d++)I(a[d],b,c);else I(a,b,c);return f},this.revalidate=function(a){var b=f.getId(a);return f.updateOffset({elId:b,recalc:!0}),f.repaint(a)},this.repaintEverything=function(a){var b,d=c();for(b in s)f.updateOffset({elId:b,recalc:!0,timestamp:d});for(b in s)I(b,null,d,a);return this},this.removeAllEndpoints=function(a,b){var c=function(a){var d,e,g=l(a),h=s[g.id];if(h)for(d=0,e=h.length;e>d;d++)f.deleteEndpoint(h[d]);if(delete s[g.id],b&&g.el&&3!=g.el.nodeType&&8!=g.el.nodeType)for(d=0,e=g.el.childNodes.length;e>d;d++)c(g.el.childNodes[d])};return c(a),this},this.remove=function(a,b){var c=l(a);return f.doWhileSuspended(function(){f.removeAllEndpoints(c.id,!0),f.dragManager.elementRemoved(c.id),delete f.floatingConnections[c.id],f.anchorManager.clearFor(c.id),f.anchorManager.removeFloatingConnection(c.id)},b===!1),sb(c.id),c.el&&(f.removeElement(c.el),c.el._jsPlumb=null),f},this.reset=function(){f.
 setSuspendEvents(!0),f.deleteEveryEndpoint(),f.unbind(),this.targetEndpointDefinitions={},this.sourceEndpointDefinitions={},q.length=0,f.setSuspendEvents(!1)};var Ab=function(a){a.canvas&&a.canvas.parentNode&&a.canvas.parentNode.removeChild(a.canvas),a.cleanup(),a.destroy()},Bb=function(a){Ab(a)};this.clear=function(){f.select().each(Bb),f.selectEndpoints().each(Bb),s={},u={}},this.setDefaultScope=function(a){return D=a,f},this.setDraggable=S,this.setId=function(a,b,c){var d;jsPlumbUtil.isString(a)?d=a:(a=this.getDOMElement(a),d=this.getId(a));var e=this.getConnections({source:d,scope:"*"},!0),f=this.getConnections({target:d,scope:"*"},!0);b=""+b,c?a=this.getDOMElement(b):(a=this.getDOMElement(d),this.setAttribute(a,"id",b)),s[b]=s[d]||[];for(var g=0,h=s[b].length;h>g;g++)s[b][g].setElementId(b),s[b][g].setReferenceElement(a);delete s[d],this.anchorManager.changeId(d,b),this.dragManager&&this.dragManager.changeId(d,b),v[b]=v[d],delete v[d];var i=function(c,d,e){for(var f=0,g=c.lengt
 h;g>f;f++)c[f].endpoints[d].setElementId(b),c[f].endpoints[d].setReferenceElement(a),c[f][e+"Id"]=b,c[f][e]=a};i(e,0,"source"),i(f,1,"target"),this.repaint(b)},this.setDebugLog=function(a){o=a},this.setSuspendDrawing=function(a,b){var c=B;return B=a,C=a?(new Date).getTime():null,b&&this.repaintEverything(),c},this.isSuspendDrawing=function(){return B},this.getSuspendedAt=function(){return C},this.doWhileSuspended=function(b,c){var d=this.isSuspendDrawing();d||this.setSuspendDrawing(!0);try{b()}catch(e){a.log("Function run while suspended failed",e)}d||this.setSuspendDrawing(!1,!c)},this.getOffset=function(a){return w[a]},this.getCachedData=W,this.timestamp=c,this.setRenderMode=function(a){if(a!==t.SVG&&a!==t.VML)throw new TypeError("Render mode ["+a+"] not supported");return E=jsPlumbAdapter.setRenderMode(a)},this.getRenderMode=function(){return E},this.show=function(a,b){return T(a,"block",b),f},this.toggleVisible=V,this.toggleDraggable=U,this.addListener=this.bind,jsPlumbAdapter.h
 eadless||(f.dragManager=jsPlumbAdapter.getDragManager(f),f.recalculateOffsets=f.dragManager.updateOffsets)};jsPlumbUtil.extend(s,jsPlumbUtil.EventGenerator,{setAttribute:function(a,b,c){this.setAttribute(a,b,c)},getAttribute:function(a,b){return this.getAttribute(t.getDOMElement(a),b)},registerConnectionType:function(a,b){this._connectionTypes[a]=t.extend({},b)},registerConnectionTypes:function(a){for(var b in a)this._connectionTypes[b]=t.extend({},a[b])},registerEndpointType:function(a,b){this._endpointTypes[a]=t.extend({},b)},registerEndpointTypes:function(a){for(var b in a)this._endpointTypes[b]=t.extend({},a[b])},getType:function(a,b){return"connection"===b?this._connectionTypes[a]:this._endpointTypes[a]},setIdChanged:function(a,b){this.setId(a,b,!0)},setParent:function(a,b){var c=this.getElementObject(a),d=this.getDOMElement(c),e=this.getId(d),f=this.getElementObject(b),g=this.getDOMElement(f),h=this.getId(g);d.parentNode.removeChild(d),g.appendChild(d),this.dragManager.setPare
 nt(c,e,f,h)},getSize:function(a){return[a.offsetWidth,a.offsetHeight]},getWidth:function(a){return a.offsetWidth},getHeight:function(a){return a.offsetHeight},extend:function(a,b,c){var d;if(c)for(d=0;d<c.length;d++)a[c[d]]=b[c[d]];else for(d in b)a[d]=b[d];return a},floatingConnections:{},getFloatingAnchorIndex:function(a){return a.endpoints[0].isFloating()?0:1}},jsPlumbAdapter);var t=new s;"undefined"!=typeof window&&(window.jsPlumb=t),t.getInstance=function(a){var b=new s(a);return b.init(),b},"function"==typeof define&&(define("jsplumb",[],function(){return t}),define("jsplumbinstance",[],function(){return t.getInstance()})),"undefined"!=typeof exports&&(exports.jsPlumb=t)}(),function(){"use strict";var a=function(a,b){var c=!1;return{drag:function(){if(c)return c=!1,!0;var d=jsPlumb.getUIPosition(arguments,b.getZoom());a.element&&(jsPlumbAdapter.setPosition(a.element,d),b.repaint(a.element,d))},stopDrag:function(){c=!0}}},b=function(a,b){var c=document.createElement("div");c.st
 yle.position="absolute";var d=b.getContainer()||document.body;d.appendChild(c);var e=b.getId(c);b.manage(e,c),a.id=e,a.element=c},c=function(a,b,c,d,e,f,g,h){var i=new jsPlumb.FloatingAnchor({reference:b,referenceCanvas:d,jsPlumbInstance:f});return g({paintStyle:a,endpoint:c,anchor:i,source:e,scope:h})},d=["connectorStyle","connectorHoverStyle","connectorOverlays","connector","connectionType","connectorClass","connectorHoverClass"],e=function(a,b){var c=0;if(null!=b)for(var d=0;d<a.connections.length;d++)if(a.connections[d].sourceId==b||a.connections[d].targetId==b){c=d;break}return a.connections[c]},f=function(a,b){return jsPlumbUtil.findWithFunction(b.connections,function(b){return b.id==a.id})};jsPlumb.Endpoint=function(g){var h=g._jsPlumb,i=jsPlumb.getElementObject,j=jsPlumbUtil,k=g.newConnection,l=g.newEndpoint;g.finaliseConnection,g.fireMoveEvent,this.idPrefix="_jsplumb_e_",this.defaultLabelLocation=[.5,.5],this.defaultOverlayKeys=["Overlays","EndpointOverlays"],OverlayCapable
 JsPlumbUIComponent.apply(this,arguments),this.getDefaultType=function(){return{parameters:{},scope:null,maxConnections:this._jsPlumb.instance.Defaults.MaxConnections,paintStyle:this._jsPlumb.instance.Defaults.EndpointStyle||jsPlumb.Defaults.EndpointStyle,endpoint:this._jsPlumb.instance.Defaults.Endpoint||jsPlumb.Defaults.Endpoint,hoverPaintStyle:this._jsPlumb.instance.Defaults.EndpointHoverStyle||jsPlumb.Defaults.EndpointHoverStyle,overlays:this._jsPlumb.instance.Defaults.EndpointOverlays||jsPlumb.Defaults.EndpointOverlays,connectorStyle:g.connectorStyle,connectorHoverStyle:g.connectorHoverStyle,connectorClass:g.connectorClass,connectorHoverClass:g.connectorHoverClass,connectorOverlays:g.connectorOverlays,connector:g.connector,connectorTooltip:g.connectorTooltip}},this._jsPlumb.enabled=!(g.enabled===!1),this._jsPlumb.visible=!0,this.element=jsPlumb.getDOMElement(g.source),this._jsPlumb.uuid=g.uuid,this._jsPlumb.floatingEndpoint=null;var m=null;this._jsPlumb.uuid&&(g.endpointsByUUID[
 this._jsPlumb.uuid]=this),this.elementId=g.elementId,this._jsPlumb.connectionCost=g.connectionCost,this._jsPlumb.connectionsDirected=g.connectionsDirected,this._jsPlumb.currentAnchorClass="",this._jsPlumb.events={};var n=function(){var a=this._jsPlumb.currentAnchorClass;this._jsPlumb.currentAnchorClass=this.anchor.getCssClass(),jsPlumbAdapter.updateClasses(this.element,h.endpointAnchorClassPrefix+"_"+this._jsPlumb.currentAnchorClass,h.endpointAnchorClassPrefix+"_"+a),this.updateClasses(h.endpointAnchorClassPrefix+"_"+this._jsPlumb.currentAnchorClass,h.endpointAnchorClassPrefix+"_"+a)}.bind(this);this.setAnchor=function(a,b){return this._jsPlumb.instance.continuousAnchorFactory.clear(this.elementId),this.anchor=this._jsPlumb.instance.makeAnchor(a,this.elementId,h),n(),this.anchor.bind("anchorChanged",function(a){this.fire("anchorChanged",{endpoint:this,anchor:a}),n()}.bind(this)),b||this._jsPlumb.instance.repaint(this.elementId),this};var o=g.anchor?g.anchor:g.anchors?g.anchors:h.Def
 aults.Anchor||"Top";this.setAnchor(o,!0);var p=function(a){if(this.connections.length>0)for(var b=0;b<this.connections.length;b++)this.connections[b].setHover(a,!1);else this.setHover(a)}.bind(this);this.bind("mouseover",function(){p(!0)}),this.bind("mouseout",function(){p(!1)}),g._transient||this._jsPlumb.instance.anchorManager.add(this,this.elementId),this.setEndpoint=function(a){null!=this.endpoint&&(this.endpoint.cleanup(),this.endpoint.destroy());var b=function(a,b){var c=h.getRenderMode();if(jsPlumb.Endpoints[c][a])return new jsPlumb.Endpoints[c][a](b);if(!h.Defaults.DoNotThrowErrors)throw{msg:"jsPlumb: unknown endpoint type '"+a+"'"}},c={_jsPlumb:this._jsPlumb.instance,cssClass:g.cssClass,container:g.container,tooltip:g.tooltip,connectorTooltip:g.connectorTooltip,endpoint:this};j.isString(a)?this.endpoint=b(a,c):j.isArray(a)?(c=j.merge(a[1],c),this.endpoint=b(a[0],c)):this.endpoint=a.clone(),this.endpoint.clone=function(){return j.isString(a)?b(a,c):j.isArray(a)?(c=j.merge(a[
 1],c),b(a[0],c)):void 0}.bind(this),this.type=this.endpoint.type},this.setEndpoint(g.endpoint||h.Defaults.Endpoint||jsPlumb.Defaults.Endpoint||"Dot"),this.setPaintStyle(g.endpointStyle||g.paintStyle||g.style||h.Defaults.EndpointStyle||jsPlumb.Defaults.EndpointStyle,!0),this.setHoverPaintStyle(g.endpointHoverStyle||g.hoverPaintStyle||h.Defaults.EndpointHoverStyle||jsPlumb.Defaults.EndpointHoverStyle,!0),this._jsPlumb.paintStyleInUse=this.getPaintStyle(),jsPlumb.extend(this,g,d),this.isSource=g.isSource||!1,this.isTemporarySource=g.isTemporarySource||!1,this.isTarget=g.isTarget||!1,this._jsPlumb.maxConnections=g.maxConnections||h.Defaults.MaxConnections,this.canvas=this.endpoint.canvas,this.canvas._jsPlumb=this,this.addClass(h.endpointAnchorClassPrefix+"_"+this._jsPlumb.currentAnchorClass),jsPlumbAdapter.addClass(this.element,h.endpointAnchorClassPrefix+"_"+this._jsPlumb.currentAnchorClass),this.connections=g.connections||[],this.connectorPointerEvents=g["connector-pointer-events"],th
 is.scope=g.scope||h.getDefaultScope(),this.timestamp=null,this.reattachConnections=g.reattach||h.Defaults.ReattachConnections,this.connectionsDetachable=h.Defaults.ConnectionsDetachable,(g.connectionsDetachable===!1||g.detachable===!1)&&(this.connectionsDetachable=!1),this.dragAllowedWhenFull=g.dragAllowedWhenFull!==!1,g.onMaxConnections&&this.bind("maxConnections",g.onMaxConnections),this.addConnection=function(a){this.connections.push(a),this[(this.connections.length>0?"add":"remove")+"Class"](h.endpointConnectedClass),this[(this.isFull()?"add":"remove")+"Class"](h.endpointFullClass)},this.detachFromConnection=function(a,b,c){b=null==b?f(a,this):b,b>=0&&(this.connections.splice(b,1),this[(this.connections.length>0?"add":"remove")+"Class"](h.endpointConnectedClass),this[(this.isFull()?"add":"remove")+"Class"](h.endpointFullClass)),!c&&this._deleteOnDetach&&0===this.connections.length&&h.deleteObject({endpoint:this,fireEvent:!1,deleteAttachedObjects:!1})},this.detach=function(a,b,c,
 d,e,g,i){var j=null==i?f(a,this):i,k=!1;return d=d!==!1,j>=0&&(c||a._forceDetach||a.isDetachable()&&a.isDetachAllowed(a)&&this.isDetachAllowed(a)&&h.checkCondition("beforeDetach",a))&&(h.deleteObject({connection:a,fireEvent:!b&&d,originalEvent:e,deleteAttachedObjects:!1}),k=!0),k},this.detachAll=function(a,b){for(;this.connections.length>0;)this.detach(this.connections[0],!1,!0,a!==!1,b,this,0);return this},this.detachFrom=function(a,b,c){for(var d=[],e=0;e<this.connections.length;e++)(this.connections[e].endpoints[1]==a||this.connections[e].endpoints[0]==a)&&d.push(this.connections[e]);for(var f=0;f<d.length;f++)this.detach(d[f],!1,!0,b,c);return this},this.getElement=function(){return this.element},this.setElement=function(a){var b=this._jsPlumb.instance.getId(a),c=this.elementId;return j.removeWithFunction(g.endpointsByElement[this.elementId],function(a){return a.id==this.id}.bind(this)),this.element=jsPlumb.getDOMElement(a),this.elementId=h.getId(this.element),h.anchorManager.re
 homeEndpoint(this,c,this.element),h.dragManager.endpointAdded(this.element),j.addToList(g.endpointsByElement,b,this),this},this.makeInPlaceCopy=function(){var a=this.anchor.getCurrentLocation({element:this}),b=this.anchor.getOrientation(this),c=this.anchor.getCssClass(),d={bind:function(){},compute:function(){return[a[0],a[1]]},getCurrentLocation:function(){return[a[0],a[1]]},getOrientation:function(){return b},getCssClass:function(){return c}};return l({dropOptions:g.dropOptions,anchor:d,source:this.element,paintStyle:this.getPaintStyle(),endpoint:g.hideOnDrag?"Blank":this.endpoint,_transient:!0,scope:this.scope})},this.connectorSelector=function(){var a=this.connections[0];return this.isTarget&&a?a:this.connections.length<this._jsPlumb.maxConnections||-1==this._jsPlumb.maxConnections?null:a},this.setStyle=this.setPaintStyle,this.paint=function(a){a=a||{};var b=a.timestamp,c=!(a.recalc===!1);if(!b||this.timestamp!==b){var d=h.updateOffset({elId:this.elementId,timestamp:b}),f=a.offs
 et?a.offset.o:d.o;if(null!=f){var g=a.anchorPoint,i=a.connectorPaintStyle;if(null==g){var j=a.dimensions||d.s,k={xy:[f.left,f.top],wh:j,element:this,timestamp:b};if(c&&this.anchor.isDynamic&&this.connections.length>0){var l=e(this,a.elementWithPrecedence),m=l.endpoints[0]==this?1:0,n=0===m?l.sourceId:l.targetId,o=h.getCachedData(n),p=o.o,q=o.s;k.txy=[p.left,p.top],k.twh=q,k.tElement=l.endpoints[m]}g=this.anchor.compute(k)}this.endpoint.compute(g,this.anchor.getOrientation(this),this._jsPlumb.paintStyleInUse,i||this.paintStyleInUse),this.endpoint.paint(this._jsPlumb.paintStyleInUse,this.anchor),this.timestamp=b;for(var r=0;r<this._jsPlumb.overlays.length;r++){var s=this._jsPlumb.overlays[r];s.isVisible()&&(this._jsPlumb.overlayPlacements[r]=s.draw(this.endpoint,this._jsPlumb.paintStyleInUse),s.paint(this._jsPlumb.overlayPlacements[r]))}}}},this.repain

<TRUNCATED>

[6/8] stratos git commit: jsPlumb lib added to application editor

Posted by im...@apache.org.
jsPlumb lib added to application editor


Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/f72d80fd
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/f72d80fd
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/f72d80fd

Branch: refs/heads/4.1.0-test
Commit: f72d80fdca56a840ff1d7dec157944326483df76
Parents: 5150a8b
Author: Dakshika Jayathilaka <si...@gmail.com>
Authored: Thu Dec 11 23:32:22 2014 +0530
Committer: Imesh Gunaratne <im...@apache.org>
Committed: Sat Dec 13 09:45:24 2014 +0530

----------------------------------------------------------------------
 .../themes/theme0/js/jsplumb-1.7.2/dom.jsPlumb-1.7.2-min.js    | 6 ++++++
 1 file changed, 6 insertions(+)
----------------------------------------------------------------------