


var ActiveMQ;
(function (ActiveMQ) {
    ActiveMQ.log = Logger.get("activemq");
    function getSelectionQueuesFolder(workspace) {
        function findQueuesFolder(node) {
            if (node) {
                if (node.title === "Queues" || node.title === "Queue") {
                    return node;
                }
                var parent = node.parent;
                if (parent) {
                    return findQueuesFolder(parent);
                }
            }
            return null;
        }
        var selection = workspace.selection;
        if (selection) {
            return findQueuesFolder(selection);
        }
        return null;
    }
    ActiveMQ.getSelectionQueuesFolder = getSelectionQueuesFolder;
    function getSelectionTopicsFolder(workspace) {
        function findTopicsFolder(node) {
            var answer = null;
            if (node) {
                if (node.title === "Topics" || node.title === "Topic") {
                    answer = node;
                }
                if (answer === null) {
                    angular.forEach(node.children, function (child) {
                        if (child.title === "Topics" || child.title === "Topic") {
                            answer = child;
                        }
                    });
                }
            }
            return answer;
        }
        var selection = workspace.selection;
        if (selection) {
            return findTopicsFolder(selection);
        }
        return null;
    }
    ActiveMQ.getSelectionTopicsFolder = getSelectionTopicsFolder;
})(ActiveMQ || (ActiveMQ = {}));
var ActiveMQ;
(function (ActiveMQ) {
    var pluginName = 'activemq';
    var jmxDomain = 'org.apache.activemq';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'ui.bootstrap.dialog', 
        'hawtioCore', 
        'camel', 
        'hawtio-ui'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/activemq/browseQueue', {
            templateUrl: 'app/activemq/html/browseQueue.html'
        }).when('/activemq/subscribers', {
            templateUrl: 'app/activemq/html/subscribers.html'
        }).when('/activemq/createDestination', {
            templateUrl: 'app/activemq/html/createDestination.html'
        }).when('/activemq/createQueue', {
            templateUrl: 'app/activemq/html/createQueue.html'
        }).when('/activemq/createTopic', {
            templateUrl: 'app/activemq/html/createTopic.html'
        }).when('/activemq/deleteQueue', {
            templateUrl: 'app/activemq/html/deleteQueue.html'
        }).when('/activemq/deleteTopic', {
            templateUrl: 'app/activemq/html/deleteTopic.html'
        }).when('/activemq/sendMessage', {
            templateUrl: 'app/camel/html/sendMessage.html'
        }).when('/activemq/durableSubscribers', {
            templateUrl: 'app/activemq/html/durableSubscribers.html'
        }).when('/activemq/jobs', {
            templateUrl: 'app/activemq/html/jobs.html'
        });
    }).run(function ($location, workspace, viewRegistry, helpRegistry) {
        viewRegistry['activemq'] = 'app/activemq/html/layoutActiveMQTree.html';
        helpRegistry.addUserDoc('activemq', 'app/activemq/doc/help.md', function () {
            return workspace.treeContainsDomainAndProperties("org.apache.activemq");
        });
        workspace.addTreePostProcessor(postProcessTree);
        var attributes = workspace.attributeColumnDefs;
        attributes[jmxDomain + "/Broker/folder"] = [
            {
                field: 'BrokerName',
                displayName: 'Name',
                width: "**"
            }, 
            {
                field: 'TotalProducerCount',
                displayName: 'Producer #'
            }, 
            {
                field: 'TotalConsumerCount',
                displayName: 'Consumer #'
            }, 
            {
                field: 'StorePercentUsage',
                displayName: 'Store %'
            }, 
            {
                field: 'TempPercentUsage',
                displayName: 'Temp %'
            }, 
            {
                field: 'MemoryPercentUsage',
                displayName: 'Memory %'
            }, 
            {
                field: 'TotalEnqueueCount',
                displayName: 'Enqueue #'
            }, 
            {
                field: 'TotalDequeueCount',
                displayName: 'Dequeue #'
            }
        ];
        attributes[jmxDomain + "/Queue/folder"] = [
            {
                field: 'Name',
                displayName: 'Name',
                width: "***"
            }, 
            {
                field: 'QueueSize',
                displayName: 'Queue Size'
            }, 
            {
                field: 'ProducerCount',
                displayName: 'Producer #'
            }, 
            {
                field: 'ConsumerCount',
                displayName: 'Consumer #'
            }, 
            {
                field: 'EnqueueCount',
                displayName: 'Enqueue #'
            }, 
            {
                field: 'DequeueCount',
                displayName: 'Dequeue #'
            }, 
            {
                field: 'MemoryPercentUsage',
                displayName: 'Memory %'
            }, 
            {
                field: 'DispatchCount',
                displayName: 'Dispatch #',
                visible: false
            }
        ];
        attributes[jmxDomain + "/Topic/folder"] = [
            {
                field: 'Name',
                displayName: 'Name',
                width: "****"
            }, 
            {
                field: 'ProducerCount',
                displayName: 'Producer #'
            }, 
            {
                field: 'ConsumerCount',
                displayName: 'Consumer #'
            }, 
            {
                field: 'EnqueueCount',
                displayName: 'Enqueue #'
            }, 
            {
                field: 'DequeueCount',
                displayName: 'Dequeue #'
            }, 
            {
                field: 'MemoryPercentUsage',
                displayName: 'Memory %'
            }, 
            {
                field: 'DispatchCount',
                displayName: 'Dispatch #',
                visible: false
            }
        ];
        attributes[jmxDomain + "/Consumer/folder"] = [
            {
                field: 'ConnectionId',
                displayName: 'Name',
                width: "**"
            }, 
            {
                field: 'PrefetchSize',
                displayName: 'Prefetch Size'
            }, 
            {
                field: 'Priority',
                displayName: 'Priority'
            }, 
            {
                field: 'DispatchedQueueSize',
                displayName: 'Dispatched Queue #'
            }, 
            {
                field: 'SlowConsumer',
                displayName: 'Slow ?'
            }, 
            {
                field: 'Retroactive',
                displayName: 'Retroactive'
            }, 
            {
                field: 'Selector',
                displayName: 'Selector'
            }
        ];
        attributes[jmxDomain + "/networkConnectors/folder"] = [
            {
                field: 'Name',
                displayName: 'Name',
                width: "**"
            }, 
            {
                field: 'UserName',
                displayName: 'User Name'
            }, 
            {
                field: 'PrefetchSize',
                displayName: 'Prefetch Size'
            }, 
            {
                field: 'ConduitSubscriptions',
                displayName: 'Conduit Subscriptions?'
            }, 
            {
                field: 'Duplex',
                displayName: 'Duplex'
            }, 
            {
                field: 'DynamicOnly',
                displayName: 'Dynamic Only'
            }
        ];
        attributes[jmxDomain + "/PersistenceAdapter/folder"] = [
            {
                field: 'IndexDirectory',
                displayName: 'Index Directory',
                width: "**"
            }, 
            {
                field: 'LogDirectory',
                displayName: 'Log Directory',
                width: "**"
            }
        ];
        workspace.topLevelTabs.push({
            id: "activemq",
            content: "ActiveMQ",
            title: "Manage your ActiveMQ message brokers",
            isValid: function (workspace) {
                return workspace.treeContainsDomainAndProperties("org.apache.activemq");
            },
            href: function () {
                return "#/jmx/attributes?tab=activemq";
            },
            isActive: function () {
                return workspace.isTopTabActive("activemq");
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-envelope"></i> Browse',
            title: "Browse the messages on the queue",
            isValid: function (workspace) {
                return isQueue(workspace);
            },
            href: function () {
                return "#/activemq/browseQueue";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-pencil"></i> Send',
            title: "Send a message to this destination",
            isValid: function (workspace) {
                return isQueue(workspace) || isTopic(workspace);
            },
            href: function () {
                return "#/activemq/sendMessage";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-picture"></i> Diagram',
            title: "View a diagram of the producers, destinations and consumers",
            isValid: function (workspace) {
                return isActiveMQFolder(workspace);
            },
            href: function () {
                return "#/activemq/subscribers";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-plus"></i> Create',
            title: "Create a new destination",
            isValid: function (workspace) {
                return isBroker(workspace);
            },
            href: function () {
                return "#/activemq/createDestination";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-plus"></i> Create',
            title: "Create a new queue",
            isValid: function (workspace) {
                return isQueuesFolder(workspace);
            },
            href: function () {
                return "#/activemq/createQueue";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-plus"></i> Create',
            title: "Create a new topic",
            isValid: function (workspace) {
                return isTopicsFolder(workspace);
            },
            href: function () {
                return "#/activemq/createTopic";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-remove"></i> Delete Topic',
            title: "Delete this topic",
            isValid: function (workspace) {
                return isTopic(workspace);
            },
            href: function () {
                return "#/activemq/deleteTopic";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-remove"></i> Delete',
            title: "Delete or purge this queue",
            isValid: function (workspace) {
                return isQueue(workspace);
            },
            href: function () {
                return "#/activemq/deleteQueue";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-list"></i> Durable Subscribers',
            title: "Manage durable subscribers",
            isValid: function (workspace) {
                return isBroker(workspace);
            },
            href: function () {
                return "#/activemq/durableSubscribers";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-list"></i> Jobs',
            title: "Manage jobs",
            isValid: function (workspace) {
                return isJobScheduler(workspace);
            },
            href: function () {
                return "#/activemq/jobs";
            }
        });
        function postProcessTree(tree) {
            var activemq = tree.get("org.apache.activemq");
            setConsumerType(activemq);
            if (activemq) {
                angular.forEach(activemq.children, function (broker) {
                    angular.forEach(broker.children, function (child) {
                        var grandChildren = child.children;
                        if (grandChildren) {
                            var names = [
                                "Topic", 
                                "Queue"
                            ];
                            angular.forEach(names, function (name) {
                                var idx = grandChildren.findIndex(function (n) {
                                    return n.title === name;
                                });
                                if (idx > 0) {
                                    var old = grandChildren[idx];
                                    grandChildren.splice(idx, 1);
                                    grandChildren.splice(0, 0, old);
                                }
                            });
                        }
                    });
                });
            }
        }
        function setConsumerType(node) {
            if (node) {
                var parent = node.parent;
                var entries = node.entries;
                if (parent && !parent.typeName && entries) {
                    var endpoint = entries["endpoint"];
                    if (endpoint === "Consumer" || endpoint === "Producer") {
                        parent.typeName = endpoint;
                    }
                    var connectorName = entries["connectorName"];
                    if (connectorName && !node.icon) {
                        node.icon = url("/app/activemq/img/connector.png");
                    }
                }
                angular.forEach(node.children, function (child) {
                    return setConsumerType(child);
                });
            }
        }
    });
    hawtioPluginLoader.addModule(pluginName);
    function isQueue(workspace) {
        return workspace.hasDomainAndProperties(jmxDomain, {
            'destinationType': 'Queue'
        }, 4) || workspace.selectionHasDomainAndType(jmxDomain, 'Queue');
    }
    ActiveMQ.isQueue = isQueue;
    function isTopic(workspace) {
        return workspace.hasDomainAndProperties(jmxDomain, {
            'destinationType': 'Topic'
        }, 4) || workspace.selectionHasDomainAndType(jmxDomain, 'Topic');
    }
    ActiveMQ.isTopic = isTopic;
    function isQueuesFolder(workspace) {
        return workspace.selectionHasDomainAndLastFolderName(jmxDomain, 'Queue');
    }
    ActiveMQ.isQueuesFolder = isQueuesFolder;
    function isTopicsFolder(workspace) {
        return workspace.selectionHasDomainAndLastFolderName(jmxDomain, 'Topic');
    }
    ActiveMQ.isTopicsFolder = isTopicsFolder;
    function isJobScheduler(workspace) {
        return workspace.hasDomainAndProperties(jmxDomain, {
            'service': 'JobScheduler'
        }, 4);
    }
    ActiveMQ.isJobScheduler = isJobScheduler;
    function isBroker(workspace) {
        if (workspace.selectionHasDomainAndType(jmxDomain, 'Broker')) {
            var parent = workspace.selection.parent;
            return !(parent && parent.ancestorHasType('Broker'));
        }
        return false;
    }
    ActiveMQ.isBroker = isBroker;
    function isActiveMQFolder(workspace) {
        return workspace.hasDomainAndProperties(jmxDomain);
    }
    ActiveMQ.isActiveMQFolder = isActiveMQFolder;
})(ActiveMQ || (ActiveMQ = {}));
var ActiveMQ;
(function (ActiveMQ) {
    function BrowseQueueController($scope, workspace, jolokia) {
        $scope.searchText = '';
        $scope.messages = [];
        $scope.headers = {};
        $scope.mode = 'text';
        $scope.deleteDialog = false;
        $scope.moveDialog = false;
        $scope.gridOptions = {
            selectedItems: [],
            data: 'messages',
            displayFooter: false,
            showFilter: false,
            showColumnMenu: true,
            enableColumnResize: true,
            enableColumnReordering: true,
            filterOptions: {
                filterText: ''
            },
            selectWithCheckboxOnly: true,
            showSelectionCheckbox: true,
            maintainColumnRatios: false,
            columnDefs: [
                {
                    field: 'JMSMessageID',
                    displayName: 'Message ID',
                    cellTemplate: '<div class="ngCellText"><a ng-click="openMessageDialog(row)">{{row.entity.JMSMessageID}}</a></div>',
                    width: '34%'
                }, 
                {
                    field: 'JMSType',
                    displayName: 'Type',
                    width: '10%'
                }, 
                {
                    field: 'JMSPriority',
                    displayName: 'Priority',
                    width: '7%'
                }, 
                {
                    field: 'JMSTimestamp',
                    displayName: 'Timestamp',
                    width: '19%'
                }, 
                {
                    field: 'JMSExpiration',
                    displayName: 'Expires',
                    width: '10%'
                }, 
                {
                    field: 'JMSReplyTo',
                    displayName: 'Reply To',
                    width: '10%'
                }, 
                {
                    field: 'JMSCorrelationID',
                    displayName: 'Correlation ID',
                    width: '10%'
                }
            ]
        };
        $scope.showMessageDetails = false;
        var ignoreColumns = [
            "PropertiesText", 
            "BodyPreview", 
            "Text"
        ];
        var flattenColumns = [
            "BooleanProperties", 
            "ByteProperties", 
            "ShortProperties", 
            "IntProperties", 
            "LongProperties", 
            "FloatProperties", 
            "DoubleProperties", 
            "StringProperties"
        ];
        $scope.$watch('workspace.selection', function () {
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            setTimeout(loadTable, 50);
        });
        $scope.openMessageDialog = function (message) {
            var idx = Core.pathGet(message, [
                "rowIndex"
            ]);
            $scope.selectRowIndex(idx);
            if ($scope.row) {
                $scope.mode = CodeEditor.detectTextFormat($scope.row.Text);
                $scope.showMessageDetails = true;
            }
        };
        $scope.refresh = loadTable;
        $scope.selectRowIndex = function (idx) {
            $scope.rowIndex = idx;
            var selected = $scope.gridOptions.selectedItems;
            selected.splice(0, selected.length);
            if (idx >= 0 && idx < $scope.messages.length) {
                $scope.row = $scope.messages[idx];
                if ($scope.row) {
                    selected.push($scope.row);
                }
            } else {
                $scope.row = null;
            }
        };
        $scope.moveMessages = function () {
            var selection = workspace.selection;
            var mbean = selection.objectName;
            if (mbean && selection) {
                var selectedItems = $scope.gridOptions.selectedItems;
                $scope.message = "Moved " + Core.maybePlural(selectedItems.length, "message" + " to " + $scope.queueName);
                var operation = "moveMessageTo(java.lang.String, java.lang.String)";
                angular.forEach(selectedItems, function (item, idx) {
                    var id = item.JMSMessageID;
                    if (id) {
                        var callback = (idx + 1 < selectedItems.length) ? intermediateResult : moveSuccess;
                        jolokia.execute(mbean, operation, id, $scope.queueName, onSuccess(callback));
                    }
                });
            }
        };
        $scope.deleteMessages = function () {
            var selection = workspace.selection;
            var mbean = selection.objectName;
            if (mbean && selection) {
                var selectedItems = $scope.gridOptions.selectedItems;
                $scope.message = "Deleted " + Core.maybePlural(selectedItems.length, "message");
                var operation = "removeMessage(java.lang.String)";
                angular.forEach(selectedItems, function (item, idx) {
                    var id = item.JMSMessageID;
                    if (id) {
                        var callback = (idx + 1 < selectedItems.length) ? intermediateResult : operationSuccess;
                        jolokia.execute(mbean, operation, id, onSuccess(callback));
                    }
                });
            }
        };
        $scope.retryMessages = function () {
            var selection = workspace.selection;
            var mbean = selection.objectName;
            if (mbean && selection) {
                var selectedItems = $scope.gridOptions.selectedItems;
                $scope.message = "Retry " + Core.maybePlural(selectedItems.length, "message");
                var operation = "retryMessage(java.lang.String)";
                angular.forEach(selectedItems, function (item, idx) {
                    var id = item.JMSMessageID;
                    if (id) {
                        var callback = (idx + 1 < selectedItems.length) ? intermediateResult : operationSuccess;
                        jolokia.execute(mbean, operation, id, onSuccess(callback));
                    }
                });
            }
        };
        $scope.queueNames = function (completionText) {
            var queuesFolder = ActiveMQ.getSelectionQueuesFolder(workspace);
            return (queuesFolder) ? queuesFolder.children.map(function (n) {
                return n.title;
            }) : [];
        };
        function populateTable(response) {
            var data = response.value;
            if (!angular.isArray(data)) {
                $scope.messages = [];
                angular.forEach(data, function (value, idx) {
                    $scope.messages.push(value);
                });
            } else {
                $scope.messages = data;
            }
            angular.forEach($scope.messages, function (message) {
                message.headerHtml = createHeaderHtml(message);
            });
            Core.$apply($scope);
        }
        function createHeaderHtml(message) {
            var headers = createHeaders(message);
            var properties = createProperties(message);
            var headerKeys = Object.extended(headers).keys();
            function sort(a, b) {
                if (a > b) {
                    return 1;
                }
                if (a < b) {
                    return -1;
                }
                return 0;
            }
            var propertiesKeys = Object.extended(properties).keys().sort(sort);
            var jmsHeaders = headerKeys.filter(function (key) {
                return key.startsWith("JMS");
            }).sort(sort);
            var remaining = headerKeys.subtract(jmsHeaders, propertiesKeys).sort(sort);
            var buffer = [];
            function appendHeader(key) {
                var value = headers[key];
                if (value === null) {
                    value = '';
                }
                buffer.push('<tr><td class="propertyName"><span class="green">Header</span> - ' + key + '</td><td class="property-value">' + value + '</td></tr>');
            }
            function appendProperty(key) {
                var value = properties[key];
                if (value === null) {
                    value = '';
                }
                buffer.push('<tr><td class="propertyName">' + key + '</td><td class="property-value">' + value + '</td></tr>');
            }
            jmsHeaders.forEach(appendHeader);
            remaining.forEach(appendHeader);
            propertiesKeys.forEach(appendProperty);
            return buffer.join("\n");
        }
        function createHeaders(row) {
            ActiveMQ.log.debug("headers: ", row);
            var answer = {};
            angular.forEach(row, function (value, key) {
                if (!ignoreColumns.any(key) && !flattenColumns.any(key)) {
                    answer[key] = value;
                }
            });
            return answer;
        }
        function createProperties(row) {
            ActiveMQ.log.debug("properties: ", row);
            var answer = {};
            angular.forEach(row, function (value, key) {
                if (!ignoreColumns.any(key) && flattenColumns.any(key)) {
                    angular.forEach(value, function (v2, k2) {
                        answer['<span class="green">' + key.replace('Properties', ' Property') + '</span> - ' + k2] = v2;
                    });
                }
            });
            return answer;
        }
        function loadTable() {
            var selection = workspace.selection;
            if (selection) {
                var mbean = selection.objectName;
                if (mbean) {
                    $scope.dlq = false;
                    jolokia.getAttribute(mbean, "DLQ", onSuccess(onDlq, {
                        silent: true
                    }));
                    jolokia.request({
                        type: 'exec',
                        mbean: mbean,
                        operation: 'browse()'
                    }, onSuccess(populateTable));
                }
            }
        }
        function onDlq(response) {
            $scope.dlq = response;
            Core.$apply($scope);
        }
        function intermediateResult() {
        }
        function operationSuccess() {
            $scope.messageDialog = false;
            $scope.gridOptions.selectedItems.splice(0);
            notification("success", $scope.message);
            setTimeout(loadTable, 50);
        }
        function moveSuccess() {
            operationSuccess();
            workspace.loadTree();
        }
    }
    ActiveMQ.BrowseQueueController = BrowseQueueController;
})(ActiveMQ || (ActiveMQ = {}));
var ActiveMQ;
(function (ActiveMQ) {
    function DestinationController($scope, workspace, jolokia) {
        $scope.workspace = workspace;
        $scope.message = "";
        $scope.queueType = 'true';
        $scope.deleteDialog = false;
        $scope.purgeDialog = false;
        updateQueueType();
        function updateQueueType() {
            $scope.destinationTypeName = $scope.queueType ? "Queue" : "Topic";
        }
        $scope.$watch('queueType', function () {
            updateQueueType();
        });
        $scope.$watch('workspace.selection', function () {
            workspace.moveIfViewInvalid();
        });
        function operationSuccess() {
            $scope.destinationName = "";
            $scope.workspace.operationCounter += 1;
            Core.$apply($scope);
            notification("success", $scope.message);
            $scope.workspace.loadTree();
        }
        function deleteSuccess() {
            workspace.removeAndSelectParentNode();
            $scope.workspace.operationCounter += 1;
            Core.$apply($scope);
            notification("success", $scope.message);
            $scope.workspace.loadTree();
        }
        function getBrokerMBean(jolokia) {
            var mbean = null;
            var selection = workspace.selection;
            if (selection && ActiveMQ.isBroker(workspace) && selection.objectName) {
                return selection.objectName;
            }
            var folderNames = selection.folderNames;
            var parent = selection ? selection.parent : null;
            if (selection && parent && jolokia && folderNames && folderNames.length > 1) {
                mbean = parent.objectName;
                if (!mbean && parent) {
                    mbean = parent.parent.objectName;
                }
                if (!mbean) {
                    mbean = "" + folderNames[0] + ":BrokerName=" + folderNames[1] + ",Type=Broker";
                }
            }
            return mbean;
        }
        $scope.createDestination = function (name, isQueue) {
            var mbean = getBrokerMBean(jolokia);
            if (mbean) {
                var operation;
                if (isQueue) {
                    operation = "addQueue(java.lang.String)";
                    $scope.message = "Created queue " + name;
                } else {
                    operation = "addTopic(java.lang.String)";
                    $scope.message = "Created topic " + name;
                }
                if (mbean) {
                    jolokia.execute(mbean, operation, name, onSuccess(operationSuccess));
                } else {
                    notification("error", "Could not find the Broker MBean!");
                }
            }
        };
        $scope.deleteDestination = function () {
            var mbean = getBrokerMBean(jolokia);
            var selection = workspace.selection;
            var entries = selection.entries;
            if (mbean && selection && jolokia && entries) {
                var domain = selection.domain;
                var name = entries["Destination"] || entries["destinationName"] || selection.title;
                var isQueue = "Topic" !== (entries["Type"] || entries["destinationType"]);
                var operation;
                if (isQueue) {
                    operation = "removeQueue(java.lang.String)";
                    $scope.message = "Deleted queue " + name;
                } else {
                    operation = "removeTopic(java.lang.String)";
                    $scope.message = "Deleted topic " + name;
                }
                jolokia.execute(mbean, operation, name, onSuccess(deleteSuccess));
            }
        };
        $scope.purgeDestination = function () {
            var mbean = workspace.getSelectedMBeanName();
            var selection = workspace.selection;
            var entries = selection.entries;
            if (mbean && selection && jolokia && entries) {
                var name = entries["Destination"] || entries["destinationName"] || selection.title;
                var operation = "purge()";
                $scope.message = "Purged queue " + name;
                jolokia.execute(mbean, operation, onSuccess(operationSuccess));
            }
        };
        $scope.name = function () {
            var selection = workspace.selection;
            if (selection) {
                return selection.title;
            }
            return null;
        };
    }
    ActiveMQ.DestinationController = DestinationController;
})(ActiveMQ || (ActiveMQ = {}));
var ActiveMQ;
(function (ActiveMQ) {
    function DurableSubscriberController($scope, workspace, jolokia) {
        $scope.refresh = loadTable;
        $scope.durableSubscribers = [];
        $scope.tempData = [];
        $scope.createSubscriberDialog = new Core.Dialog();
        $scope.deleteSubscriberDialog = new Core.Dialog();
        $scope.showSubscriberDialog = new Core.Dialog();
        $scope.topicName = '';
        $scope.clientId = '';
        $scope.subscriberName = '';
        $scope.subSelector = '';
        $scope.gridOptions = {
            selectedItems: [],
            data: 'durableSubscribers',
            displayFooter: false,
            showFilter: false,
            showColumnMenu: true,
            enableCellSelection: false,
            enableColumnResize: true,
            enableColumnReordering: true,
            selectWithCheckboxOnly: false,
            showSelectionCheckbox: false,
            multiSelect: false,
            displaySelectionCheckbox: false,
            filterOptions: {
                filterText: ''
            },
            maintainColumnRatios: false,
            columnDefs: [
                {
                    field: 'destinationName',
                    displayName: 'Topic',
                    width: '30%'
                }, 
                {
                    field: 'clientId',
                    displayName: 'Client ID',
                    width: '30%'
                }, 
                {
                    field: 'consumerId',
                    displayName: 'Consumer ID',
                    cellTemplate: '<div class="ngCellText"><a ng-click="openSubscriberDialog(row)">{{row.entity.consumerId}}</a></div>',
                    width: '30%'
                }, 
                {
                    field: 'status',
                    displayName: 'Status',
                    width: '10%'
                }
            ]
        };
        $scope.doCreateSubscriber = function (clientId, subscriberName, topicName, subSelector) {
            $scope.createSubscriberDialog.close();
            $scope.clientId = clientId;
            $scope.subscriberName = subscriberName;
            $scope.topicName = topicName;
            $scope.subSelector = subSelector;
            var mbean = getBrokerMBean(jolokia);
            if (mbean) {
                jolokia.execute(mbean, "createDurableSubscriber(java.lang.String, java.lang.String, java.lang.String, java.lang.String)", $scope.clientId, $scope.subscriberName, $scope.topicName, $scope.subSelector, onSuccess(function () {
                    notification('success', "Created durable subscriber " + clientId);
                    $scope.clientId = '';
                    $scope.subscriberName = '';
                    $scope.topicName = '';
                    $scope.subSelector = '';
                    loadTable();
                }));
            } else {
                notification("error", "Could not find the Broker MBean!");
            }
        };
        $scope.deleteSubscribers = function () {
            var mbean = getBrokerMBean(jolokia);
            if (mbean) {
                jolokia.execute(mbean, "destroyDurableSubscriber(java.lang.String, java.lang.String)", $scope.showSubscriberDialog.subscriber.ClientId, $scope.showSubscriberDialog.subscriber.SubscriptionName, onSuccess(function () {
                    $scope.showSubscriberDialog.close();
                    notification('success', "Deleted durable subscriber");
                    loadTable();
                }));
            } else {
                notification("error", "Could not find the Broker MBean!");
            }
        };
        $scope.openSubscriberDialog = function (subscriber) {
            jolokia.request({
                type: "read",
                mbean: subscriber.entity._id
            }, onSuccess(function (response) {
                $scope.showSubscriberDialog.subscriber = response.value;
                $scope.showSubscriberDialog.subscriber.Status = subscriber.entity.status;
                console.log("Subscriber is now " + $scope.showSubscriberDialog.subscriber);
                Core.$apply($scope);
                setTimeout(function () {
                    $scope.showSubscriberDialog.open();
                    Core.$apply($scope);
                }, 100);
            }));
        };
        $scope.topicNames = function (completionText) {
            var topicsFolder = ActiveMQ.getSelectionTopicsFolder(workspace);
            return (topicsFolder) ? topicsFolder.children.map(function (n) {
                return n.title;
            }) : [];
        };
        $scope.$watch('workspace.selection', function () {
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            setTimeout(loadTable, 50);
        });
        function loadTable() {
            var mbean = getBrokerMBean(jolokia);
            if (mbean) {
                $scope.durableSubscribers = [];
                jolokia.request({
                    type: "read",
                    mbean: mbean,
                    attribute: [
                        "DurableTopicSubscribers"
                    ]
                }, onSuccess(function (response) {
                    return populateTable(response, "DurableTopicSubscribers", "Active");
                }));
                jolokia.request({
                    type: "read",
                    mbean: mbean,
                    attribute: [
                        "InactiveDurableTopicSubscribers"
                    ]
                }, onSuccess(function (response) {
                    return populateTable(response, "InactiveDurableTopicSubscribers", "Offline");
                }));
            }
        }
        function populateTable(response, attr, status) {
            var data = response.value;
            $scope.durableSubscribers.push.apply($scope.durableSubscribers, data[attr].map(function (o) {
                var objectName = o["objectName"];
                var entries = Core.objectNameProperties(objectName);
                entries["_id"] = objectName;
                entries["status"] = status;
                return entries;
            }));
            Core.$apply($scope);
        }
        function getBrokerMBean(jolokia) {
            var mbean = null;
            var selection = workspace.selection;
            if (selection && ActiveMQ.isBroker(workspace) && selection.objectName) {
                return selection.objectName;
            }
            var folderNames = selection.folderNames;
            var parent = selection ? selection.parent : null;
            if (selection && parent && jolokia && folderNames && folderNames.length > 1) {
                mbean = parent.objectName;
                if (!mbean && parent) {
                    mbean = parent.parent.objectName;
                }
                if (!mbean) {
                    mbean = "" + folderNames[0] + ":BrokerName=" + folderNames[1] + ",Type=Broker";
                }
            }
            return mbean;
        }
    }
    ActiveMQ.DurableSubscriberController = DurableSubscriberController;
})(ActiveMQ || (ActiveMQ = {}));
var ActiveMQ;
(function (ActiveMQ) {
    function SubscriberGraphController($scope, $element, $timeout, workspace, jolokia) {
        $scope.nodes = [];
        $scope.links = [];
        $scope.queues = {};
        $scope.topics = {};
        $scope.subscriptions = {};
        $scope.producers = {};
        $scope.networks = {};
        $scope.parentHeight = 0;
        $scope.parentWidth = 0;
        $scope.updateGraph = function () {
            var canvas = $("#canvas");
            var parent = canvas.parent();
            var parentWidth = parent.width();
            var parentHeight = parent.height();
            var canvasWidth = canvas.width();
            var canvasHeight = canvas.height();
            if ((canvasHeight !== parentHeight || canvasWidth !== parentWidth) && (canvasHeight != $scope.lastCanvasHeight || canvasWidth != $scope.lastCanvasWidth) && workspace.selection && $scope.nodes.length) {
                console.log("force resize");
                layoutGraph();
            }
        };
        $scope.$watch($scope.updateGraph);
        $scope.$watch('workspace.selection', function (newValue) {
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            $timeout(reloadData, 50);
        });
        function reloadData() {
            var selection = workspace.selection;
            console.log("loading graph data for selection " + selection);
            $scope.nodes = [];
            $scope.links = [];
            var isQueue = false;
            var isTopic = false;
            if (jolokia && selection) {
                $scope.selectionDestinationName = null;
                var typeName = nodeTypeName(selection);
                if (typeName) {
                    isQueue = typeName === "Queue";
                    isTopic = typeName === "Topic";
                }
                $scope.selectionDestinationName = selection.entries["Destination"] || selection.title;
                $scope.isQueue = isQueue;
                $scope.isTopic = isTopic;
                if (!typeName) {
                    if (isQueue) {
                        typeName = "Queue";
                    } else {
                        typeName = "Topic";
                    }
                }
                var options = {};
                var brokerFolder = findBrokerFolder(selection);
                if (isQueue || isTopic) {
                    var children = selection.children;
                    if (children && children.length) {
                        var consumerFolder = children[0];
                        loadConsumers(true, isQueue, $scope.selectionDestinationName, consumerFolder.children);
                    }
                    if (brokerFolder) {
                        angular.forEach(brokerFolder.children, function (childFolder) {
                            var title = (childFolder.title || "").toLowerCase();
                            if (title.indexOf("producer") >= 0) {
                                loadProducers(isQueue, $scope.selectionDestinationName, childFolder.children);
                            } else if (title.indexOf("subscription") >= 0) {
                                loadConsumers(false, isQueue, $scope.selectionDestinationName, childFolder.children);
                            }
                        });
                    }
                } else {
                    if (brokerFolder) {
                        angular.forEach(brokerFolder.children, function (childFolder) {
                            var title = (childFolder.title || "").toLowerCase();
                            if (title.indexOf("network") >= 0) {
                                loadNetworkConnectors(childFolder.children);
                            }
                        });
                    }
                }
                layoutGraph();
            }
        }
        function loadConsumers(childOfDestination, isQueue, destinationName, folderArray) {
            Core.forEachLeafFolder(folderArray, function (folder) {
                var id = null;
                var valid = childOfDestination;
                if (!childOfDestination) {
                    var mbean = folder.objectName;
                    if (mbean) {
                        var response = jolokia.request({
                            type: 'read',
                            mbean: mbean
                        }, onSuccess(null));
                        var answer = response.value;
                        var destinationNameAttribute = answer["DestinationName"];
                        var queueConsumer = answer["DestinationQueue"];
                        if (queueConsumer === isQueue && matchesSelection(destinationNameAttribute)) {
                            valid = true;
                        }
                    }
                }
                var entries = folder.entries;
                if (valid && entries) {
                    var subscriptionKey = entries["consumerId"] || entries["connectionId"] || entries["subcriptionId"];
                    if (subscriptionKey) {
                        if (isQueue) {
                            id = getOrCreate($scope.queues, destinationName, {
                                label: destinationName,
                                imageUrl: url("/app/activemq/img/queue.png")
                            });
                        } else {
                            id = getOrCreate($scope.topics, destinationName, {
                                label: destinationName,
                                imageUrl: url("/app/activemq/img/topic.png")
                            });
                        }
                        var subscriptionId = getOrCreate($scope.subscriptions, subscriptionKey, {
                            label: subscriptionKey,
                            imageUrl: url("/app/activemq/img/listener.gif")
                        });
                        $scope.links.push({
                            source: id,
                            target: subscriptionId
                        });
                    }
                }
            });
        }
        function loadProducers(queueProducers, destinationName, folderArray) {
            Core.forEachLeafFolder(folderArray, function (folder) {
                var entries = folder.entries;
                if (entries) {
                    var producerDestinationName = entries["destinationName"] || entries["DestinationName"];
                    if (!producerDestinationName) {
                        var mbean = folder.objectName;
                        if (mbean) {
                            var response = jolokia.request({
                                type: 'read',
                                mbean: mbean
                            }, onSuccess(null));
                            var answer = response.value;
                            var destinationNameAttribute = answer["DestinationName"];
                            var isQueue = answer["DestinationQueue"];
                            if (queueProducers !== isQueue) {
                            } else if (matchesSelection(destinationNameAttribute)) {
                                loadProducer(queueProducers, destinationName, folder);
                            }
                        }
                    } else if (matchesSelection(producerDestinationName)) {
                        loadProducer(queueProducers, destinationName, folder);
                    }
                }
            });
        }
        function loadProducer(isQueue, destinationName, folder) {
            var entries = folder ? folder.entries : null;
            if (entries) {
                var id = null;
                if (isQueue) {
                    id = getOrCreate($scope.queues, destinationName, {
                        label: destinationName,
                        imageUrl: url("/app/activemq/img/queue.png")
                    });
                } else {
                    id = getOrCreate($scope.topics, destinationName, {
                        label: destinationName,
                        imageUrl: url("/app/activemq/img/topic.png")
                    });
                }
                var producerKey = entries["producerId"] || entries["connectionId"];
                var producerId = getOrCreate($scope.producers, producerKey, {
                    label: producerKey,
                    imageUrl: url("/app/activemq/img/sender.gif")
                });
                $scope.links.push({
                    source: producerId,
                    target: id
                });
            }
        }
        function loadNetworkConnectors(folderArray) {
            Core.forEachLeafFolder(folderArray, function (folder) {
                var mbean = folder.objectName;
                if (mbean) {
                    var response = jolokia.request({
                        type: 'read',
                        mbean: mbean
                    }, onSuccess(null));
                    var answer = response.value;
                    if (answer) {
                        var localBrokerName = answer["LocalBrokerName"];
                        var remoteBrokerName = answer["RemoteBrokerName"];
                        if (localBrokerName && remoteBrokerName) {
                            var localId = getOrCreate($scope.networks, localBrokerName, {
                                label: localBrokerName,
                                imageUrl: url("/app/activemq/img/message_broker.png")
                            });
                            var remoteId = getOrCreate($scope.networks, remoteBrokerName, {
                                label: remoteBrokerName,
                                imageUrl: url("/app/activemq/img/message_broker.png")
                            });
                            $scope.links.push({
                                source: localId,
                                target: remoteId
                            });
                        }
                    }
                }
            });
        }
        function layoutGraph() {
            var canvas = $("#canvas");
            var canvasWidth = canvas.width();
            var canvasHeight = canvas.height();
            $scope.lastCanvasWidth = canvasWidth;
            $scope.lastCanvasHeight = canvasHeight;
            console.log("about to layout " + $scope.nodes.length + " nodes");
            Core.d3ForceGraph($scope, $scope.nodes, $scope.links, $element);
            Core.$apply($scope);
        }
        function findBrokerFolder(selection) {
            var answer = null;
            if (selection) {
                var parent = selection.parent;
                if (parent && isQueueOrTopicFolder(parent)) {
                    parent = parent.parent;
                }
                if (parent) {
                    answer = findBrokerFolder(parent);
                }
                if (answer) {
                    if (!isQueueOrTopicFolder(selection) && selection.typeName === "Broker" && parent.typeName !== "Broker" && selection.children.length > parent.children.length) {
                        return selection;
                    }
                } else {
                    if (selection.typeName === "Broker") {
                        if (selection.children.length) {
                            answer = selection;
                        } else if (parent.children.length > 1) {
                            answer = parent;
                        }
                    } else {
                        if (selection.children.some(function (n) {
                            return n.typeName === "Broker";
                        })) {
                            return selection;
                        }
                    }
                }
            }
            return answer;
        }
        function isQueueOrTopicFolder(selection) {
            var title = Core.pathGet(selection, [
                "title"
            ]);
            return title === "Queue" || title === "Topic";
        }
        function nodeTypeName(selection) {
            var typeName = null;
            if (selection) {
                typeName = selection.entries["destinationType"] || selection.typeName || selection.title;
            }
            return typeName;
        }
        function matchesSelection(destinationName) {
            var selectionDestinationName = $scope.selectionDestinationName;
            return !selectionDestinationName || destinationName === selectionDestinationName;
        }
        function getOrCreate(container, key, defaultObject) {
            var value = container[key];
            var id;
            if (!value) {
                container[key] = defaultObject;
                id = $scope.nodes.length;
                defaultObject["id"] = id;
                $scope.nodes.push(defaultObject);
            } else {
                id = value["id"];
            }
            return id;
        }
    }
    ActiveMQ.SubscriberGraphController = SubscriberGraphController;
})(ActiveMQ || (ActiveMQ = {}));
var ActiveMQ;
(function (ActiveMQ) {
    function JobSchedulerController($scope, workspace, jolokia) {
        $scope.refresh = loadTable;
        $scope.jobs = [];
        $scope.deleteJobsDialog = new Core.Dialog();
        $scope.gridOptions = {
            selectedItems: [],
            data: 'jobs',
            displayFooter: false,
            showFilter: false,
            showColumnMenu: true,
            enableColumnResize: true,
            enableColumnReordering: true,
            filterOptions: {
                filterText: ''
            },
            selectWithCheckboxOnly: true,
            showSelectionCheckbox: true,
            maintainColumnRatios: false,
            columnDefs: [
                {
                    field: 'jobId',
                    displayName: 'Job ID',
                    width: '25%'
                }, 
                {
                    field: 'cronEntry',
                    displayName: 'Cron Entry',
                    width: '10%'
                }, 
                {
                    field: 'delay',
                    displayName: 'Delay',
                    width: '5%'
                }, 
                {
                    field: 'repeat',
                    displayName: 'repeat',
                    width: '5%'
                }, 
                {
                    field: 'period',
                    displayName: 'period',
                    width: '5%'
                }, 
                {
                    field: 'start',
                    displayName: 'Start',
                    width: '25%'
                }, 
                {
                    field: 'next',
                    displayName: 'Next',
                    width: '25%'
                }
            ]
        };
        $scope.$watch('workspace.selection', function () {
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            setTimeout(loadTable, 50);
        });
        function loadTable() {
            var selection = workspace.selection;
            if (selection) {
                var mbean = selection.objectName;
                if (mbean) {
                    jolokia.request({
                        type: 'read',
                        mbean: mbean,
                        attribute: "AllJobs"
                    }, onSuccess(populateTable));
                }
            }
            Core.$apply($scope);
        }
        function populateTable(response) {
            var data = response.value;
            if (!angular.isArray(data)) {
                $scope.jobs = [];
                angular.forEach(data, function (value, idx) {
                    $scope.jobs.push(value);
                });
            } else {
                $scope.jobs = data;
            }
            Core.$apply($scope);
        }
        $scope.deleteJobs = function () {
            var selection = workspace.selection;
            var mbean = selection.objectName;
            if (mbean && selection) {
                var selectedItems = $scope.gridOptions.selectedItems;
                $scope.message = "Deleted " + Core.maybePlural(selectedItems.length, "job");
                var operation = "removeJob(java.lang.String)";
                angular.forEach(selectedItems, function (item, idx) {
                    var id = item.jobId;
                    if (id) {
                        var callback = (idx + 1 < selectedItems.length) ? intermediateResult : operationSuccess;
                        jolokia.execute(mbean, operation, id, onSuccess(callback));
                    }
                });
            }
        };
        function intermediateResult() {
        }
        function operationSuccess() {
            $scope.gridOptions.selectedItems.splice(0);
            notification("success", $scope.message);
            setTimeout(loadTable, 50);
        }
    }
    ActiveMQ.JobSchedulerController = JobSchedulerController;
})(ActiveMQ || (ActiveMQ = {}));
var ActiveMQ;
(function (ActiveMQ) {
    function TreeController($scope, $location, workspace) {
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateSelectionFromURL, 50);
        });
        $scope.$watch('workspace.tree', function () {
            reloadTree();
        });
        $scope.$on('jmxTreeUpdated', function () {
            reloadTree();
        });
        function updateSelectionFromURL() {
            Jmx.updateTreeSelectionFromURL($location, $("#activemqtree"), true);
        }
        function reloadTree() {
            console.log("workspace tree has changed, lets reload the activemq tree");
            var children = [];
            var tree = workspace.tree;
            if (tree) {
                var domainName = "org.apache.activemq";
                var folder = tree.get(domainName);
                if (folder) {
                    children = folder.children;
                }
                if (children.length) {
                    var firstChild = children[0];
                    if (!firstChild.typeName && firstChild.children.length < 4) {
                        var answer = [];
                        angular.forEach(children, function (child) {
                            answer = answer.concat(child.children);
                        });
                        children = answer;
                    }
                }
                var treeElement = $("#activemqtree");
                Jmx.enableTree($scope, $location, workspace, treeElement, children, true);
                setTimeout(updateSelectionFromURL, 50);
            }
        }
    }
    ActiveMQ.TreeController = TreeController;
})(ActiveMQ || (ActiveMQ = {}));
var API;
(function (API) {
    API.log = Logger.get("API");
    API.wadlNamespace = "http://schemas.xmlsoap.org/wsdl/";
    function loadXml(url, onXml) {
        if (url) {
            API.log.info("Loading XML: " + url);
            $.ajax({
                type: "GET",
                url: url,
                dataType: "xml",
                success: onXml
            });
        }
    }
    API.loadXml = loadXml;
    var wadlXmlToJavaConfig = {};
    function parseJson(json) {
        var answer = null;
        try  {
            answer = JSON.parse(json);
        } catch (e) {
            API.log.info("Failed to parse JSON " + e);
            API.log.info("JSON: " + json);
        }
        return answer;
    }
    API.parseJson = parseJson;
    function initScope($scope, $location, jolokia) {
        var search = $location.search();
        $scope.container = search["container"];
        $scope.objectName = search["objectName"];
        if ($scope.container && $scope.objectName) {
            Fabric.containerJolokia(jolokia, $scope.container, function (remoteJolokia) {
                $scope.remoteJolokia = remoteJolokia;
                if (remoteJolokia) {
                    API.loadJsonSchema(remoteJolokia, $scope.objectName, function (jsonSchema) {
                        $scope.jsonSchema = jsonSchema;
                    });
                } else {
                    API.log.info("No Remote Jolokia!");
                }
            });
        } else {
            API.log.info("No container or objectName");
        }
        API.log.info("container: " + $scope.container + " objectName: " + $scope.objectName + " url: " + $scope.url);
    }
    API.initScope = initScope;
    function loadJsonSchema(jolokia, mbean, onJsonSchemaFn) {
        function onResults(response) {
            var schema = {};
            if (response) {
                var json = response;
                if (json) {
                    schema = parseJson(json);
                }
            }
            onJsonSchemaFn(schema);
        }
        if (mbean) {
            return jolokia.execute(mbean, "getJSONSchema", onSuccess(onResults));
        } else {
            var schema = {};
            onJsonSchemaFn(schema);
            return schema;
        }
    }
    API.loadJsonSchema = loadJsonSchema;
    function onWadlXmlLoaded(response) {
        var root = response.documentElement;
        var output = {};
        return API.convertWadlToJson(root, output);
    }
    API.onWadlXmlLoaded = onWadlXmlLoaded;
    function convertWadlToJson(element, obj) {
        if (typeof obj === "undefined") { obj = {}; }
        return API.convertXmlToJson(element, obj, wadlXmlToJavaConfig);
    }
    API.convertWadlToJson = convertWadlToJson;
    function convertWadlJsonToSwagger(object) {
        var apis = [];
        var basePath = null;
        var resourcePath = null;
        var resources = Core.pathGet(object, [
            "resources", 
            0
        ]);
        if (resources) {
            basePath = resources.base;
            angular.forEach(resources.resource, function (resource) {
                var path = resource.path;
                var operations = [];
                angular.forEach(resource.method, function (method) {
                    var name = method.name;
                    var responseMessages = [];
                    var parameters = [];
                    operations.push({
                        "method": method.name,
                        "summary": method.summary,
                        "notes": method.notes,
                        "nickname": method.nickname,
                        "type": method.type,
                        "parameters": parameters,
                        "produces": [
                            "application/json"
                        ],
                        "responseMessages": responseMessages
                    });
                });
                apis.push({
                    path: path,
                    operations: operations
                });
            });
        }
        return {
            "apiVersion": "1.0",
            "swaggerVersion": "1.2",
            "basePath": basePath,
            "resourcePath": resourcePath,
            "produces": [
                "application/json"
            ],
            apis: apis
        };
    }
    API.convertWadlJsonToSwagger = convertWadlJsonToSwagger;
    function nodeName(owner, node) {
        return node ? node.localName : null;
    }
    function convertXmlToJson(element, obj, config) {
        var elementProperyFn = config.elementToPropertyName || nodeName;
        var attributeProperyFn = config.attributeToPropertyName || nodeName;
        angular.forEach(element.childNodes, function (child) {
            if (child.nodeType === 1) {
                var propertyName = elementProperyFn(element, child);
                if (propertyName) {
                    var array = obj[propertyName] || [];
                    if (!angular.isArray(array)) {
                        array = [
                            array
                        ];
                    }
                    var value = {};
                    convertXmlToJson(child, value, config);
                    array.push(value);
                    obj[propertyName] = array;
                }
            }
        });
        angular.forEach(element.attributes, function (attr) {
            var propertyName = attributeProperyFn(element, attr);
            if (propertyName) {
                var value = attr.nodeValue;
                obj[propertyName] = value;
            }
        });
        return obj;
    }
    API.convertXmlToJson = convertXmlToJson;
    ;
})(API || (API = {}));
var API;
(function (API) {
    var pluginName = 'api';
    angular.module(pluginName, [
        'bootstrap', 
        'hawtioCore', 
        'hawtio-ui'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/api/wsdl', {
            templateUrl: 'app/api/html/wsdl.html'
        }).when('/api/wadl', {
            templateUrl: 'app/api/html/wadl.html'
        });
    }).run(function ($location, workspace, viewRegistry, layoutFull, helpRegistry) {
        viewRegistry['api'] = layoutFull;
    });
    hawtioPluginLoader.addModule(pluginName);
})(API || (API = {}));
var API;
(function (API) {
    function WadlViewController($scope, $location, jolokia) {
        API.initScope($scope, $location, jolokia);
        $scope.url = $location.search()["wadl"];
        API.loadXml($scope.url, onWsdl);
        function onWsdl(response) {
            $scope.apidocs = API.onWadlXmlLoaded(response);
            Core.$apply($scope);
        }
    }
    API.WadlViewController = WadlViewController;
})(API || (API = {}));
var API;
(function (API) {
    function WsdlViewController($scope, $location, jolokia) {
        var log = Logger.get("API");
        API.initScope($scope, $location, jolokia);
        var wsdlNamespace = "http://schemas.xmlsoap.org/wsdl/";
        $scope.url = $location.search()["wsdl"];
        API.loadXml($scope.url, onWsdl);
        function onWsdl(response) {
            $scope.services = [];
            var root = response.documentElement;
            var targetNamespace = root ? root.getAttribute("targetNamespace") : null;
            var name = root ? root.getAttribute("name") : null;
            var portTypes = response.getElementsByTagNameNS(wsdlNamespace, "portType");
            var services = response.getElementsByTagNameNS(wsdlNamespace, "service");
            var bindings = response.getElementsByTagNameNS(wsdlNamespace, "binding");
            angular.forEach(portTypes, function (portType) {
                var service = {
                    name: name,
                    targetNamespace: targetNamespace,
                    portName: portType.getAttribute("name") || "Unknown",
                    operations: []
                };
                $scope.services.push(service);
                var operations = portType.getElementsByTagNameNS(wsdlNamespace, "operation");
                angular.forEach(operations, function (operation) {
                    var input = operation.getElementsByTagNameNS(wsdlNamespace, "input");
                    var output = operation.getElementsByTagNameNS(wsdlNamespace, "output");
                    function createMessageData(data) {
                        var answer = [];
                        angular.forEach(data, function (item) {
                            var name = item.getAttribute("name");
                            if (name) {
                                answer.push({
                                    name: name
                                });
                            }
                        });
                        return answer;
                    }
                    var opData = {
                        name: operation.getAttribute("name") || "Unknown",
                        inputs: createMessageData(input),
                        outputs: createMessageData(output)
                    };
                    service.operations.push(opData);
                });
            });
            Core.$apply($scope);
        }
    }
    API.WsdlViewController = WsdlViewController;
})(API || (API = {}));
var Apollo;
(function (Apollo) {
    function ApolloController($scope, $http, $location, localStorage, workspace) {
        var jolokia = workspace.jolokia;
        $scope.broker = {};
        $scope.online = true;
        $scope.route = function () {
            return $location.path();
        };
        $scope.apollo = {
            version: jolokia.getAttribute('org.apache.apollo:type=broker,name="default"', "Version", onSuccess(null)),
            url: jolokia.getAttribute('org.apache.apollo:type=broker,name="default"', "WebAdminUrl", onSuccess(null))
        };
        var default_error_handler = function (data, status, headers, config) {
            if (status === 401) {
                alert("Action not authorized.");
            } else {
                alert("Error: " + status);
            }
        };
        $scope.ajax = function (type, path, success, error, data, binary_options) {
            if (!error) {
                error = default_error_handler;
            }
            var username = "admin";
            var password = "password";
            var ajax_options = {
                method: type,
                url: $scope.apollo.url + "/api/json" + path,
                headers: {
                    AuthPrompt: 'false',
                    Accept: "application/json",
                    ContentType: "application/json",
                    Authorization: "Basic " + btoa(username + ':' + password)
                },
                cache: false,
                data: null
            };
            if (binary_options) {
                ajax_options.headers["Accept"] = binary_options.Accept || "application/octet-stream";
                ajax_options.headers["ContentType"] || "application/octet-stream";
                ajax_options.data = binary_options.data;
            }
            return $http(ajax_options).success(function (data, status, headers, config) {
                $scope.online = true;
                if (success) {
                    success(data, status, headers, config);
                }
            }).error(function (data, status, headers, config) {
                if (status === 0) {
                    $scope.online = false;
                } else {
                    $scope.online = true;
                    error(data, status, headers, config);
                }
            });
        };
        var reload = function () {
            if ($scope.apollo.url) {
                $scope.ajax("GET", "/broker", function (broker) {
                    $scope.broker = broker;
                    if ($scope.apollo.selected_virtual_host === undefined) {
                        $scope.apollo.selected_virtual_host = broker.virtual_hosts[0];
                    }
                }, function (error) {
                    alert("fail:" + error);
                });
            } else {
                $scope.broker = {};
            }
        };
        var schedule_refresh = function () {
        };
        schedule_refresh = function () {
            setTimeout(function () {
                reload();
                schedule_refresh();
            }, 1000);
        };
        schedule_refresh();
        $scope.$watch('apollo.url', reload);
        $scope.$watch('online', function () {
        });
    }
    Apollo.ApolloController = ApolloController;
})(Apollo || (Apollo = {}));
var Apollo;
(function (Apollo) {
    var pluginName = 'apollo';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'hawtioCore'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/apollo', {
            templateUrl: 'app/apollo/html/layout-apollo.html'
        });
    }).run(function ($location, workspace, viewRegistry, helpRegistry) {
        viewRegistry['apollo'] = "app/apollo/html/layout-apollo.html";
        helpRegistry.addUserDoc('apollo', 'app/apollo/doc/help.md', function () {
            return workspace.treeContainsDomainAndProperties("org.apache.apollo");
        });
        workspace.topLevelTabs.push({
            content: "Apollo",
            title: "Manage your Apollo Broker",
            isValid: function (workspace) {
                return workspace.treeContainsDomainAndProperties("org.apache.apollo");
            },
            href: function () {
                return '#/apollo/virtual-hosts';
            },
            isActive: function (workspace) {
                return workspace.isLinkActive("apollo");
            }
        });
    });
    hawtioPluginLoader.addModule(pluginName);
})(Apollo || (Apollo = {}));
var Apollo;
(function (Apollo) {
    function VirtualHostController($scope, $http, $location, localStorage, workspace) {
        $scope.virtual_host = {};
        $scope.init = function (virtual_host_name) {
            $scope.ajax("GET", "/broker/virtual-hosts/" + virtual_host_name, function (host) {
                $scope.virtual_host = host;
            });
        };
    }
    Apollo.VirtualHostController = VirtualHostController;
})(Apollo || (Apollo = {}));
var Core;
(function (Core) {
    function parseBooleanValue(value) {
        if (!angular.isDefined(value)) {
            return false;
        }
        if (value.constructor === Boolean) {
            return value;
        }
        if (angular.isString(value)) {
            switch(value.toLowerCase()) {
                case "true":
                case "1":
                case "yes":
                    return true;
                default:
                    return false;
            }
        }
        if (angular.isNumber(value)) {
            return value !== 0;
        }
        throw new Error("Can't convert value " + value + " to boolean");
    }
    Core.parseBooleanValue = parseBooleanValue;
})(Core || (Core = {}));
var Branding;
(function (Branding) {
    Branding.enabled = false;
    Branding.profile = null;
    Branding.mqProfiles = [
        "mq", 
        "a-mq", 
        "a-mq-openshift", 
        "mq-replicated"
    ];
    $.ajaxSetup({
        async: true
    });
    $.get('/hawtio/branding', function (response) {
        Branding.enabled = Core.parseBooleanValue(response.enable);
        if (Branding.enabled) {
            Branding.profile = response.profile;
            var link = $("<link>");
            $("head").append(link);
            link.attr({
                rel: 'stylesheet',
                type: 'text/css',
                href: 'css/site-branding.css'
            });
        }
    });
    Branding.pluginName = 'hawtio-branding';
    Branding.propertiesToCheck = [
        'karaf.version'
    ];
    Branding.wantedStrings = [
        'redhat', 
        'fuse'
    ];
    angular.module(Branding.pluginName, [
        'hawtioCore'
    ]).run(function ($http, helpRegistry, branding) {
        helpRegistry.addDevDoc("branding", 'app/branding/doc/developer.md');
        if (Branding.enabled) {
            console.log("enabled branding");
            branding.appName = 'Management Console';
            branding.appLogo = 'img/branding/RHJB_Fuse_UXlogotype_0513LL_white.svg';
            branding.loginBg = 'img/branding/login-screen-background.jpg';
            branding.fullscreenLogin = true;
            branding.profile = Branding.profile;
            if (Branding.mqProfiles.any(branding.profile)) {
                branding.appLogo = 'img/branding/RH_JBoss_AMQ_logotype_interface_LL_white.svg';
            }
        }
    });
    hawtioPluginLoader.addModule(Branding.pluginName);
})(Branding || (Branding = {}));
var Camel;
(function (Camel) {
    function AttributesToolBarController($scope, workspace, jolokia) {
        $scope.deleteDialog = false;
        $scope.start = function () {
            $scope.invokeSelectedMBeans(function (item) {
                return Camel.isState(item, "suspend") ? "resume()" : "start()";
            });
        };
        $scope.pause = function () {
            $scope.invokeSelectedMBeans("suspend()");
        };
        $scope.stop = function () {
            $scope.invokeSelectedMBeans("stop()", function () {
                workspace.removeAndSelectParentNode();
            });
        };
        $scope.delete = function () {
            $scope.invokeSelectedMBeans("remove()", function () {
                $scope.workspace.operationCounter += 1;
                Core.$apply($scope);
            });
        };
        $scope.anySelectionHasState = function (state) {
            var selected = $scope.selectedItems || [];
            return selected.length && selected.any(function (s) {
                return Camel.isState(s, state);
            });
        };
        $scope.everySelectionHasState = function (state) {
            var selected = $scope.selectedItems || [];
            return selected.length && selected.every(function (s) {
                return Camel.isState(s, state);
            });
        };
    }
    Camel.AttributesToolBarController = AttributesToolBarController;
})(Camel || (Camel = {}));
var Camel;
(function (Camel) {
    function BrowseEndpointController($scope, workspace, jolokia) {
        $scope.workspace = workspace;
        $scope.forwardDialog = new Core.Dialog();
        $scope.showMessageDetails = false;
        $scope.mode = 'text';
        $scope.gridOptions = Camel.createBrowseGridOptions();
        $scope.$watch('workspace.selection', function () {
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            loadData();
        });
        $scope.openMessageDialog = function (message) {
            var idx = Core.pathGet(message, [
                "rowIndex"
            ]);
            $scope.selectRowIndex(idx);
            if ($scope.row) {
                $scope.mode = CodeEditor.detectTextFormat($scope.row.body);
                $scope.showMessageDetails = true;
            }
        };
        $scope.selectRowIndex = function (idx) {
            $scope.rowIndex = idx;
            var selected = $scope.gridOptions.selectedItems;
            selected.splice(0, selected.length);
            if (idx >= 0 && idx < $scope.messages.length) {
                $scope.row = $scope.messages[idx];
                if ($scope.row) {
                    selected.push($scope.row);
                }
            } else {
                $scope.row = null;
            }
        };
        $scope.forwardMessagesAndCloseForwardDialog = function () {
            var mbean = Camel.getSelectionCamelContextMBean(workspace);
            var selectedItems = $scope.gridOptions.selectedItems;
            var uri = $scope.endpointUri;
            if (mbean && uri && selectedItems && selectedItems.length) {
                jolokia.execute(mbean, "createEndpoint(java.lang.String)", uri, onSuccess(intermediateResult));
                $scope.message = "Forwarded " + Core.maybePlural(selectedItems.length, "message" + " to " + uri);
                angular.forEach(selectedItems, function (item, idx) {
                    var callback = (idx + 1 < selectedItems.length) ? intermediateResult : operationSuccess;
                    var body = item.body;
                    var headers = item.headers;
                    jolokia.execute(mbean, "sendBodyAndHeaders(java.lang.String, java.lang.Object, java.util.Map)", uri, body, headers, onSuccess(callback));
                });
            }
            $scope.forwardDialog.close();
        };
        $scope.endpointUris = function () {
            var endpointFolder = Camel.getSelectionCamelContextEndpoints(workspace);
            return (endpointFolder) ? endpointFolder.children.map(function (n) {
                return n.title;
            }) : [];
        };
        $scope.refresh = loadData;
        function intermediateResult() {
        }
        function operationSuccess() {
            if ($scope.messageDialog) {
                $scope.messageDialog.close();
            }
            $scope.gridOptions.selectedItems.splice(0);
            notification("success", $scope.message);
            setTimeout(loadData, 50);
        }
        function loadData() {
            var mbean = workspace.getSelectedMBeanName();
            if (mbean) {
                var options = onSuccess(populateTable);
                jolokia.execute(mbean, 'browseAllMessagesAsXml(java.lang.Boolean)', true, options);
            }
        }
        function populateTable(response) {
            var data = [];
            if (angular.isString(response)) {
                var doc = $.parseXML(response);
                var allMessages = $(doc).find("message");
                allMessages.each(function (idx, message) {
                    var messageData = Camel.createMessageFromXml(message);
                    data.push(messageData);
                });
            }
            $scope.messages = data;
            Core.$apply($scope);
        }
    }
    Camel.BrowseEndpointController = BrowseEndpointController;
})(Camel || (Camel = {}));
var Camel;
(function (Camel) {
    function CamelController($scope, $element, workspace, jolokia, localStorage) {
        var log = Logger.get("Camel");
        $scope.routes = [];
        $scope.routeNodes = {};
        $scope.camelIgnoreIdForLabel = Camel.ignoreIdForLabel(localStorage);
        $scope.camelMaximumLabelWidth = Camel.maximumLabelWidth(localStorage);
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateRoutes, 50);
        });
        $scope.$watch('workspace.selection', function () {
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            updateRoutes();
        });
        $scope.$watch('nodeXmlNode', function () {
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            updateRoutes();
        });
        function updateRoutes() {
            var routeXmlNode = null;
            if (!$scope.ignoreRouteXmlNode) {
                routeXmlNode = Camel.getSelectedRouteNode(workspace);
                if (!routeXmlNode) {
                    routeXmlNode = $scope.nodeXmlNode;
                }
                if (routeXmlNode && routeXmlNode.localName !== "route") {
                    var wrapper = document.createElement("route");
                    wrapper.appendChild(routeXmlNode.cloneNode(true));
                    routeXmlNode = wrapper;
                }
            }
            $scope.mbean = Camel.getSelectionCamelContextMBean(workspace);
            if (routeXmlNode) {
                $scope.nodes = {};
                var nodes = [];
                var links = [];
                Camel.addRouteXmlChildren($scope, routeXmlNode, nodes, links, null, 0, 0);
                showGraph(nodes, links);
            } else if ($scope.mbean) {
                jolokia.request({
                    type: 'exec',
                    mbean: $scope.mbean,
                    operation: 'dumpRoutesAsXml()'
                }, onSuccess(populateTable));
            } else {
                console.log("No camel context bean!");
            }
        }
        var populateTable = function (response) {
            var data = response.value;
            $scope.routes = data;
            $scope.nodes = {};
            $scope.routeNodes = {};
            var nodes = [];
            var links = [];
            var selectedRouteId = Camel.getSelectedRouteId(workspace);
            if (data) {
                var doc = $.parseXML(data);
                Camel.loadRouteXmlNodes($scope, doc, selectedRouteId, nodes, links, getWidth());
                showGraph(nodes, links);
            } else {
                console.log("No data from route XML!");
            }
            Core.$apply($scope);
        };
        var postfix = " selected";
        function isSelected(node) {
            if (node) {
                var className = node.getAttribute("class");
                return className && className.endsWith(postfix);
            }
            return false;
        }
        function setSelected(node, flag) {
            var answer = false;
            if (node) {
                var className = node.getAttribute("class");
                var selected = className && className.endsWith(postfix);
                if (selected) {
                    className = className.substring(0, className.length - postfix.length);
                } else {
                    if (!flag) {
                        return answer;
                    }
                    className = className + postfix;
                    answer = true;
                }
                node.setAttribute("class", className);
            }
            return answer;
        }
        function showGraph(nodes, links) {
            var canvasDiv = $($element);
            var width = getWidth();
            var height = getHeight();
            var svg = canvasDiv.children("svg")[0];
            $scope.graphData = Core.dagreLayoutGraph(nodes, links, width, height, svg);
            var nodes = canvasDiv.find("g.node");
            nodes.click(function () {
                var selected = isSelected(this);
                nodes.each(function (idx, element) {
                    setSelected(element, false);
                });
                var cid = null;
                if (!selected) {
                    cid = this.getAttribute("data-cid");
                    setSelected(this, true);
                }
                $scope.$emit("camel.diagram.selectedNodeId", cid);
                Core.$apply($scope);
            });
            if ($scope.mbean) {
                Core.register(jolokia, $scope, {
                    type: 'exec',
                    mbean: $scope.mbean,
                    operation: 'dumpRoutesStatsAsXml',
                    arguments: [
                        true, 
                        true
                    ]
                }, onSuccess(statsCallback, {
                    silent: true,
                    error: false
                }));
            }
            $scope.$emit("camel.diagram.layoutComplete");
            return width;
        }
        function getWidth() {
            var canvasDiv = $($element);
            return canvasDiv.width();
        }
        function getHeight() {
            var canvasDiv = $($element);
            return Camel.getCanvasHeight(canvasDiv);
        }
        function statsCallback(response) {
            var data = response.value;
            if (data) {
                var doc = $.parseXML(data);
                var allStats = $(doc).find("routeStat");
                allStats.each(function (idx, stat) {
                    addTooltipToNode(true, stat);
                });
                var allStats = $(doc).find("processorStat");
                allStats.each(function (idx, stat) {
                    addTooltipToNode(false, stat);
                });
                Core.dagreUpdateGraphData($scope.graphData);
            }
            function addTooltipToNode(isRoute, stat) {
                var id = stat.getAttribute("id");
                var completed = stat.getAttribute("exchangesCompleted");
                var tooltip = "";
                if (id && completed) {
                    var container = isRoute ? $scope.routeNodes : $scope.nodes;
                    var node = container[id];
                    if (!node) {
                        angular.forEach(container, function (value, key) {
                            if (!node && id === value.elementId) {
                                node = value;
                            }
                        });
                    }
                    if (node) {
                        var total = 0 + parseInt(completed);
                        var failed = stat.getAttribute("exchangesFailed");
                        if (failed) {
                            total += parseInt(failed);
                        }
                        var last = stat.getAttribute("lastProcessingTime");
                        var mean = stat.getAttribute("meanProcessingTime");
                        var min = stat.getAttribute("minProcessingTime");
                        var max = stat.getAttribute("maxProcessingTime");
                        tooltip = "last: " + last + " (ms)\nmean: " + mean + " (ms)\nmin: " + min + " (ms)\nmax: " + max + " (ms)";
                        node["counter"] = total;
                        var labelSummary = node["labelSummary"];
                        if (labelSummary) {
                            tooltip = labelSummary + "\n\n" + tooltip;
                        }
                        node["tooltip"] = tooltip;
                    } else {
                    }
                }
            }
        }
    }
    Camel.CamelController = CamelController;
})(Camel || (Camel = {}));
var Camel;
(function (Camel) {
    Camel.camelHeaderSchema = {
        definitions: {
            headers: {
                properties: {
                    "CamelAuthentication": {
                        type: "java.lang.String"
                    },
                    "CamelAuthenticationFailurePolicyId": {
                        type: "java.lang.String"
                    },
                    "CamelAcceptContentType": {
                        type: "java.lang.String"
                    },
                    "CamelAggregatedSize": {
                        type: "java.lang.String"
                    },
                    "CamelAggregatedTimeout": {
                        type: "java.lang.String"
                    },
                    "CamelAggregatedCompletedBy": {
                        type: "java.lang.String"
                    },
                    "CamelAggregatedCorrelationKey": {
                        type: "java.lang.String"
                    },
                    "CamelAggregationStrategy": {
                        type: "java.lang.String"
                    },
                    "CamelAggregationCompleteAllGroups": {
                        type: "java.lang.String"
                    },
                    "CamelAggregationCompleteAllGroupsInclusive": {
                        type: "java.lang.String"
                    },
                    "CamelAsyncWait": {
                        type: "java.lang.String"
                    },
                    "CamelBatchIndex": {
                        type: "java.lang.String"
                    },
                    "CamelBatchSize": {
                        type: "java.lang.String"
                    },
                    "CamelBatchComplete": {
                        type: "java.lang.String"
                    },
                    "CamelBeanMethodName": {
                        type: "java.lang.String"
                    },
                    "CamelBeanMultiParameterArray": {
                        type: "java.lang.String"
                    },
                    "CamelBinding": {
                        type: "java.lang.String"
                    },
                    "breadcrumbId": {
                        type: "java.lang.String"
                    },
                    "CamelCharsetName": {
                        type: "java.lang.String"
                    },
                    "CamelCreatedTimestamp": {
                        type: "java.lang.String"
                    },
                    "Content-Encoding": {
                        type: "java.lang.String"
                    },
                    "Content-Length": {
                        type: "java.lang.String"
                    },
                    "Content-Type": {
                        type: "java.lang.String"
                    },
                    "CamelCorrelationId": {
                        type: "java.lang.String"
                    },
                    "CamelDataSetIndex": {
                        type: "java.lang.String"
                    },
                    "org.apache.camel.default.charset": {
                        type: "java.lang.String"
                    },
                    "CamelDestinationOverrideUrl": {
                        type: "java.lang.String"
                    },
                    "CamelDisableHttpStreamCache": {
                        type: "java.lang.String"
                    },
                    "CamelDuplicateMessage": {
                        type: "java.lang.String"
                    },
                    "CamelExceptionCaught": {
                        type: "java.lang.String"
                    },
                    "CamelExceptionHandled": {
                        type: "java.lang.String"
                    },
                    "CamelEvaluateExpressionResult": {
                        type: "java.lang.String"
                    },
                    "CamelErrorHandlerHandled": {
                        type: "java.lang.String"
                    },
                    "CamelExternalRedelivered": {
                        type: "java.lang.String"
                    },
                    "CamelFailureHandled": {
                        type: "java.lang.String"
                    },
                    "CamelFailureEndpoint": {
                        type: "java.lang.String"
                    },
                    "CamelFailureRouteId": {
                        type: "java.lang.String"
                    },
                    "CamelFilterNonXmlChars": {
                        type: "java.lang.String"
                    },
                    "CamelFileLocalWorkPath": {
                        type: "java.lang.String"
                    },
                    "CamelFileName": {
                        type: "java.lang.String"
                    },
                    "CamelFileNameOnly": {
                        type: "java.lang.String"
                    },
                    "CamelFileNameProduced": {
                        type: "java.lang.String"
                    },
                    "CamelFilePath": {
                        type: "java.lang.String"
                    },
                    "CamelFileParent": {
                        type: "java.lang.String"
                    },
                    "CamelFileLastModified": {
                        type: "java.lang.String"
                    },
                    "CamelFileLength": {
                        type: "java.lang.String"
                    },
                    "CamelFilterMatched": {
                        type: "java.lang.String"
                    },
                    "CamelFileLockFileAcquired": {
                        type: "java.lang.String"
                    },
                    "CamelFileLockFileName": {
                        type: "java.lang.String"
                    },
                    "CamelGroupedExchange": {
                        type: "java.lang.String"
                    },
                    "CamelHttpBaseUri": {
                        type: "java.lang.String"
                    },
                    "CamelHttpCharacterEncoding": {
                        type: "java.lang.String"
                    },
                    "CamelHttpMethod": {
                        type: "java.lang.String"
                    },
                    "CamelHttpPath": {
                        type: "java.lang.String"
                    },
                    "CamelHttpProtocolVersion": {
                        type: "java.lang.String"
                    },
                    "CamelHttpQuery": {
                        type: "java.lang.String"
                    },
                    "CamelHttpResponseCode": {
                        type: "java.lang.String"
                    },
                    "CamelHttpUri": {
                        type: "java.lang.String"
                    },
                    "CamelHttpUrl": {
                        type: "java.lang.String"
                    },
                    "CamelHttpChunked": {
                        type: "java.lang.String"
                    },
                    "CamelHttpServletRequest": {
                        type: "java.lang.String"
                    },
                    "CamelHttpServletResponse": {
                        type: "java.lang.String"
                    },
                    "CamelInterceptedEndpoint": {
                        type: "java.lang.String"
                    },
                    "CamelInterceptSendToEndpointWhenMatched": {
                        type: "java.lang.String"
                    },
                    "CamelLanguageScript": {
                        type: "java.lang.String"
                    },
                    "CamelLogDebugBodyMaxChars": {
                        type: "java.lang.String"
                    },
                    "CamelLogDebugStreams": {
                        type: "java.lang.String"
                    },
                    "CamelLoopIndex": {
                        type: "java.lang.String"
                    },
                    "CamelLoopSize": {
                        type: "java.lang.String"
                    },
                    "CamelMaximumCachePoolSize": {
                        type: "java.lang.String"
                    },
                    "CamelMaximumEndpointCacheSize": {
                        type: "java.lang.String"
                    },
                    "CamelMessageHistory": {
                        type: "java.lang.String"
                    },
                    "CamelMulticastIndex": {
                        type: "java.lang.String"
                    },
                    "CamelMulticastComplete": {
                        type: "java.lang.String"
                    },
                    "CamelNotifyEvent": {
                        type: "java.lang.String"
                    },
                    "CamelOnCompletion": {
                        type: "java.lang.String"
                    },
                    "CamelOverruleFileName": {
                        type: "java.lang.String"
                    },
                    "CamelParentUnitOfWork": {
                        type: "java.lang.String"
                    },
                    "CamelReceivedTimestamp": {
                        type: "java.lang.String"
                    },
                    "CamelRedelivered": {
                        type: "java.lang.String"
                    },
                    "CamelRedeliveryCounter": {
                        type: "java.lang.String"
                    },
                    "CamelRedeliveryMaxCounter": {
                        type: "java.lang.String"
                    },
                    "CamelRedeliveryExhausted": {
                        type: "java.lang.String"
                    },
                    "CamelRedeliveryDelay": {
                        type: "java.lang.String"
                    },
                    "CamelRollbackOnly": {
                        type: "java.lang.String"
                    },
                    "CamelRollbackOnlyLast": {
                        type: "java.lang.String"
                    },
                    "CamelRouteStop": {
                        type: "java.lang.String"
                    },
                    "CamelSoapAction": {
                        type: "java.lang.String"
                    },
                    "CamelSkipGzipEncoding": {
                        type: "java.lang.String"
                    },
                    "CamelSlipEndpoint": {
                        type: "java.lang.String"
                    },
                    "CamelSplitIndex": {
                        type: "java.lang.String"
                    },
                    "CamelSplitComplete": {
                        type: "java.lang.String"
                    },
                    "CamelSplitSize": {
                        type: "java.lang.String"
                    },
                    "CamelTimerCounter": {
                        type: "java.lang.String"
                    },
                    "CamelTimerFiredTime": {
                        type: "java.lang.String"
                    },
                    "CamelTimerName": {
                        type: "java.lang.String"
                    },
                    "CamelTimerPeriod": {
                        type: "java.lang.String"
                    },
                    "CamelTimerTime": {
                        type: "java.lang.String"
                    },
                    "CamelToEndpoint": {
                        type: "java.lang.String"
                    },
                    "CamelTraceEvent": {
                        type: "java.lang.String"
                    },
                    "CamelTraceEventNodeId": {
                        type: "java.lang.String"
                    },
                    "CamelTraceEventTimestamp": {
                        type: "java.lang.String"
                    },
                    "CamelTraceEventExchange": {
                        type: "java.lang.String"
                    },
                    "Transfer-Encoding": {
                        type: "java.lang.String"
                    },
                    "CamelUnitOfWorkExhausted": {
                        type: "java.lang.String"
                    },
                    "CamelUnitOfWorkProcessSync": {
                        type: "java.lang.String"
                    },
                    "CamelXsltFileName": {
                        type: "java.lang.String"
                    }
                }
            }
        }
    };
})(Camel || (Camel = {}));
var Camel;
(function (Camel) {
    Camel.log = Logger.get("Camel");
    Camel.defaultMaximumLabelWidth = 34;
    Camel.defaultCamelMaximumTraceOrDebugBodyLength = 5000;
    function processRouteXml(workspace, jolokia, folder, onRoute) {
        var selectedRouteId = getSelectedRouteId(workspace, folder);
        var mbean = getSelectionCamelContextMBean(workspace);
        function onRouteXml(response) {
            var route = null;
            var data = response ? response.value : null;
            if (data) {
                var doc = $.parseXML(data);
                var routes = $(doc).find("route[id='" + selectedRouteId + "']");
                if (routes && routes.length) {
                    route = routes[0];
                }
            }
            onRoute(route);
        }
        if (mbean && selectedRouteId) {
            jolokia.request({
                type: 'exec',
                mbean: mbean,
                operation: 'dumpRoutesAsXml()'
            }, onSuccess(onRouteXml, {
                error: onRouteXml
            }));
        } else {
            if (!selectedRouteId) {
                console.log("No selectedRouteId when trying to lazy load the route!");
            }
            onRoute(null);
        }
    }
    Camel.processRouteXml = processRouteXml;
    function getRouteNodeUri(node) {
        var uri = null;
        if (node) {
            uri = node.getAttribute("uri");
            if (!uri) {
                var ref = node.getAttribute("ref");
                if (ref) {
                    var method = node.getAttribute("method");
                    if (method) {
                        uri = ref + "." + method + "()";
                    } else {
                        uri = "ref:" + ref;
                    }
                }
            }
        }
        return uri;
    }
    Camel.getRouteNodeUri = getRouteNodeUri;
    function getRouteFolderJSON(folder, answer) {
        if (typeof answer === "undefined") { answer = {}; }
        var nodeData = folder["camelNodeData"];
        if (!nodeData) {
            var routeXmlNode = folder["routeXmlNode"];
            if (routeXmlNode) {
                nodeData = Camel.getRouteNodeJSON(routeXmlNode);
            }
            if (!nodeData) {
                nodeData = answer;
            }
            folder["camelNodeData"] = nodeData;
        }
        return nodeData;
    }
    Camel.getRouteFolderJSON = getRouteFolderJSON;
    function getRouteNodeJSON(routeXmlNode, answer) {
        if (typeof answer === "undefined") { answer = {}; }
        if (routeXmlNode) {
            angular.forEach(routeXmlNode.attributes, function (attr) {
                answer[attr.name] = attr.value;
            });
            var localName = routeXmlNode.localName;
            if (localName !== "route" && localName !== "routes" && localName !== "camelContext") {
                $(routeXmlNode).children("*").each(function (idx, element) {
                    var nodeName = element.localName;
                    var langSettings = Camel.camelLanguageSettings(nodeName);
                    if (langSettings) {
                        answer["expression"] = {
                            language: nodeName,
                            expression: element.textContent
                        };
                    } else {
                        if (!isCamelPattern(nodeName)) {
                            var nested = getRouteNodeJSON(element);
                            if (nested) {
                                answer[nodeName] = nested;
                            }
                        }
                    }
                });
            }
        }
        return answer;
    }
    Camel.getRouteNodeJSON = getRouteNodeJSON;
    function increaseIndent(currentIndent, indentAmount) {
        if (typeof indentAmount === "undefined") { indentAmount = "  "; }
        return currentIndent + indentAmount;
    }
    Camel.increaseIndent = increaseIndent;
    function setRouteNodeJSON(routeXmlNode, newData, indent) {
        if (routeXmlNode) {
            var childIndent = increaseIndent(indent);
            angular.forEach(newData, function (value, key) {
                if (angular.isObject(value)) {
                    var textContent = null;
                    if (key === "expression") {
                        var languageName = value["language"];
                        if (languageName) {
                            key = languageName;
                            textContent = value["expression"];
                            value = angular.copy(value);
                            delete value["expression"];
                            delete value["language"];
                        }
                    }
                    var nested = $(routeXmlNode).children(key);
                    var element = null;
                    if (!nested || !nested.length) {
                        var doc = routeXmlNode.ownerDocument || document;
                        routeXmlNode.appendChild(doc.createTextNode("\n" + childIndent));
                        element = doc.createElement(key);
                        if (textContent) {
                            element.appendChild(doc.createTextNode(textContent));
                        }
                        routeXmlNode.appendChild(element);
                    } else {
                        element = nested[0];
                    }
                    setRouteNodeJSON(element, value, childIndent);
                    if (textContent) {
                        nested.text(textContent);
                    }
                } else {
                    if (value) {
                        if (key.startsWith("_")) {
                        } else {
                            var text = value.toString();
                            routeXmlNode.setAttribute(key, text);
                        }
                    } else {
                        routeXmlNode.removeAttribute(key);
                    }
                }
            });
        }
    }
    Camel.setRouteNodeJSON = setRouteNodeJSON;
    function getRouteNodeIcon(nodeSettingsOrXmlNode) {
        var nodeSettings = null;
        if (nodeSettingsOrXmlNode) {
            var nodeName = nodeSettingsOrXmlNode.localName;
            if (nodeName) {
                nodeSettings = getCamelSchema(nodeName);
            } else {
                nodeSettings = nodeSettingsOrXmlNode;
            }
        }
        if (nodeSettings) {
            var imageName = nodeSettings["icon"] || "generic24.png";
            return url("/app/camel/img/" + imageName);
        } else {
            return null;
        }
    }
    Camel.getRouteNodeIcon = getRouteNodeIcon;
    function getSelectedEndpointName(workspace) {
        var selection = workspace.selection;
        if (selection && selection['objectName'] && selection['typeName'] && selection['typeName'] === 'endpoints') {
            var mbean = Core.parseMBean(selection['objectName']);
            if (!mbean) {
                return null;
            }
            var attributes = mbean['attributes'];
            if (!attributes) {
                return null;
            }
            if (!('name' in attributes)) {
                return null;
            }
            var uri = attributes['name'];
            uri = uri.replace("\\?", "?");
            if (uri.startsWith("\"")) {
                uri = uri.last(uri.length - 1);
            }
            if (uri.endsWith("\"")) {
                uri = uri.first(uri.length - 1);
            }
            return uri;
        } else {
            return null;
        }
    }
    Camel.getSelectedEndpointName = getSelectedEndpointName;
    function getContextAndTargetEndpoint(workspace) {
        return {
            uri: Camel.getSelectedEndpointName(workspace),
            mbean: Camel.getSelectionCamelContextMBean(workspace)
        };
    }
    Camel.getContextAndTargetEndpoint = getContextAndTargetEndpoint;
    function getSelectedRouteNode(workspace) {
        var selection = workspace.selection;
        return (selection && Camel.jmxDomain === selection.domain) ? selection["routeXmlNode"] : null;
    }
    Camel.getSelectedRouteNode = getSelectedRouteNode;
    function clearSelectedRouteNode(workspace) {
        var selection = workspace.selection;
        if (selection && Camel.jmxDomain === selection.domain) {
            delete selection["routeXmlNode"];
        }
    }
    Camel.clearSelectedRouteNode = clearSelectedRouteNode;
    function getCamelSchema(nodeIdOrDefinition) {
        return (angular.isObject(nodeIdOrDefinition)) ? nodeIdOrDefinition : Forms.lookupDefinition(nodeIdOrDefinition, _apacheCamelModel);
    }
    Camel.getCamelSchema = getCamelSchema;
    function isCamelPattern(nodeId) {
        return Forms.isJsonType(nodeId, _apacheCamelModel, "org.apache.camel.model.OptionalIdentifiedDefinition");
    }
    Camel.isCamelPattern = isCamelPattern;
    function isNextSiblingAddedAsChild(nodeIdOrDefinition) {
        var definition = getCamelSchema(nodeIdOrDefinition);
        if (definition) {
            return definition["nextSiblingAddedAsChild"] || false;
        }
        return null;
    }
    Camel.isNextSiblingAddedAsChild = isNextSiblingAddedAsChild;
    function acceptInput(nodeIdOrDefinition) {
        var definition = getCamelSchema(nodeIdOrDefinition);
        if (definition) {
            return definition["acceptInput"] || false;
        }
        return null;
    }
    Camel.acceptInput = acceptInput;
    function acceptOutput(nodeIdOrDefinition) {
        var definition = getCamelSchema(nodeIdOrDefinition);
        if (definition) {
            return definition["acceptOutput"] || false;
        }
        return null;
    }
    Camel.acceptOutput = acceptOutput;
    function camelLanguageSettings(nodeName) {
        return _apacheCamelModel.languages[nodeName];
    }
    Camel.camelLanguageSettings = camelLanguageSettings;
    function isCamelLanguage(nodeName) {
        return (camelLanguageSettings(nodeName) || nodeName === "expression") ? true : false;
    }
    Camel.isCamelLanguage = isCamelLanguage;
    function loadCamelTree(xml, key) {
        var doc = xml;
        if (angular.isString(xml)) {
            doc = $.parseXML(xml);
        }
        var id = "camelContext";
        var folder = new Folder(id);
        folder.addClass = "org-apache-camel-context";
        folder.domain = Camel.jmxDomain;
        folder.typeName = "context";
        folder.key = Core.toSafeDomID(key);
        var context = $(doc).find("camelContext");
        if (!context || !context.length) {
            context = $(doc).find("routes");
        }
        if (context && context.length) {
            folder["xmlDocument"] = doc;
            folder["routeXmlNode"] = context;
            $(context).children("route").each(function (idx, route) {
                var id = route.getAttribute("id");
                if (!id) {
                    id = "route" + idx;
                    route.setAttribute("id", id);
                }
                var routeFolder = new Folder(id);
                routeFolder.addClass = "org-apache-camel-route";
                routeFolder.typeName = "routes";
                routeFolder.domain = Camel.jmxDomain;
                routeFolder.key = folder.key + "_" + Core.toSafeDomID(id);
                routeFolder.parent = folder;
                var nodeSettings = getCamelSchema("route");
                if (nodeSettings) {
                    var imageUrl = getRouteNodeIcon(nodeSettings);
                    routeFolder.tooltip = nodeSettings["tooltip"] || nodeSettings["description"] || id;
                    routeFolder.icon = imageUrl;
                }
                folder.children.push(routeFolder);
                addRouteChildren(routeFolder, route);
            });
        }
        return folder;
    }
    Camel.loadCamelTree = loadCamelTree;
    function addRouteChildren(folder, route) {
        folder.children = [];
        folder["routeXmlNode"] = route;
        route.setAttribute("_cid", folder.key);
        $(route).children("*").each(function (idx, n) {
            addRouteChild(folder, n);
        });
    }
    Camel.addRouteChildren = addRouteChildren;
    function addRouteChild(folder, n) {
        var nodeName = n.localName;
        if (nodeName) {
            var nodeSettings = getCamelSchema(nodeName);
            if (nodeSettings) {
                var imageUrl = getRouteNodeIcon(nodeSettings);
                var child = new Folder(nodeName);
                child.domain = Camel.jmxDomain;
                child.typeName = "routeNode";
                updateRouteNodeLabelAndTooltip(child, n, nodeSettings);
                child.parent = folder;
                child.folderNames = folder.folderNames;
                var id = n.getAttribute("id") || nodeName;
                var key = folder.key + "_" + Core.toSafeDomID(id);
                var counter = 1;
                var notFound = true;
                while(notFound) {
                    var tmpKey = key + counter;
                    if (folder.children.some({
                        key: tmpKey
                    })) {
                        counter += 1;
                    } else {
                        notFound = false;
                        key = tmpKey;
                    }
                }
                child.key = key;
                child.icon = imageUrl;
                child["routeXmlNode"] = n;
                if (!folder.children) {
                    folder.children = [];
                }
                folder.children.push(child);
                addRouteChildren(child, n);
                return child;
            }
        }
        return null;
    }
    Camel.addRouteChild = addRouteChild;
    function getFolderCamelNodeId(folder) {
        var answer = Core.pathGet(folder, [
            "routeXmlNode", 
            "localName"
        ]);
        return ("from" === answer || "to" === answer) ? "endpoint" : answer;
    }
    Camel.getFolderCamelNodeId = getFolderCamelNodeId;
    function createFolderXmlTree(treeNode, xmlNode, indent) {
        if (typeof indent === "undefined") { indent = Camel.increaseIndent(""); }
        var folder = treeNode.data || treeNode;
        var count = 0;
        var parentName = getFolderCamelNodeId(folder);
        if (folder) {
            if (!xmlNode) {
                xmlNode = document.createElement(parentName);
                var rootJson = Camel.getRouteFolderJSON(folder);
                if (rootJson) {
                    Camel.setRouteNodeJSON(xmlNode, rootJson, indent);
                }
            }
            var doc = xmlNode.ownerDocument || document;
            var namespaceURI = xmlNode.namespaceURI;
            var from = parentName !== "route";
            var childIndent = Camel.increaseIndent(indent);
            angular.forEach(treeNode.children || treeNode.getChildren(), function (childTreeNode) {
                var childFolder = childTreeNode.data || childTreeNode;
                var name = Camel.getFolderCamelNodeId(childFolder);
                var json = Camel.getRouteFolderJSON(childFolder);
                if (name && json) {
                    var language = false;
                    if (name === "endpoint") {
                        if (from) {
                            name = "to";
                        } else {
                            name = "from";
                            from = true;
                        }
                    }
                    if (name === "expression") {
                        var languageName = json["language"];
                        if (languageName) {
                            name = languageName;
                            language = true;
                        }
                    }
                    xmlNode.appendChild(doc.createTextNode("\n" + childIndent));
                    var newNode = doc.createElementNS(namespaceURI, name);
                    Camel.setRouteNodeJSON(newNode, json, childIndent);
                    xmlNode.appendChild(newNode);
                    count += 1;
                    createFolderXmlTree(childTreeNode, newNode, childIndent);
                }
            });
            if (count) {
                xmlNode.appendChild(doc.createTextNode("\n" + indent));
            }
        }
        return xmlNode;
    }
    Camel.createFolderXmlTree = createFolderXmlTree;
    function updateRouteNodeLabelAndTooltip(folder, routeXmlNode, nodeSettings) {
        var localName = routeXmlNode.localName;
        var id = routeXmlNode.getAttribute("id");
        var label = nodeSettings["title"] || localName;
        var tooltip = nodeSettings["tooltip"] || nodeSettings["description"] || label;
        if (id) {
            label = id;
        } else {
            var uri = getRouteNodeUri(routeXmlNode);
            if (uri) {
                label = uri;
                var split = uri.split("?");
                if (split && split.length > 1) {
                    label = split[0];
                }
                tooltip += " " + uri;
            } else {
                var children = $(routeXmlNode).children("*");
                if (children && children.length) {
                    var child = children[0];
                    var childName = child.localName;
                    var expression = null;
                    if (Camel.isCamelLanguage(childName)) {
                        expression = child.textContent;
                        if (!expression) {
                            expression = child.getAttribute("expression");
                        }
                    }
                    if (expression) {
                        label += " " + expression;
                        tooltip += " " + childName + " expression";
                    }
                }
            }
        }
        folder.title = label;
        folder.tooltip = tooltip;
        return label;
    }
    Camel.updateRouteNodeLabelAndTooltip = updateRouteNodeLabelAndTooltip;
    function getSelectionCamelContextMBean(workspace) {
        if (workspace) {
            var contextId = getContextId(workspace);
            var selection = workspace.selection;
            var tree = workspace.tree;
            if (tree && selection) {
                var domain = selection.domain;
                if (domain && contextId) {
                    var result = tree.navigate(domain, contextId, "context");
                    if (result && result.children) {
                        var contextBean = result.children.first();
                        if (contextBean.title) {
                            var contextName = contextBean.title;
                            return "" + domain + ":context=" + contextId + ',type=context,name="' + contextName + '"';
                        }
                    }
                }
            }
        }
        return null;
    }
    Camel.getSelectionCamelContextMBean = getSelectionCamelContextMBean;
    function getSelectionCamelContextEndpoints(workspace) {
        if (workspace) {
            var contextId = getContextId(workspace);
            var selection = workspace.selection;
            var tree = workspace.tree;
            if (tree && selection) {
                var domain = selection.domain;
                if (domain && contextId) {
                    return tree.navigate(domain, contextId, "endpoints");
                }
            }
        }
        return null;
    }
    Camel.getSelectionCamelContextEndpoints = getSelectionCamelContextEndpoints;
    function getSelectionCamelTraceMBean(workspace) {
        if (workspace) {
            var contextId = getContextId(workspace);
            var selection = workspace.selection;
            var tree = workspace.tree;
            if (tree && selection) {
                var domain = selection.domain;
                if (domain && contextId) {
                    var result = tree.navigate(domain, contextId, "tracer");
                    if (result && result.children) {
                        var mbean = result.children.find(function (m) {
                            return m.title.startsWith("BacklogTracer");
                        });
                        if (mbean) {
                            return mbean.objectName;
                        }
                    }
                    var fabricResult = tree.navigate(domain, contextId, "fabric");
                    if (fabricResult && fabricResult.children) {
                        var mbean = fabricResult.children.first();
                        return mbean.objectName;
                    }
                }
            }
        }
        return null;
    }
    Camel.getSelectionCamelTraceMBean = getSelectionCamelTraceMBean;
    function getSelectionCamelDebugMBean(workspace) {
        if (workspace) {
            var contextId = getContextId(workspace);
            var selection = workspace.selection;
            var tree = workspace.tree;
            if (tree && selection) {
                var domain = selection.domain;
                if (domain && contextId) {
                    var result = tree.navigate(domain, contextId, "tracer");
                    if (result && result.children) {
                        var mbean = result.children.find(function (m) {
                            return m.title.startsWith("BacklogDebugger");
                        });
                        if (mbean) {
                            return mbean.objectName;
                        }
                    }
                }
            }
        }
        return null;
    }
    Camel.getSelectionCamelDebugMBean = getSelectionCamelDebugMBean;
    function getContextId(workspace) {
        var selection = workspace.selection;
        if (selection) {
            var tree = workspace.tree;
            var folderNames = selection.folderNames;
            var entries = selection.entries;
            var contextId;
            if (tree) {
                if (folderNames && folderNames.length > 1) {
                    contextId = folderNames[1];
                } else if (entries) {
                    contextId = entries["context"];
                }
            }
        }
        return contextId;
    }
    Camel.getContextId = getContextId;
    function isState(item, state) {
        var value = (item.State || "").toLowerCase();
        if (angular.isArray(state)) {
            return state.any(function (stateText) {
                return value.startsWith(stateText);
            });
        } else {
            return value.startsWith(state);
        }
    }
    Camel.isState = isState;
    function iconClass(state) {
        if (state) {
            switch(state.toLowerCase()) {
                case 'started':
                    return "green icon-play-circle";
                case 'suspended':
                    return "icon-pause";
            }
        }
        return "orange icon-off";
    }
    Camel.iconClass = iconClass;
    function getSelectedRouteId(workspace, folder) {
        if (typeof folder === "undefined") { folder = null; }
        var selection = folder || workspace.selection;
        var selectedRouteId = null;
        if (selection) {
            if (selection && selection.entries) {
                var typeName = selection.entries["type"];
                var name = selection.entries["name"];
                if ("routes" === typeName && name) {
                    selectedRouteId = trimQuotes(name);
                }
            }
        }
        return selectedRouteId;
    }
    Camel.getSelectedRouteId = getSelectedRouteId;
    function getSelectionRouteMBean(workspace, routeId) {
        if (workspace) {
            var contextId = getContextId(workspace);
            var selection = workspace.selection;
            var tree = workspace.tree;
            if (tree && selection) {
                var domain = selection.domain;
                if (domain && contextId) {
                    var result = tree.navigate(domain, contextId, "routes");
                    if (result && result.children) {
                        var mbean = result.children.find(function (m) {
                            return m.title === routeId;
                        });
                        if (mbean) {
                            return mbean.objectName;
                        }
                    }
                }
            }
        }
        return null;
    }
    Camel.getSelectionRouteMBean = getSelectionRouteMBean;
    function getCamelVersion(workspace, jolokia) {
        var mbean = getSelectionCamelContextMBean(workspace);
        if (mbean) {
            return jolokia.getAttribute(mbean, "CamelVersion", onSuccess(null));
        } else {
            return null;
        }
    }
    Camel.getCamelVersion = getCamelVersion;
    function createMessageFromXml(exchange) {
        var exchangeElement = $(exchange);
        var uid = exchangeElement.children("uid").text();
        var timestamp = exchangeElement.children("timestamp").text();
        var messageData = {
            headers: {},
            headerTypes: {},
            id: null,
            uid: uid,
            timestamp: timestamp,
            headerHtml: ""
        };
        var message = exchangeElement.children("message")[0];
        if (!message) {
            message = exchange;
        }
        var messageElement = $(message);
        var headers = messageElement.find("header");
        var headerHtml = "";
        headers.each(function (idx, header) {
            var key = header.getAttribute("key");
            var typeName = header.getAttribute("type");
            var value = header.textContent;
            if (key) {
                if (value) {
                    messageData.headers[key] = value;
                }
                if (typeName) {
                    messageData.headerTypes[key] = typeName;
                }
                headerHtml += "<tr><td class='property-name'>" + key + "</td>" + "<td class='property-value'>" + (value || "") + "</td></tr>";
            }
        });
        messageData.headerHtml = headerHtml;
        var id = messageData.headers["breadcrumbId"];
        if (!id) {
            var postFixes = [
                "MessageID", 
                "ID", 
                "Path", 
                "Name"
            ];
            angular.forEach(postFixes, function (postfix) {
                if (!id) {
                    angular.forEach(messageData.headers, function (value, key) {
                        if (!id && key.endsWith(postfix)) {
                            id = value;
                        }
                    });
                }
            });
            angular.forEach(messageData.headers, function (value, key) {
                if (!id) {
                    id = value;
                }
            });
        }
        messageData.id = id;
        var body = messageElement.children("body")[0];
        if (body) {
            var bodyText = body.textContent;
            var bodyType = body.getAttribute("type");
            messageData["body"] = bodyText;
            messageData["bodyType"] = bodyType;
        }
        return messageData;
    }
    Camel.createMessageFromXml = createMessageFromXml;
    function createBrowseGridOptions() {
        return {
            selectedItems: [],
            data: 'messages',
            displayFooter: false,
            showFilter: false,
            showColumnMenu: true,
            enableColumnResize: true,
            enableColumnReordering: true,
            filterOptions: {
                filterText: ''
            },
            selectWithCheckboxOnly: true,
            showSelectionCheckbox: true,
            maintainColumnRatios: false,
            columnDefs: [
                {
                    field: 'id',
                    displayName: 'ID',
                    cellTemplate: '<div class="ngCellText"><a ng-click="openMessageDialog(row)">{{row.entity.id}}</a></div>'
                }
            ]
        };
    }
    Camel.createBrowseGridOptions = createBrowseGridOptions;
    function loadRouteXmlNodes($scope, doc, selectedRouteId, nodes, links, width) {
        var allRoutes = $(doc).find("route");
        var routeDelta = width / allRoutes.length;
        var rowX = 0;
        allRoutes.each(function (idx, route) {
            var routeId = route.getAttribute("id");
            if (!selectedRouteId || !routeId || selectedRouteId === routeId) {
                Camel.addRouteXmlChildren($scope, route, nodes, links, null, rowX, 0);
                rowX += routeDelta;
            }
        });
    }
    Camel.loadRouteXmlNodes = loadRouteXmlNodes;
    function addRouteXmlChildren($scope, parent, nodes, links, parentId, parentX, parentY, parentNode) {
        if (typeof parentNode === "undefined") { parentNode = null; }
        var delta = 150;
        var x = parentX;
        var y = parentY + delta;
        var rid = parent.getAttribute("id");
        var siblingNodes = [];
        var parenNodeName = parent.localName;
        $(parent).children().each(function (idx, route) {
            var id = nodes.length;
            var nodeId = route.localName;
            if (nodeId === "from" && !parentId) {
                parentId = id;
            }
            var nodeSettings = getCamelSchema(nodeId);
            var node = null;
            if (nodeSettings) {
                var label = nodeSettings["title"] || nodeId;
                var uri = getRouteNodeUri(route);
                if (uri) {
                    label += " " + uri.split("?")[0];
                }
                var tooltip = nodeSettings["tooltip"] || nodeSettings["description"] || label;
                if (uri) {
                    tooltip += " " + uri;
                }
                var elementID = route.getAttribute("id");
                var labelSummary = label;
                if (elementID) {
                    var customId = route.getAttribute("customId");
                    if ($scope.camelIgnoreIdForLabel || (!customId || customId === "false")) {
                        labelSummary = "id: " + elementID;
                    } else {
                        label = elementID;
                    }
                }
                var labelLimit = $scope.camelMaximumLabelWidth || Camel.defaultMaximumLabelWidth;
                var length = label.length;
                if (length > labelLimit) {
                    labelSummary = label + "\n\n" + labelSummary;
                    label = label.substring(0, labelLimit) + "..";
                }
                var imageUrl = getRouteNodeIcon(nodeSettings);
                if ((nodeId === "from" || nodeId === "to") && uri) {
                    var idx = uri.indexOf(":");
                    if (idx > 0) {
                        var componentScheme = uri.substring(0, idx);
                        if (componentScheme) {
                            var value = Camel.getEndpointIcon(componentScheme);
                            if (value) {
                                imageUrl = url(value);
                            }
                        }
                    }
                }
                var cid = route.getAttribute("_cid") || route.getAttribute("id");
                node = {
                    "name": name,
                    "label": label,
                    "labelSummary": labelSummary,
                    "group": 1,
                    "id": id,
                    "elementId": elementID,
                    "x": x,
                    "y:": y,
                    "imageUrl": imageUrl,
                    "cid": cid,
                    "tooltip": tooltip
                };
                if (rid) {
                    node["rid"] = rid;
                    if (!$scope.routeNodes) {
                        $scope.routeNodes = {};
                    }
                    $scope.routeNodes[rid] = node;
                }
                if (!cid) {
                    cid = nodeId + (nodes.length + 1);
                }
                if (cid) {
                    node["cid"] = cid;
                    if (!$scope.nodes) {
                        $scope.nodes = {};
                    }
                    $scope.nodes[cid] = node;
                }
                rid = null;
                nodes.push(node);
                if (parentId !== null && parentId !== id) {
                    if (siblingNodes.length === 0 || parenNodeName === "choice") {
                        links.push({
                            "source": parentId,
                            "target": id,
                            "value": 1
                        });
                    } else {
                        siblingNodes.forEach(function (nodeId) {
                            links.push({
                                "source": nodeId,
                                "target": id,
                                "value": 1
                            });
                        });
                        siblingNodes.length = 0;
                    }
                }
            } else {
                var langSettings = Camel.camelLanguageSettings(nodeId);
                if (langSettings && parentNode) {
                    var name = langSettings["name"] || nodeId;
                    var text = route.textContent;
                    if (text) {
                        parentNode["tooltip"] = parentNode["label"] + " " + name + " " + text;
                        parentNode["label"] = text;
                    } else {
                        parentNode["label"] = parentNode["label"] + " " + name;
                    }
                }
            }
            var siblings = addRouteXmlChildren($scope, route, nodes, links, id, x, y, node);
            if (parenNodeName === "choice") {
                siblingNodes = siblingNodes.concat(siblings);
                x += delta;
            } else if (nodeId === "choice") {
                siblingNodes = siblings;
                y += delta;
            } else {
                siblingNodes = [
                    nodes.length - 1
                ];
                y += delta;
            }
        });
        return siblingNodes;
    }
    Camel.addRouteXmlChildren = addRouteXmlChildren;
    function getCanvasHeight(canvasDiv) {
        var height = canvasDiv.height();
        if (height < 300) {
            console.log("browse thinks the height is only " + height + " so calculating offset from doc height");
            var offset = canvasDiv.offset();
            height = $(document).height() - 5;
            if (offset) {
                var top = offset['top'];
                if (top) {
                    height -= top;
                }
            }
        }
        return height;
    }
    Camel.getCanvasHeight = getCanvasHeight;
    function addFoldersToIndex(folder, map) {
        if (typeof map === "undefined") { map = {}; }
        if (folder) {
            var key = folder.key;
            if (key) {
                map[key] = folder;
            }
            angular.forEach(folder.children, function (child) {
                return addFoldersToIndex(child, map);
            });
        }
        return map;
    }
    Camel.addFoldersToIndex = addFoldersToIndex;
    function generateXmlFromFolder(treeNode) {
        var folder = (treeNode && treeNode.data) ? treeNode.data : treeNode;
        if (!folder) {
            return null;
        }
        var doc = folder["xmlDocument"];
        var context = folder["routeXmlNode"];
        if (context && context.length) {
            var element = context[0];
            var children = element.childNodes;
            var routeIndices = [];
            for(var i = 0; i < children.length; i++) {
                var node = children[i];
                var name = node.localName;
                if ("route" === name && parent) {
                    routeIndices.push(i);
                }
            }
            while(routeIndices.length) {
                var idx = routeIndices.pop();
                var nextIndex = idx + 1;
                while(true) {
                    var node = element.childNodes[nextIndex];
                    if (Core.isTextNode(node)) {
                        element.removeChild(node);
                    } else {
                        break;
                    }
                }
                if (idx < element.childNodes.length) {
                    element.removeChild(element.childNodes[idx]);
                }
                for(var i = idx - 1; i >= 0; i--) {
                    var node = element.childNodes[i];
                    if (Core.isTextNode(node)) {
                        element.removeChild(node);
                    } else {
                        break;
                    }
                }
            }
            Camel.createFolderXmlTree(treeNode, context[0]);
        }
        return doc;
    }
    Camel.generateXmlFromFolder = generateXmlFromFolder;
    function camelContextMBeansById(workspace) {
        var answer = {};
        var tree = workspace.tree;
        if (tree) {
            var camelTree = tree.navigate(Camel.jmxDomain);
            if (camelTree) {
                angular.forEach(camelTree.children, function (contextsFolder) {
                    var contextFolder = contextsFolder.navigate("context");
                    if (contextFolder && contextFolder.children && contextFolder.children.length) {
                        var contextItem = contextFolder.children[0];
                        var id = Core.pathGet(contextItem, [
                            "entries", 
                            "name"
                        ]) || contextItem.key;
                        if (id) {
                            answer[id] = {
                                folder: contextItem,
                                mbean: contextItem.objectName
                            };
                        }
                    }
                });
            }
        }
        return answer;
    }
    Camel.camelContextMBeansById = camelContextMBeansById;
    function camelContextMBeansByComponentName(workspace) {
        return camelContextMBeansByRouteOrComponentId(workspace, "components");
    }
    Camel.camelContextMBeansByComponentName = camelContextMBeansByComponentName;
    function camelContextMBeansByRouteId(workspace) {
        return camelContextMBeansByRouteOrComponentId(workspace, "routes");
    }
    Camel.camelContextMBeansByRouteId = camelContextMBeansByRouteId;
    function camelContextMBeansByRouteOrComponentId(workspace, componentsOrRoutes) {
        var answer = {};
        var tree = workspace.tree;
        if (tree) {
            var camelTree = tree.navigate(Camel.jmxDomain);
            if (camelTree) {
                angular.forEach(camelTree.children, function (contextsFolder) {
                    var contextFolder = contextsFolder.navigate("context");
                    var componentsFolder = contextsFolder.navigate(componentsOrRoutes);
                    if (contextFolder && componentsFolder && contextFolder.children && contextFolder.children.length) {
                        var contextItem = contextFolder.children[0];
                        var mbean = contextItem.objectName;
                        if (mbean) {
                            var contextValues = {
                                folder: contextItem,
                                mbean: mbean
                            };
                            angular.forEach(componentsFolder.children, function (componentFolder) {
                                var id = componentFolder.title;
                                if (id) {
                                    answer[id] = contextValues;
                                }
                            });
                        }
                    }
                });
            }
        }
        return answer;
    }
    function ignoreIdForLabel(localStorage) {
        var value = localStorage["camelIgnoreIdForLabel"];
        return value && (value === "true" || value === true);
    }
    Camel.ignoreIdForLabel = ignoreIdForLabel;
    function maximumLabelWidth(localStorage) {
        var value = localStorage["camelMaximumLabelWidth"];
        if (angular.isString(value)) {
            value = parseInt(value);
        }
        if (!value) {
            value = Camel.defaultMaximumLabelWidth;
        }
        return value;
    }
    Camel.maximumLabelWidth = maximumLabelWidth;
    function maximumTraceOrDebugBodyLength(localStorage) {
        var value = localStorage["camelMaximumTraceOrDebugBodyLength"];
        if (angular.isString(value)) {
            value = parseInt(value);
        }
        if (!value) {
            value = Camel.defaultCamelMaximumTraceOrDebugBodyLength;
        }
        return value;
    }
    Camel.maximumTraceOrDebugBodyLength = maximumTraceOrDebugBodyLength;
})(Camel || (Camel = {}));
var Jmx;
(function (Jmx) {
    Jmx.log = Logger.get("JMX");
    var attributesToolBars = {};
    Jmx.lazyLoaders = {};
    function findLazyLoadingFunction(workspace, folder) {
        var factories = workspace.jmxTreeLazyLoadRegistry[folder.domain];
        var lazyFunction = null;
        if (factories && factories.length) {
            angular.forEach(factories, function (customLoader) {
                if (!lazyFunction) {
                    lazyFunction = customLoader(folder);
                }
            });
        }
        return lazyFunction;
    }
    Jmx.findLazyLoadingFunction = findLazyLoadingFunction;
    function registerLazyLoadHandler(domain, lazyLoaderFactory) {
        if (!Jmx.lazyLoaders) {
            Jmx.lazyLoaders = {};
        }
        var array = Jmx.lazyLoaders[domain];
        if (!array) {
            array = [];
            Jmx.lazyLoaders[domain] = array;
        }
        array.push(lazyLoaderFactory);
    }
    Jmx.registerLazyLoadHandler = registerLazyLoadHandler;
    function unregisterLazyLoadHandler(domain, lazyLoaderFactory) {
        if (Jmx.lazyLoaders) {
            var array = Jmx.lazyLoaders[domain];
            if (array) {
                array.remove(lazyLoaderFactory);
            }
        }
    }
    Jmx.unregisterLazyLoadHandler = unregisterLazyLoadHandler;
    function addAttributeToolBar(pluginName, jmxDomain, fn) {
        var array = attributesToolBars[jmxDomain];
        if (!array) {
            array = [];
            attributesToolBars[jmxDomain] = array;
        }
        array.push(fn);
    }
    Jmx.addAttributeToolBar = addAttributeToolBar;
    function getAttributeToolBar(node, defaultValue) {
        if (typeof defaultValue === "undefined") { defaultValue = "app/jmx/html/attributeToolBar.html"; }
        var answer = null;
        var jmxDomain = (node) ? node.domain : null;
        if (jmxDomain) {
            var array = attributesToolBars[jmxDomain];
            if (array) {
                for(var idx in array) {
                    var fn = array[idx];
                    answer = fn(node);
                    if (answer) {
                        break;
                    }
                }
            }
        }
        return (answer) ? answer : defaultValue;
    }
    Jmx.getAttributeToolBar = getAttributeToolBar;
    function updateTreeSelectionFromURL($location, treeElement, activateIfNoneSelected) {
        if (typeof activateIfNoneSelected === "undefined") { activateIfNoneSelected = false; }
        var dtree = treeElement.dynatree("getTree");
        if (dtree) {
            var node = null;
            var key = $location.search()['nid'];
            if (key) {
                try  {
                    node = dtree.activateKey(key);
                } catch (e) {
                }
            }
            if (node) {
                node.expand(true);
            } else {
                if (!treeElement.dynatree("getActiveNode")) {
                    var root = treeElement.dynatree("getRoot");
                    var children = root ? root.getChildren() : null;
                    if (children && children.length) {
                        var first = children[0];
                        first.expand(true);
                        if (activateIfNoneSelected) {
                            first.activate();
                        }
                    }
                }
            }
        }
    }
    Jmx.updateTreeSelectionFromURL = updateTreeSelectionFromURL;
    function getUniqueTypeNames(children) {
        var typeNameMap = {};
        angular.forEach(children, function (mbean) {
            var typeName = mbean.typeName;
            if (typeName) {
                typeNameMap[typeName] = mbean;
            }
        });
        var typeNames = Object.keys(typeNameMap);
        return typeNames;
    }
    Jmx.getUniqueTypeNames = getUniqueTypeNames;
    function enableTree($scope, $location, workspace, treeElement, children, redraw, onActivateFn) {
        if (typeof redraw === "undefined") { redraw = false; }
        if (typeof onActivateFn === "undefined") { onActivateFn = null; }
        if (treeElement.length) {
            if (!onActivateFn) {
                onActivateFn = function (node) {
                    var data = node.data;
                    workspace.updateSelectionNode(data);
                    Core.$apply($scope);
                };
            }
            workspace.treeElement = treeElement;
            treeElement.dynatree({
                onActivate: onActivateFn,
                onLazyRead: function (treeNode) {
                    var folder = treeNode.data;
                    var plugin = null;
                    if (folder) {
                        plugin = Jmx.findLazyLoadingFunction(workspace, folder);
                    }
                    if (plugin) {
                        console.log("Lazy loading folder " + folder.title);
                        var oldChildren = folder.childen;
                        plugin(workspace, folder, function () {
                            treeNode.setLazyNodeStatus(DTNodeStatus_Ok);
                            var newChildren = folder.children;
                            if (newChildren !== oldChildren) {
                                treeNode.removeChildren();
                                angular.forEach(newChildren, function (newChild) {
                                    treeNode.addChild(newChild);
                                });
                            }
                        });
                    } else {
                        treeNode.setLazyNodeStatus(DTNodeStatus_Ok);
                    }
                },
                onClick: function (node, event) {
                    if (event["metaKey"]) {
                        event.preventDefault();
                        var url = $location.absUrl();
                        if (node && node.data) {
                            var key = node.data["key"];
                            if (key) {
                                var hash = $location.search();
                                hash["nid"] = key;
                                var idx = url.indexOf('?');
                                if (idx <= 0) {
                                    url += "?";
                                } else {
                                    url = url.substring(0, idx + 1);
                                }
                                url += $.param(hash);
                            }
                        }
                        window.open(url, '_blank');
                        window.focus();
                        return false;
                    }
                    return true;
                },
                persist: false,
                debugLevel: 0,
                children: children
            });
            if (redraw) {
                workspace.redrawTree();
            }
        }
    }
    Jmx.enableTree = enableTree;
})(Jmx || (Jmx = {}));
var Camel;
(function (Camel) {
    var jmxModule = Jmx;
    var pluginName = 'camel';
    Camel.jmxDomain = 'org.apache.camel';
    var routeToolBar = "app/camel/html/attributeToolBarRoutes.html";
    var contextToolBar = "app/camel/html/attributeToolBarContext.html";
    angular.module(pluginName, [
        'bootstrap', 
        'ui.bootstrap', 
        'ui.bootstrap.dialog', 
        'ui.bootstrap.tabs', 
        'ui.bootstrap.typeahead', 
        'ngResource', 
        'hawtioCore', 
        'hawtio-ui'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/camel/browseEndpoint', {
            templateUrl: 'app/camel/html/browseEndpoint.html'
        }).when('/camel/createEndpoint', {
            templateUrl: 'app/camel/html/createEndpoint.html'
        }).when('/camel/routes', {
            templateUrl: 'app/camel/html/routes.html'
        }).when('/camel/sendMessage', {
            templateUrl: 'app/camel/html/sendMessage.html',
            reloadOnSearch: false
        }).when('/camel/source', {
            templateUrl: 'app/camel/html/source.html'
        }).when('/camel/traceRoute', {
            templateUrl: 'app/camel/html/traceRoute.html'
        }).when('/camel/debugRoute', {
            templateUrl: 'app/camel/html/debug.html'
        }).when('/camel/profileRoute', {
            templateUrl: 'app/camel/html/profileRoute.html'
        }).when('/camel/properties', {
            templateUrl: 'app/camel/html/properties.html'
        });
    }).filter('camelIconClass', function () {
        return Camel.iconClass;
    }).run(function (workspace, jolokia, viewRegistry, helpRegistry) {
        viewRegistry['camel'] = 'app/camel/html/layoutCamelTree.html';
        helpRegistry.addUserDoc('camel', 'app/camel/doc/help.md', function () {
            return workspace.treeContainsDomainAndProperties(Camel.jmxDomain);
        });
        Jmx.addAttributeToolBar(pluginName, Camel.jmxDomain, function (selection) {
            var typeName = selection.typeName;
            if (typeName) {
                if (typeName.startsWith("context")) {
                    return contextToolBar;
                }
                if (typeName.startsWith("route")) {
                    return routeToolBar;
                }
            }
            var folderNames = selection.folderNames;
            if (folderNames && selection.domain === Camel.jmxDomain) {
                var last = folderNames.last();
                if ("routes" === last) {
                    return routeToolBar;
                }
                if ("context" === last) {
                    return contextToolBar;
                }
            }
            return null;
        });
        var stateTemplate = '<div class="ngCellText pagination-centered" title="{{row.getProperty(col.field)}}"><i class="{{row.getProperty(col.field) | camelIconClass}}"></i></div>';
        var stateColumn = {
            field: 'State',
            displayName: 'State',
            cellTemplate: stateTemplate,
            width: 56,
            minWidth: 56,
            maxWidth: 56,
            resizable: false
        };
        var attributes = workspace.attributeColumnDefs;
        attributes[Camel.jmxDomain + "/context/folder"] = [
            stateColumn, 
            {
                field: 'CamelId',
                displayName: 'Context'
            }, 
            {
                field: 'Uptime',
                displayName: 'Uptime',
                visible: false
            }, 
            {
                field: 'CamelVersion',
                displayName: 'Version',
                visible: false
            }, 
            {
                field: 'ExchangesCompleted',
                displayName: 'Completed #'
            }, 
            {
                field: 'ExchangesFailed',
                displayName: 'Failed #'
            }, 
            {
                field: 'ExchangesTotal',
                displayName: 'Total #',
                visible: false
            }, 
            {
                field: 'InflightExchanges',
                displayName: 'Inflight #'
            }, 
            {
                field: 'MeanProcessingTime',
                displayName: 'Mean Time'
            }, 
            {
                field: 'MinProcessingTime',
                displayName: 'Min Time'
            }, 
            {
                field: 'MaxProcessingTime',
                displayName: 'Max Time'
            }, 
            {
                field: 'TotalProcessingTime',
                displayName: 'Total Time',
                visible: false
            }, 
            {
                field: 'DeltaProcessingTime',
                displayName: 'Delta Time',
                visible: false
            }, 
            {
                field: 'LastExchangeCompletedTimestamp',
                displayName: 'Last completed',
                visible: false
            }, 
            {
                field: 'LastExchangeFailedTimestamp',
                displayName: 'Last failed',
                visible: false
            }
        ];
        attributes[Camel.jmxDomain + "/routes/folder"] = [
            stateColumn, 
            {
                field: 'CamelId',
                displayName: 'Context'
            }, 
            {
                field: 'RouteId',
                displayName: 'Route'
            }, 
            {
                field: 'ExchangesCompleted',
                displayName: 'Completed #'
            }, 
            {
                field: 'ExchangesFailed',
                displayName: 'Failed #'
            }, 
            {
                field: 'ExchangesTotal',
                displayName: 'Total #',
                visible: false
            }, 
            {
                field: 'InflightExchanges',
                displayName: 'Inflight #'
            }, 
            {
                field: 'MeanProcessingTime',
                displayName: 'Mean Time'
            }, 
            {
                field: 'MinProcessingTime',
                displayName: 'Min Time'
            }, 
            {
                field: 'MaxProcessingTime',
                displayName: 'Max Time'
            }, 
            {
                field: 'TotalProcessingTime',
                displayName: 'Total Time',
                visible: false
            }, 
            {
                field: 'DeltaProcessingTime',
                displayName: 'Delta Time',
                visible: false
            }, 
            {
                field: 'LastExchangeCompletedTimestamp',
                displayName: 'Last completed',
                visible: false
            }, 
            {
                field: 'LastExchangeFailedTimestamp',
                displayName: 'Last failed',
                visible: false
            }
        ];
        attributes[Camel.jmxDomain + "/processors/folder"] = [
            stateColumn, 
            {
                field: 'CamelId',
                displayName: 'Context'
            }, 
            {
                field: 'RouteId',
                displayName: 'Route'
            }, 
            {
                field: 'ProcessorId',
                displayName: 'Processor'
            }, 
            {
                field: 'ExchangesCompleted',
                displayName: 'Completed #'
            }, 
            {
                field: 'ExchangesFailed',
                displayName: 'Failed #'
            }, 
            {
                field: 'ExchangesTotal',
                displayName: 'Total #',
                visible: false
            }, 
            {
                field: 'InflightExchanges',
                displayName: 'Inflight #'
            }, 
            {
                field: 'MeanProcessingTime',
                displayName: 'Mean Time'
            }, 
            {
                field: 'MinProcessingTime',
                displayName: 'Min Time'
            }, 
            {
                field: 'MaxProcessingTime',
                displayName: 'Max Time'
            }, 
            {
                field: 'TotalProcessingTime',
                displayName: 'Total Time',
                visible: false
            }, 
            {
                field: 'DeltaProcessingTime',
                displayName: 'Delta Time',
                visible: false
            }, 
            {
                field: 'LastExchangeCompletedTimestamp',
                displayName: 'Last completed',
                visible: false
            }, 
            {
                field: 'LastExchangeFailedTimestamp',
                displayName: 'Last failed',
                visible: false
            }
        ];
        attributes[Camel.jmxDomain + "/components/folder"] = [
            stateColumn, 
            {
                field: 'CamelId',
                displayName: 'Context'
            }, 
            {
                field: 'ComponentName',
                displayName: 'Name'
            }
        ];
        attributes[Camel.jmxDomain + "/consumers/folder"] = [
            stateColumn, 
            {
                field: 'CamelId',
                displayName: 'Context'
            }, 
            {
                field: 'RouteId',
                displayName: 'Route'
            }, 
            {
                field: 'EndpointUri',
                displayName: 'Endpoint URI',
                width: "**"
            }, 
            {
                field: 'Suspended',
                displayName: 'Suspended',
                resizable: false
            }, 
            {
                field: 'InflightExchanges',
                displayName: 'Inflight #'
            }
        ];
        attributes[Camel.jmxDomain + "/services/folder"] = [
            stateColumn, 
            {
                field: 'CamelId',
                displayName: 'Context'
            }, 
            {
                field: 'RouteId',
                displayName: 'Route'
            }, 
            {
                field: 'Suspended',
                displayName: 'Suspended',
                resizable: false
            }, 
            {
                field: 'SupportsSuspended',
                displayName: 'Can Suspend',
                resizable: false
            }
        ];
        attributes[Camel.jmxDomain + "/endpoints/folder"] = [
            stateColumn, 
            {
                field: 'CamelId',
                displayName: 'Context'
            }, 
            {
                field: 'EndpointUri',
                displayName: 'Endpoint URI',
                width: "***"
            }, 
            {
                field: 'Singleton',
                displayName: 'Singleton',
                resizable: false
            }
        ];
        attributes[Camel.jmxDomain + "/threadpools/folder"] = [
            {
                field: 'Id',
                displayName: 'Id',
                width: "**"
            }, 
            {
                field: 'ActiveCount',
                displayName: 'Active #'
            }, 
            {
                field: 'PoolSize',
                displayName: 'Pool Size'
            }, 
            {
                field: 'CorePoolSize',
                displayName: 'Core Pool Size'
            }, 
            {
                field: 'TaskQueueSize',
                displayName: 'Task Queue Size'
            }, 
            {
                field: 'TaskCount',
                displayName: 'Task #'
            }, 
            {
                field: 'CompletedTaskCount',
                displayName: 'Completed Task #'
            }
        ];
        attributes[Camel.jmxDomain + "/errorhandlers/folder"] = [
            {
                field: 'CamelId',
                displayName: 'Context'
            }, 
            {
                field: 'DeadLetterChannel',
                displayName: 'Dead Letter'
            }, 
            {
                field: 'DeadLetterChannelEndpointUri',
                displayName: 'Endpoint URI',
                width: "**",
                resizable: true
            }, 
            {
                field: 'MaximumRedeliveries',
                displayName: 'Max Redeliveries'
            }, 
            {
                field: 'RedeliveryDelay',
                displayName: 'Redelivery Delay'
            }, 
            {
                field: 'MaximumRedeliveryDelay',
                displayName: 'Max Redeliveries Delay'
            }
        ];
        workspace.topLevelTabs.push({
            id: "camel",
            content: "Camel",
            title: "Manage your Apache Camel applications",
            isValid: function (workspace) {
                return workspace.treeContainsDomainAndProperties(Camel.jmxDomain);
            },
            href: function () {
                return "#/jmx/attributes?tab=camel";
            },
            isActive: function (workspace) {
                return workspace.isTopTabActive("camel");
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-picture"></i> Diagram',
            title: "View a diagram of the Camel routes",
            isValid: function (workspace) {
                return workspace.isRoute();
            },
            href: function () {
                return "#/camel/routes";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class=" icon-file-alt"></i> Source',
            title: "View the source of the Camel routes",
            isValid: function (workspace) {
                return workspace.isRoute() || workspace.isRoutesFolder() || workspace.isCamelContext();
            },
            href: function () {
                return "#/camel/source";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class=" icon-edit"></i> Properties',
            title: "View the pattern properties",
            isValid: function (workspace) {
                return Camel.getSelectedRouteNode(workspace);
            },
            href: function () {
                return "#/camel/properties";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-envelope"></i> Browse',
            title: "Browse the messages on the endpoint",
            isValid: function (workspace) {
                return workspace.isEndpoint();
            },
            href: function () {
                return "#/camel/browseEndpoint";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-stethoscope"></i> Debug',
            title: "Debug the Camel route",
            isValid: function (workspace) {
                return workspace.isRoute() && Camel.getSelectionCamelDebugMBean(workspace);
            },
            href: function () {
                return "#/camel/debugRoute";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-envelope"></i> Trace',
            title: "Trace the messages flowing through the Camel route",
            isValid: function (workspace) {
                return workspace.isRoute() && Camel.getSelectionCamelTraceMBean(workspace);
            },
            href: function () {
                return "#/camel/traceRoute";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-bar-chart"></i> Profile',
            title: "Profile the messages flowing through the Camel route",
            isValid: function (workspace) {
                return workspace.isRoute() && Camel.getSelectionCamelTraceMBean(workspace);
            },
            href: function () {
                return "#/camel/profileRoute";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-pencil"></i> Send',
            title: "Send a message to this endpoint",
            isValid: function (workspace) {
                return workspace.isEndpoint();
            },
            href: function () {
                return "#/camel/sendMessage";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-plus"></i> Endpoint',
            title: "Create a new endpoint",
            isValid: function (workspace) {
                return workspace.isEndpointsFolder();
            },
            href: function () {
                return "#/camel/createEndpoint";
            }
        });
    });
    hawtioPluginLoader.addModule(pluginName);
    hawtioPluginLoader.loadPlugins(function () {
        jmxModule.registerLazyLoadHandler(Camel.jmxDomain, function (folder) {
            if (Camel.jmxDomain === folder.domain && "routes" === folder.typeName) {
                return function (workspace, folder, onComplete) {
                    if ("routes" === folder.typeName) {
                        Camel.processRouteXml(workspace, workspace.jolokia, folder, function (route) {
                            if (route) {
                                Camel.addRouteChildren(folder, route);
                            }
                            onComplete();
                        });
                    } else {
                        onComplete();
                    }
                };
            }
            return null;
        });
    });
})(Camel || (Camel = {}));
var Camel;
(function (Camel) {
    function DebugRouteController($scope, $element, workspace, jolokia) {
        var _this = this;
        $scope.camelMaximumTraceOrDebugBodyLength = Camel.maximumTraceOrDebugBodyLength(localStorage);
        $scope.ignoreRouteXmlNode = true;
        $scope.startDebugging = function () {
            setDebugging(true);
        };
        $scope.stopDebugging = function () {
            setDebugging(false);
        };
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(reloadData, 50);
        });
        $scope.$on("camel.diagram.selectedNodeId", function (event, value) {
            $scope.selectedDiagramNodeId = value;
            updateBreakpointFlag();
        });
        $scope.$on("camel.diagram.layoutComplete", function (event, value) {
            updateBreakpointIcons();
            $($element).find("g.node").dblclick(function (n) {
                var id = this.getAttribute("data-cid");
                $scope.toggleBreakpoint(id);
            });
        });
        $scope.$watch('workspace.selection', function () {
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            reloadData();
        });
        $scope.toggleBreakpoint = function (id) {
            var mbean = Camel.getSelectionCamelDebugMBean(workspace);
            if (mbean && id) {
                var method = isBreakpointSet(id) ? "removeBreakpoint" : "addBreakpoint";
                jolokia.execute(mbean, method, id, onSuccess(breakpointsChanged));
            }
        };
        $scope.addBreakpoint = function () {
            var mbean = Camel.getSelectionCamelDebugMBean(workspace);
            if (mbean && $scope.selectedDiagramNodeId) {
                jolokia.execute(mbean, "addBreakpoint", $scope.selectedDiagramNodeId, onSuccess(breakpointsChanged));
            }
        };
        $scope.removeBreakpoint = function () {
            var mbean = Camel.getSelectionCamelDebugMBean(workspace);
            if (mbean && $scope.selectedDiagramNodeId) {
                jolokia.execute(mbean, "removeBreakpoint", $scope.selectedDiagramNodeId, onSuccess(breakpointsChanged));
            }
        };
        $scope.resume = function () {
            var mbean = Camel.getSelectionCamelDebugMBean(workspace);
            if (mbean) {
                jolokia.execute(mbean, "resumeAll", onSuccess(clearStoppedAndResume));
            }
        };
        $scope.suspend = function () {
            var mbean = Camel.getSelectionCamelDebugMBean(workspace);
            if (mbean) {
                jolokia.execute(mbean, "suspendAll", onSuccess(clearStoppedAndResume));
            }
        };
        $scope.step = function () {
            var mbean = Camel.getSelectionCamelDebugMBean(workspace);
            var stepNode = getStoppedBreakpointId();
            if (mbean && stepNode) {
                jolokia.execute(mbean, "stepBreakpoint(java.lang.String)", stepNode, onSuccess(clearStoppedAndResume));
            }
        };
        $scope.messages = [];
        $scope.mode = 'text';
        $scope.messageDialog = new Core.Dialog();
        $scope.gridOptions = Camel.createBrowseGridOptions();
        $scope.gridOptions.selectWithCheckboxOnly = false;
        $scope.gridOptions.showSelectionCheckbox = false;
        $scope.gridOptions.afterSelectionChange = onSelectionChanged;
        $scope.gridOptions.columnDefs.push({
            field: 'toNode',
            displayName: 'To Node'
        });
        $scope.openMessageDialog = function (message) {
            var idx = Core.pathGet(message, [
                "rowIndex"
            ]);
            $scope.selectRowIndex(idx);
            if ($scope.row) {
                var body = $scope.row.body;
                $scope.mode = angular.isString(body) ? CodeEditor.detectTextFormat(body) : "text";
                $scope.messageDialog.open();
            }
        };
        $scope.selectRowIndex = function (idx) {
            $scope.rowIndex = idx;
            var selected = $scope.gridOptions.selectedItems;
            selected.splice(0, selected.length);
            if (idx >= 0 && idx < $scope.messages.length) {
                $scope.row = $scope.messages[idx];
                if ($scope.row) {
                    selected.push($scope.row);
                }
            } else {
                $scope.row = null;
            }
            onSelectionChanged();
        };
        function onSelectionChanged() {
            var toNode = getStoppedBreakpointId();
            if (toNode) {
                var nodes = getDiagramNodes();
                nodes.attr("class", "node");
                nodes.filter(function (item) {
                    if (item) {
                        var cid = item["cid"];
                        var rid = item["rid"];
                        if (cid) {
                            return toNode === cid;
                        } else {
                            return toNode === rid;
                        }
                    }
                    return null;
                }).attr("class", "node selected");
            }
        }
        function reloadData() {
            $scope.debugging = false;
            var mbean = Camel.getSelectionCamelDebugMBean(workspace);
            if (mbean) {
                $scope.debugging = jolokia.getAttribute(mbean, "Enabled", onSuccess(null));
                if ($scope.debugging) {
                    jolokia.execute(mbean, "getBreakpoints", onSuccess(onBreakpoints));
                    $scope.graphView = "app/camel/html/routes.html";
                    $scope.tableView = "app/camel/html/browseMessages.html";
                    Core.register(jolokia, $scope, {
                        type: 'exec',
                        mbean: mbean,
                        operation: 'getDebugCounter'
                    }, onSuccess(onBreakpointCounter));
                } else {
                    $scope.graphView = null;
                    $scope.tableView = null;
                }
            }
        }
        function onBreakpointCounter(response) {
            var counter = response.value;
            if (counter && counter !== $scope.breakpointCounter) {
                $scope.breakpointCounter = counter;
                loadCurrentStack();
            }
        }
        function loadCurrentStack() {
            var mbean = Camel.getSelectionCamelDebugMBean(workspace);
            if (mbean) {
                console.log("getting suspended breakpoints!");
                jolokia.execute(mbean, "getSuspendedBreakpointNodeIds", onSuccess(onSuspendedBreakpointNodeIds));
            }
        }
        function onSuspendedBreakpointNodeIds(response) {
            var mbean = Camel.getSelectionCamelDebugMBean(workspace);
            $scope.suspendedBreakpoints = response;
            $scope.stopped = response && response.length;
            var stopNodeId = getStoppedBreakpointId();
            if (mbean && stopNodeId) {
                jolokia.execute(mbean, 'dumpTracedMessagesAsXml', stopNodeId, onSuccess(onMessages));
                $scope.selectedDiagramNodeId = stopNodeId;
            }
            updateBreakpointIcons();
            Core.$apply($scope);
        }
        function onMessages(response) {
            console.log("onMessage! ");
            $scope.messages = [];
            if (response) {
                var xml = response;
                if (angular.isString(xml)) {
                    var doc = $.parseXML(xml);
                    var allMessages = $(doc).find("fabricTracerEventMessage");
                    if (!allMessages || !allMessages.length) {
                        allMessages = $(doc).find("backlogTracerEventMessage");
                    }
                    allMessages.each(function (idx, message) {
                        var messageData = Camel.createMessageFromXml(message);
                        var toNode = $(message).find("toNode").text();
                        if (toNode) {
                            messageData["toNode"] = toNode;
                        }
                        $scope.messages.push(messageData);
                    });
                }
            } else {
                console.log("WARNING: dumpTracedMessagesAsXml() returned no results!");
            }
            updateMessageSelection();
            console.log("has messages " + $scope.messages.length + " selected row " + $scope.row + " index " + $scope.rowIndex);
            Core.$apply($scope);
            updateBreakpointIcons();
        }
        function updateMessageSelection() {
            $scope.selectRowIndex($scope.rowIndex);
            if (!$scope.row && $scope.messageDialog.show) {
                $scope.row = {
                    headers: {},
                    body: ""
                };
            }
        }
        function clearStoppedAndResume() {
            $scope.messages = [];
            $scope.suspendedBreakpoints = [];
            $scope.stopped = false;
            updateMessageSelection();
            Core.$apply($scope);
            updateBreakpointIcons();
        }
        function getStoppedBreakpointId() {
            var stepNode = null;
            var stepNodes = $scope.suspendedBreakpoints;
            if (stepNodes && stepNodes.length) {
                stepNode = stepNodes[0];
                if (stepNodes.length > 1 && isSuspendedAt($scope.selectedDiagramNodeId)) {
                    stepNode = $scope.selectedDiagramNodeId;
                }
            }
            return stepNode;
        }
        function isSuspendedAt(nodeId) {
            return containsNodeId($scope.suspendedBreakpoints, nodeId);
        }
        function onBreakpoints(response) {
            $scope.breakpoints = response;
            updateBreakpointFlag();
            var nodes = getDiagramNodes();
            if (nodes.length) {
                updateBreakpointIcons(nodes);
            }
            Core.$apply($scope);
        }
        function isBreakpointSet(nodeId) {
            return containsNodeId($scope.breakpoints, nodeId);
        }
        function updateBreakpointFlag() {
            $scope.hasBreakpoint = isBreakpointSet($scope.selectedDiagramNodeId);
        }
        function containsNodeId(breakpoints, nodeId) {
            return nodeId && breakpoints && breakpoints.some(nodeId);
        }
        function getDiagramNodes() {
            var svg = d3.select("svg");
            return svg.selectAll("g .node");
        }
        var breakpointImage = url("/app/camel/img/debug/breakpoint.gif");
        var suspendedBreakpointImage = url("/app/camel/img/debug/breakpoint-suspended.gif");
        function updateBreakpointIcons(nodes) {
            if (typeof nodes === "undefined") { nodes = getDiagramNodes(); }
            nodes.each(function (object) {
                var nodeId = object.cid;
                var thisNode = d3.select(this);
                var icons = thisNode.selectAll("image.breakpoint");
                var isSuspended = isSuspendedAt(nodeId);
                var isBreakpoint = isBreakpointSet(nodeId);
                if (isBreakpoint || isSuspended) {
                    var imageUrl = isSuspended ? suspendedBreakpointImage : breakpointImage;
                    if (!icons.length || !icons[0].length) {
                        thisNode.append("image").attr("xlink:href", function (d) {
                            return imageUrl;
                        }).attr("class", "breakpoint").attr("x", -12).attr("y", -20).attr("height", 24).attr("width", 24);
                    } else {
                        icons.attr("xlink:href", function (d) {
                            return imageUrl;
                        });
                    }
                } else {
                    icons.remove();
                }
            });
        }
        function breakpointsChanged(response) {
            reloadData();
            Core.$apply($scope);
        }
        function setDebugging(flag) {
            var mbean = Camel.getSelectionCamelDebugMBean(workspace);
            if (mbean) {
                var method = flag ? "enableDebugger" : "disableDebugger";
                var max = $scope.camelMaximumTraceOrDebugBodyLength;
                jolokia.setAttribute(mbean, "BodyMaxChars", max);
                jolokia.execute(mbean, method, onSuccess(breakpointsChanged));
            }
        }
    }
    Camel.DebugRouteController = DebugRouteController;
})(Camel || (Camel = {}));
var Camel;
(function (Camel) {
    function EndpointController($scope, $location, localStorage, workspace, jolokia) {
        Camel.initEndpointChooserScope($scope, $location, localStorage, workspace, jolokia);
        $scope.workspace = workspace;
        $scope.message = "";
        $scope.createEndpoint = function (name) {
            var jolokia = workspace.jolokia;
            if (jolokia) {
                var mbean = Camel.getSelectionCamelContextMBean(workspace);
                if (mbean) {
                    $scope.message = "Creating endpoint " + name;
                    var operation = "createEndpoint(java.lang.String)";
                    jolokia.execute(mbean, operation, name, onSuccess(operationSuccess));
                } else {
                    notification("error", "Could not find the CamelContext MBean!");
                }
            }
        };
        $scope.createEndpointFromData = function () {
            if ($scope.selectedComponentName && $scope.endpointPath) {
                var name = $scope.selectedComponentName + "://" + $scope.endpointPath;
                console.log("Have endpoint data " + JSON.stringify($scope.endpointParameters));
                var params = "";
                angular.forEach($scope.endpointParameters, function (value, key) {
                    var prefix = params ? "&" : "";
                    params += prefix + key + "=" + value;
                });
                if (params) {
                    name += "?" + params;
                }
                $scope.createEndpoint(name);
            }
        };
        $scope.deleteEndpoint = function () {
            var jolokia = workspace.jolokia;
            var selection = workspace.selection;
            var entries = selection.entries;
            if (selection && jolokia && entries) {
                var domain = selection.domain;
                var brokerName = entries["BrokerName"];
                var name = entries["Destination"];
                var isQueue = "Topic" !== entries["Type"];
                if (domain && brokerName) {
                    var mbean = "" + domain + ":BrokerName=" + brokerName + ",Type=Broker";
                    $scope.message = "Deleting " + (isQueue ? "queue" : "topic") + " " + name;
                    var operation = "removeEndpoint(java.lang.String)";
                    jolokia.execute(mbean, operation, name, onSuccess(deleteSuccess));
                }
            }
        };
        function operationSuccess() {
            $scope.endpointName = "";
            $scope.workspace.operationCounter += 1;
            Core.$apply($scope);
            notification("success", $scope.message);
        }
        function deleteSuccess() {
            if (workspace.selection) {
                var parent = workspace.selection.parent;
                if (parent) {
                    $scope.workspace.updateSelectionNode(parent);
                }
            }
            $scope.workspace.operationCounter += 1;
            Core.$apply($scope);
            notification("success", $scope.message);
        }
    }
    Camel.EndpointController = EndpointController;
})(Camel || (Camel = {}));
var Camel;
(function (Camel) {
    Camel.endpointCategories = {
        bigdata: {
            label: "Big Data",
            endpoints: [
                "hdfs", 
                "hbase", 
                "lucene", 
                "solr"
            ],
            endpointIcon: "/app/camel/img/endpointRepository24.png"
        },
        database: {
            label: "Database",
            endpoints: [
                "couchdb", 
                "elasticsearch", 
                "hbase", 
                "jdbc", 
                "jpa", 
                "hibernate", 
                "mongodb", 
                "mybatis", 
                "sql"
            ],
            endpointIcon: "/app/camel/img/endpointRepository24.png"
        },
        cloud: {
            label: "Cloud",
            endpoints: [
                "aws-cw", 
                "aws-ddb", 
                "aws-sdb", 
                "aws-ses", 
                "aws-sns", 
                "aws-sqs", 
                "aws-s3", 
                "gauth", 
                "ghhtp", 
                "glogin", 
                "gtask", 
                "jclouds"
            ]
        },
        core: {
            label: "Core",
            endpoints: [
                "bean", 
                "direct", 
                "seda"
            ]
        },
        messaging: {
            label: "Messaging",
            endpoints: [
                "jms", 
                "activemq", 
                "amqp", 
                "cometd", 
                "cometds", 
                "mqtt", 
                "netty", 
                "vertx", 
                "websocket"
            ],
            endpointIcon: "/app/camel/img/endpointQueue24.png"
        },
        mobile: {
            label: "Mobile",
            endpoints: [
                "apns"
            ]
        },
        sass: {
            label: "SaaS",
            endpoints: [
                "salesforce", 
                "sap-netweaver"
            ]
        },
        social: {
            label: "Social",
            endpoints: [
                "atom", 
                "facebook", 
                "irc", 
                "ircs", 
                "rss", 
                "smpp", 
                "twitter", 
                "weather"
            ]
        },
        storage: {
            label: "Storage",
            endpointIcon: "/app/camel/img/endpointFolder24.png",
            endpoints: [
                "file", 
                "ftp", 
                "sftp", 
                "scp", 
                "jsch"
            ]
        },
        template: {
            label: "Templating",
            endpoints: [
                "freemarker", 
                "velocity", 
                "xquery", 
                "xslt", 
                "scalate", 
                "string-template"
            ]
        }
    };
    Camel.endpointToCategory = {};
    Camel.endpointIcon = "/app/camel/img/endpoint24.png";
    Camel.endpointConfigurations = {
        drools: {
            icon: "/app/camel/img/endpointQueue24.png"
        },
        quartz: {
            icon: "/app/camel/img/endpointTimer24.png"
        },
        facebook: {
            icon: "/app/camel/img/endpoints/facebook24.jpg"
        },
        salesforce: {
            icon: "/app/camel/img/endpoints/salesForce24.png"
        },
        sap: {
            icon: "/app/camel/img/endpoints/SAPe24.png"
        },
        "sap-netweaver": {
            icon: "/app/camel/img/endpoints/SAPNetweaver24.jpg"
        },
        timer: {
            icon: "/app/camel/img/endpointTimer24.png"
        },
        twitter: {
            icon: "/app/camel/img/endpoints/twitter24.png"
        },
        weather: {
            icon: "/app/camel/img/endpoints/weather24.jpg"
        }
    };
    Camel.endpointForms = {
        file: {
            tabs: {
                'Options': [
                    '*'
                ]
            }
        },
        activemq: {
            tabs: {
                'Connection': [
                    'clientId', 
                    'transacted', 
                    'transactedInOut', 
                    'transactionName', 
                    'transactionTimeout'
                ],
                'Producer': [
                    'timeToLive', 
                    'priority', 
                    'allowNullBody', 
                    'pubSubNoLocal', 
                    'preserveMessageQos'
                ],
                'Consumer': [
                    'concurrentConsumers', 
                    'acknowledgementModeName', 
                    'selector', 
                    'receiveTimeout'
                ],
                'Reply': [
                    'replyToDestination', 
                    'replyToDeliveryPersistent', 
                    'replyToCacheLevelName', 
                    'replyToDestinationSelectorName'
                ],
                'Options': [
                    '*'
                ]
            }
        }
    };
    Camel.endpointForms["jms"] = Camel.endpointForms.activemq;
    angular.forEach(Camel.endpointCategories, function (category, catKey) {
        category.id = catKey;
        angular.forEach(category.endpoints, function (endpoint) {
            Camel.endpointToCategory[endpoint] = category;
        });
    });
    var camelModelTabExtensions = {
        route: {
            'Overview': [
                'id', 
                'description'
            ],
            'Advanced': [
                '*'
            ]
        }
    };
    function getEndpointIcon(endpointName) {
        var value = Camel.getEndpointConfig(endpointName, null);
        var answer = Core.pathGet(value, [
            "icon"
        ]);
        if (!answer) {
            var category = getEndpointCategory(endpointName);
            answer = Core.pathGet(category, [
                "endpointIcon"
            ]);
        }
        return answer || Camel.endpointIcon;
    }
    Camel.getEndpointIcon = getEndpointIcon;
    function getEndpointConfig(endpointName, category) {
        var answer = Camel.endpointConfigurations[endpointName];
        if (!answer) {
            answer = {};
            Camel.endpointConfigurations[endpointName] = answer;
        }
        if (!answer.label) {
            answer.label = endpointName;
        }
        if (!answer.icon) {
            answer.icon = Core.pathGet(category, [
                "endpointIcon"
            ]) || Camel.endpointIcon;
        }
        if (!answer.category) {
            answer.category = category;
        }
        return answer;
    }
    Camel.getEndpointConfig = getEndpointConfig;
    function getEndpointCategory(endpointName) {
        return Camel.endpointToCategory[endpointName] || Camel.endpointCategories.core;
    }
    Camel.getEndpointCategory = getEndpointCategory;
    function getConfiguredCamelModel() {
        var schema = _apacheCamelModel;
        var definitions = schema["definitions"];
        if (definitions) {
            angular.forEach(camelModelTabExtensions, function (tabs, name) {
                var model = definitions[name];
                if (model) {
                    if (!model["tabs"]) {
                        model["tabs"] = tabs;
                    }
                }
            });
        }
        return schema;
    }
    Camel.getConfiguredCamelModel = getConfiguredCamelModel;
    function initEndpointChooserScope($scope, $location, localStorage, workspace, jolokia) {
        $scope.selectedComponentName = null;
        $scope.endpointParameters = {};
        $scope.endpointPath = "";
        $scope.schema = {
            definitions: {}
        };
        $scope.jolokia = jolokia;
        var versionId = $scope.branch;
        var profileId = Fabric.pagePathToProfileId($scope.pageId);
        if (profileId && versionId) {
            Fabric.profileJolokia(jolokia, profileId, versionId, function (profileJolokia) {
                if (!profileJolokia) {
                    Camel.log.info("No container is running for profile " + profileId + " and version " + versionId + " so using current container for endpoint completion");
                    profileJolokia = jolokia;
                }
                $scope.jolokia = profileJolokia;
                $scope.profileWorkspace = null;
                $scope.loadEndpointNames();
            });
        }
        var silentOptions = {
            silent: true
        };
        $scope.$watch('workspace.selection', function () {
            $scope.loadEndpointNames();
        });
        $scope.$watch('selectedComponentName', function () {
            if ($scope.selectedComponentName !== $scope.loadedComponentName) {
                $scope.endpointParameters = {};
                $scope.loadEndpointSchema($scope.selectedComponentName);
                $scope.loadedComponentName = $scope.selectedComponentName;
            }
        });
        $scope.endpointCompletions = function (completionText) {
            var answer = null;
            var mbean = findCamelContextMBean();
            var componentName = $scope.selectedComponentName;
            var endpointParameters = {};
            if (mbean && componentName && completionText) {
                answer = $scope.jolokia.execute(mbean, 'completeEndpointPath', componentName, endpointParameters, completionText, onSuccess(null, silentOptions));
            }
            return answer || [];
        };
        $scope.loadEndpointNames = function () {
            $scope.componentNames = null;
            var mbean = findCamelContextMBean();
            if (mbean) {
                $scope.jolokia.execute(mbean, 'findComponentNames', onSuccess(onComponents, {
                    silent: true
                }));
            } else {
                console.log("WARNING: No camel context mbean so cannot load component names");
            }
        };
        $scope.loadEndpointSchema = function (componentName) {
            var mbean = findCamelContextMBean();
            if (mbean && componentName && componentName !== $scope.loadedEndpointSchema) {
                $scope.selectedComponentName = componentName;
                $scope.jolokia.execute(mbean, 'componentParameterJsonSchema', componentName, onSuccess(onEndpointSchema, silentOptions));
            }
        };
        function onComponents(response) {
            $scope.componentNames = response;
            Camel.log.info("onComponents: " + response);
            $scope.hasComponentNames = $scope.componentNames ? true : false;
            Core.$apply($scope);
        }
        function onEndpointSchema(response) {
            if (response) {
                try  {
                    var json = JSON.parse(response);
                    var endpointName = $scope.selectedComponentName;
                    configureEndpointSchema(endpointName, json);
                    $scope.endpointSchema = json;
                    $scope.schema.definitions[endpointName] = json;
                    $scope.loadedEndpointSchema = endpointName;
                    Core.$apply($scope);
                } catch (e) {
                    console.log("Failed to parse JSON " + e);
                    console.log("JSON: " + response);
                }
            }
        }
        function configureEndpointSchema(endpointName, json) {
            console.log("======== configuring schema for " + endpointName);
            var config = Camel.endpointForms[endpointName];
            if (config && json) {
                if (config.tabs) {
                    json.tabs = config.tabs;
                }
            }
        }
        function findCamelContextMBean() {
            var profileWorkspace = $scope.profileWorkspace;
            if (!profileWorkspace) {
                if ($scope.jolokia) {
                    var jolokiaStatus = {
                        xhr: null
                    };
                    var $rootScope = null;
                    var jmxTreeLazyLoadRegistry = Jmx.lazyLoaders;
                    var $compile = null;
                    var $templateCache = null;
                    profileWorkspace = new Workspace($scope.jolokia, jolokiaStatus, jmxTreeLazyLoadRegistry, $location, $compile, $templateCache, localStorage, $rootScope);
                    Camel.log.info("Loading the profile using jolokia: " + $scope.jolokia);
                    profileWorkspace.loadTree();
                    $scope.profileWorkspace = profileWorkspace;
                }
            }
            if (!profileWorkspace) {
                Camel.log.info("No profileWorkspace found so defaulting it to workspace for now");
                profileWorkspace = workspace;
            }
            var componentName = $scope.selectedComponentName;
            var selectedCamelContextId;
            var selectedRouteId;
            if (angular.isDefined($scope.camelSelectionDetails)) {
                selectedCamelContextId = $scope.camelSelectionDetails.selectedCamelContextId;
                selectedRouteId = $scope.camelSelectionDetails.selectedRouteId;
            }
            console.log("==== componentName " + componentName + " selectedCamelContextId: " + selectedCamelContextId + " selectedRouteId: " + selectedRouteId);
            var contextsById = Camel.camelContextMBeansById(profileWorkspace);
            if (selectedCamelContextId) {
                var mbean = Core.pathGet(contextsById, [
                    selectedCamelContextId, 
                    "mbean"
                ]);
                if (mbean) {
                    return mbean;
                }
            }
            if (selectedRouteId) {
                var map = Camel.camelContextMBeansByRouteId(profileWorkspace);
                var mbean = Core.pathGet(map, [
                    selectedRouteId, 
                    "mbean"
                ]);
                if (mbean) {
                    return mbean;
                }
            }
            if (componentName) {
                var map = Camel.camelContextMBeansByComponentName(profileWorkspace);
                var mbean = Core.pathGet(map, [
                    componentName, 
                    "mbean"
                ]);
                if (mbean) {
                    return mbean;
                }
            }
            var answer = null;
            angular.forEach(contextsById, function (details, id) {
                var mbean = details.mbean;
                if (!answer && mbean) {
                    answer = mbean;
                }
            });
            return answer;
        }
    }
    Camel.initEndpointChooserScope = initEndpointChooserScope;
})(Camel || (Camel = {}));
var Camel;
(function (Camel) {
    Camel.jmsHeaderSchema = {
        definitions: {
            headers: {
                properties: {
                    JMSCorrelationID: {
                        type: "java.lang.String"
                    },
                    JMSDeliveryMode: {
                        "type": "string",
                        "enum": [
                            "PERSISTENT", 
                            "NON_PERSISTENT"
                        ]
                    },
                    JMSDestination: {
                        type: "javax.jms.Destination"
                    },
                    JMSExpiration: {
                        type: "long"
                    },
                    JMSPriority: {
                        type: "int"
                    },
                    JMSReplyTo: {
                        type: "javax.jms.Destination"
                    },
                    JMSType: {
                        type: "java.lang.String"
                    },
                    JMSXGroupId: {
                        type: "java.lang.String"
                    },
                    AMQ_SCHEDULED_CRON: {
                        type: "java.lang.String"
                    },
                    AMQ_SCHEDULED_DELAY: {
                        type: "java.lang.String"
                    },
                    AMQ_SCHEDULED_PERIOD: {
                        type: "java.lang.String"
                    },
                    AMQ_SCHEDULED_REPEAT: {
                        type: "java.lang.String"
                    }
                }
            },
            "javax.jms.Destination": {
                type: "java.lang.String"
            }
        }
    };
})(Camel || (Camel = {}));
var Core;
(function (Core) {
    var PageTitle = (function () {
        function PageTitle() {
            this.titleElements = [];
        }
        PageTitle.prototype.addTitleElement = function (element) {
            this.titleElements.push(element);
        };
        PageTitle.prototype.getTitle = function () {
            return this.getTitleExcluding([], ' ');
        };
        PageTitle.prototype.getTitleWithSeparator = function (separator) {
            return this.getTitleExcluding([], separator);
        };
        PageTitle.prototype.getTitleExcluding = function (excludes, separator) {
            return this.getTitleArrayExcluding(excludes).join(separator);
        };
        PageTitle.prototype.getTitleArrayExcluding = function (excludes) {
            return this.titleElements.map(function (element) {
                var answer = '';
                if (element) {
                    answer = element();
                    if (answer === null) {
                        return '';
                    }
                }
                return answer;
            }).exclude(excludes).exclude('');
        };
        return PageTitle;
    })();
    Core.PageTitle = PageTitle;    
})(Core || (Core = {}));
var Camel;
(function (Camel) {
    function ProfileRouteController($scope, $location, workspace, jolokia) {
        $scope.data = [];
        $scope.calcManually = true;
        $scope.icons = {};
        $scope.selectedRouteId = "";
        var columnDefs = [
            {
                field: 'id',
                displayName: 'Id',
                cellTemplate: '<div class="ngCellText" ng-bind-html-unsafe="rowIcon(row.entity.id)"></div>',
                cellFilter: null,
                width: "**",
                resizable: true
            }, 
            {
                field: 'count',
                displayName: 'Count',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'last',
                displayName: 'Last',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'delta',
                displayName: 'Delta',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'mean',
                displayName: 'Mean',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'min',
                displayName: 'Min',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'max',
                displayName: 'Max',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'total',
                displayName: 'Total',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'self',
                displayName: 'Self',
                cellFilter: null,
                width: "*",
                resizable: true
            }
        ];
        $scope.rowIcon = function (id) {
            var entry = $scope.icons[id];
            if (entry) {
                return entry.img + " " + id;
            } else {
                return id;
            }
        };
        $scope.gridOptions = {
            data: 'data',
            displayFooter: true,
            displaySelectionCheckbox: false,
            canSelectRows: false,
            enableSorting: false,
            columnDefs: columnDefs,
            filterOptions: {
                filterText: ''
            }
        };
        var populateProfileMessages = function (response) {
            var updatedData = [];
            var xml = response.value;
            if (angular.isString(xml)) {
                var doc = $.parseXML(xml);
                var routeMessages = $(doc).find("routeStat");
                routeMessages.each(function (idx, message) {
                    var messageData = {
                        id: {},
                        count: {},
                        last: {},
                        delta: {},
                        mean: {},
                        min: {},
                        max: {},
                        total: {},
                        self: {}
                    };
                    messageData.id = message.getAttribute("id");
                    var total = 0;
                    total += +message.getAttribute("exchangesCompleted");
                    total += +message.getAttribute("exchangesFailed");
                    messageData.count = total;
                    messageData.last = message.getAttribute("lastProcessingTime");
                    var delta = message.getAttribute("deltaProcessingTime");
                    if (delta) {
                        messageData.delta = delta;
                    } else {
                        messageData.delta = 0;
                    }
                    messageData.mean = message.getAttribute("meanProcessingTime");
                    messageData.min = message.getAttribute("minProcessingTime");
                    messageData.max = message.getAttribute("maxProcessingTime");
                    messageData.total = message.getAttribute("totalProcessingTime");
                    var self = message.getAttribute("selfProcessingTime");
                    if (self) {
                        messageData.self = self;
                    } else {
                        $scope.calcManually = true;
                        messageData.self = "0";
                    }
                    updatedData.push(messageData);
                });
                var processorMessages = $(doc).find("processorStat");
                processorMessages.each(function (idx, message) {
                    var messageData = {
                        id: {},
                        count: {},
                        last: {},
                        delta: {},
                        mean: {},
                        min: {},
                        max: {},
                        total: {},
                        self: {}
                    };
                    messageData.id = message.getAttribute("id");
                    var total = 0;
                    total += +message.getAttribute("exchangesCompleted");
                    total += +message.getAttribute("exchangesFailed");
                    messageData.count = total;
                    messageData.last = message.getAttribute("lastProcessingTime");
                    var delta = message.getAttribute("deltaProcessingTime");
                    if (delta) {
                        messageData.delta = delta;
                    } else {
                        messageData.delta = 0;
                    }
                    messageData.mean = message.getAttribute("meanProcessingTime");
                    messageData.min = message.getAttribute("minProcessingTime");
                    messageData.max = message.getAttribute("maxProcessingTime");
                    var apt = message.getAttribute("accumulatedProcessingTime");
                    if (apt) {
                        messageData.total = apt;
                    } else {
                        messageData.total = "0";
                    }
                    messageData.self = message.getAttribute("totalProcessingTime");
                    updatedData.push(messageData);
                });
            }
            if ($scope.calcManually) {
                updatedData.sort(function (e1, e2) {
                    var entry1 = $scope.icons[e1.id];
                    var entry2 = $scope.icons[e2.id];
                    if (entry1 && entry2) {
                        return entry1.index - entry2.index;
                    } else {
                        return 0;
                    }
                });
                var accTotal = 0;
                updatedData.reverse().forEach(function (data, idx) {
                    if (idx < updatedData.length - 1) {
                        accTotal += +data.self;
                        data.total = accTotal;
                    } else {
                        data.self = +(data.total - accTotal);
                        if (data.self < 0) {
                            data.self = 0;
                        }
                    }
                });
                updatedData.reverse();
            }
            $scope.data = updatedData;
            Core.$apply($scope);
        };
        $scope.onResponse = function (response) {
            loadData();
        };
        $scope.$watch('workspace.tree', function () {
            setTimeout(loadData, 50);
        });
        function initIdToIcon() {
            console.log("initializing id and icons");
            $scope.icons = {};
            var routeXml = Core.pathGet(workspace.selection, [
                "routeXmlNode"
            ]);
            if (routeXml) {
                var entry = {
                    img: "",
                    index: 0
                };
                entry.index = -1;
                entry.img = "<img src='app/camel/img/camel_route.png'>";
                $scope.icons[$scope.selectedRouteId] = entry;
                $(routeXml).find('*').each(function (idx, element) {
                    var id = element.getAttribute("id");
                    if (id) {
                        var entry = {
                            img: "",
                            index: 0
                        };
                        entry.index = idx;
                        var icon = Camel.getRouteNodeIcon(element);
                        if (icon) {
                            entry.img = "<img src='" + icon + "'>";
                        } else {
                            entry.img = "";
                        }
                        $scope.icons[id] = entry;
                    }
                });
            }
        }
        function loadData() {
            console.log("Loading Camel route profile data...");
            $scope.selectedRouteId = Camel.getSelectedRouteId(workspace);
            var routeMBean = Camel.getSelectionRouteMBean(workspace, $scope.selectedRouteId);
            console.log("Selected route is " + $scope.selectedRouteId);
            var camelVersion = Camel.getCamelVersion(workspace, jolokia);
            if (camelVersion) {
                console.log("Camel version " + camelVersion);
                camelVersion += "camel-";
                var numbers = Core.parseVersionNumbers(camelVersion);
                if (Core.compareVersionNumberArrays(numbers, [
                    2, 
                    11
                ]) >= 0) {
                    console.log("Camel 2.11 or better detected");
                    $scope.calcManually = false;
                } else {
                    console.log("Camel 2.10 or older detected");
                    $scope.calcManually = true;
                }
            }
            initIdToIcon();
            console.log("Initialized icons, with " + $scope.icons.length + " icons");
            var query = {
                type: 'exec',
                mbean: routeMBean,
                operation: 'dumpRouteStatsAsXml(boolean,boolean)',
                arguments: [
                    false, 
                    true
                ]
            };
            scopeStoreJolokiaHandle($scope, jolokia, jolokia.register(populateProfileMessages, query));
        }
    }
    Camel.ProfileRouteController = ProfileRouteController;
})(Camel || (Camel = {}));
var Camel;
(function (Camel) {
    function PropertiesController($scope, workspace) {
        $scope.viewTemplate = null;
        $scope.schema = _apacheCamelModel;
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateData, 50);
        });
        $scope.$watch('workspace.selection', function () {
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            updateData();
        });
        function updateData() {
            var routeXmlNode = Camel.getSelectedRouteNode(workspace);
            $scope.nodeData = Camel.getRouteNodeJSON(routeXmlNode);
            if (routeXmlNode) {
                var nodeName = routeXmlNode.nodeName;
                $scope.model = Camel.getCamelSchema(nodeName);
                if ($scope.model) {
                    console.log("data is: " + JSON.stringify($scope.nodeData, null, "  "));
                    console.log("model schema is: " + JSON.stringify($scope.model, null, "  "));
                    $scope.viewTemplate = "app/camel/html/nodePropertiesView.html";
                }
            }
        }
    }
    Camel.PropertiesController = PropertiesController;
})(Camel || (Camel = {}));
var Camel;
(function (Camel) {
    function SendMessageController($route, $scope, $element, $timeout, workspace, jolokia, localStorage, $location) {
        var log = Logger.get("Camel");
        log.info("Loaded page!");
        $scope.noCredentials = false;
        $scope.showChoose = false;
        $scope.profileFileNames = [];
        $scope.profileFileNameToProfileId = {};
        $scope.selectedFiles = {};
        $scope.container = {};
        Core.bindModelToSearchParam($scope, $location, "tab", "subtab", "compose");
        Core.bindModelToSearchParam($scope, $location, "searchText", "q", "");
        Core.reloadWhenParametersChange($route, $scope, $location);
        if ($location.path().has('activemq')) {
            if (!localStorage['activemqUserName'] || !localStorage['activemqPassword']) {
                $scope.noCredentials = true;
            }
        }
        var LANGUAGE_FORMAT_PREFERENCE = "defaultLanguageFormat";
        var sourceFormat = workspace.getLocalStorage(LANGUAGE_FORMAT_PREFERENCE) || "javascript";
        $scope.message = "\n\n\n\n";
        $scope.codeMirror = undefined;
        var options = {
            mode: {
                name: sourceFormat
            },
            onChange: function (codeMirror) {
                if (!$scope.codeMirror) {
                    $scope.codeMirror = codeMirror;
                }
            }
        };
        $scope.codeMirrorOptions = CodeEditor.createEditorSettings(options);
        $scope.headers = [];
        $scope.addHeader = function () {
            $scope.headers.push({
                name: "",
                value: ""
            });
            if ($element) {
                $timeout(function () {
                    var lastHeader = $element.find("input.headerName").last();
                    lastHeader.focus();
                }, 100);
            }
        };
        $scope.removeHeader = function (header) {
            $scope.headers = $scope.headers.remove(header);
        };
        $scope.defaultHeaderNames = function () {
            var answer = [];
            function addHeaderSchema(schema) {
                angular.forEach(schema.definitions.headers.properties, function (value, name) {
                    answer.push(name);
                });
            }
            if (isJmsEndpoint()) {
                addHeaderSchema(Camel.jmsHeaderSchema);
            }
            if (isCamelEndpoint()) {
                addHeaderSchema(Camel.camelHeaderSchema);
            }
            return answer;
        };
        $scope.$watch('workspace.selection', function () {
            workspace.moveIfViewInvalid();
            if (Fabric.fabricCreated(workspace)) {
                loadProfileConfigurationFiles();
            }
        });
        $scope.$watch('codeMirrorOptions.mode.name', function (newValue, oldValue) {
            workspace.setLocalStorage(LANGUAGE_FORMAT_PREFERENCE, newValue);
        });
        var sendWorked = function () {
            $scope.message = "";
            notification("success", "Message sent!");
        };
        $scope.autoFormat = function () {
            setTimeout(function () {
                CodeEditor.autoFormatEditor($scope.codeMirror);
            }, 50);
        };
        $scope.sendMessage = function () {
            var body = $scope.message;
            doSendMessage(body, sendWorked);
        };
        function doSendMessage(body, onSendCompleteFn) {
            var selection = workspace.selection;
            if (selection) {
                var mbean = selection.objectName;
                if (mbean) {
                    var headers = null;
                    if ($scope.headers.length) {
                        headers = {};
                        angular.forEach($scope.headers, function (object) {
                            var key = object.name;
                            if (key) {
                                headers[key] = object.value;
                            }
                        });
                        log.info("About to send headers: " + JSON.stringify(headers));
                    }
                    var callback = onSuccess(onSendCompleteFn);
                    if (selection.domain === "org.apache.camel") {
                        var target = Camel.getContextAndTargetEndpoint(workspace);
                        var uri = target['uri'];
                        mbean = target['mbean'];
                        if (mbean && uri) {
                            if (headers) {
                                jolokia.execute(mbean, "sendBodyAndHeaders(java.lang.String, java.lang.Object, java.util.Map)", uri, body, headers, callback);
                            } else {
                                jolokia.execute(mbean, "sendStringBody(java.lang.String, java.lang.String)", uri, body, callback);
                            }
                        } else {
                            if (!mbean) {
                                notification("error", "Could not find CamelContext MBean!");
                            } else {
                                notification("error", "Failed to determine endpoint name!");
                            }
                            log.debug("Parsed context and endpoint: ", target);
                        }
                    } else {
                        var user = localStorage["activemqUserName"];
                        var pwd = localStorage["activemqPassword"];
                        if (headers) {
                            jolokia.execute(mbean, "sendTextMessage(java.util.Map, java.lang.String, java.lang.String, java.lang.String)", headers, body, user, pwd, callback);
                        } else {
                            jolokia.execute(mbean, "sendTextMessage(java.lang.String, java.lang.String, java.lang.String)", body, user, pwd, callback);
                        }
                    }
                }
            }
        }
        $scope.fileSelection = function () {
            var answer = [];
            angular.forEach($scope.selectedFiles, function (value, key) {
                if (value) {
                    answer.push(key);
                }
            });
            return answer;
        };
        $scope.sendSelectedFiles = function () {
            var filesToSend = $scope.fileSelection();
            var fileCount = filesToSend.length;
            var version = $scope.container.versionId || "1.0";
            function onSendFileCompleted(response) {
                if (filesToSend.length) {
                    var fileName = filesToSend.pop();
                    if (fileName) {
                        var profile = $scope.profileFileNameToProfileId[fileName];
                        if (profile) {
                            var body = Fabric.getConfigFile(jolokia, version, profile, fileName);
                            if (!body) {
                                log.warn("No body for message " + fileName);
                                body = "";
                            }
                            doSendMessage(body, onSendFileCompleted);
                        }
                    }
                } else {
                    var text = Core.maybePlural(fileCount, "Message") + " sent!";
                    notification("success", text);
                }
            }
            onSendFileCompleted(null);
        };
        function isCamelEndpoint() {
            return true;
        }
        function isJmsEndpoint() {
            return true;
        }
        function loadProfileConfigurationFiles() {
            if (Fabric.fabricCreated(workspace)) {
                $scope.container = Fabric.getCurrentContainer(jolokia, [
                    'versionId', 
                    'profileIds'
                ]);
                jolokia.execute(Fabric.managerMBean, "currentContainerConfigurationFiles", onSuccess(onFabricConfigFiles));
            }
        }
        function onFabricConfigFiles(response) {
            $scope.profileFileNameToProfileId = response;
            $scope.profileFileNames = Object.keys(response).sort();
            $scope.showChoose = $scope.profileFileNames.length ? true : false;
            $scope.selectedFiles = {};
            Core.$apply($scope);
        }
    }
    Camel.SendMessageController = SendMessageController;
})(Camel || (Camel = {}));
var Camel;
(function (Camel) {
    function SourceController($scope, workspace) {
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateRoutes, 50);
        });
        $scope.$watch('workspace.selection', function () {
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            updateRoutes();
        });
        var options = {
            mode: {
                name: 'xml'
            }
        };
        $scope.codeMirrorOptions = CodeEditor.createEditorSettings(options);
        function getSource(routeXmlNode) {
            function removeCrappyHeaders(idx, e) {
                var answer = e.getAttribute("customId");
                if (e.nodeName === 'route') {
                    answer = "true";
                }
                if (!answer || answer !== "true") {
                    e.removeAttribute("id");
                }
                e.removeAttribute("customId");
                e.removeAttribute("_cid");
                e.removeAttribute("group");
            }
            var copy = $(routeXmlNode).clone();
            copy.each(removeCrappyHeaders);
            copy.find("*").each(removeCrappyHeaders);
            var newNode = (copy && copy.length) ? copy[0] : routeXmlNode;
            return Core.xmlNodeToString(newNode);
        }
        function updateRoutes() {
            var routeXmlNode = Camel.getSelectedRouteNode(workspace);
            $scope.mbean = Camel.getSelectionCamelContextMBean(workspace);
            if (routeXmlNode) {
                $scope.source = getSource(routeXmlNode);
                Core.$apply($scope);
            } else if ($scope.mbean) {
                var jolokia = workspace.jolokia;
                jolokia.request({
                    type: 'exec',
                    mbean: $scope.mbean,
                    operation: 'dumpRoutesAsXml()'
                }, onSuccess(populateTable));
            }
        }
        var populateTable = function (response) {
            var data = response.value;
            var selectedRouteId = Camel.getSelectedRouteId(workspace);
            if (data && selectedRouteId) {
                var doc = $.parseXML(data);
                var routes = $(doc).find('route[id="' + selectedRouteId + '"]');
                if (routes && routes.length) {
                    var selectedRoute = routes[0];
                    var routeXml = getSource(selectedRoute);
                    if (routeXml) {
                        data = routeXml;
                    }
                }
            }
            $scope.source = data;
            Core.$apply($scope);
        };
        var saveWorked = function () {
            notification("success", "Route updated!");
            Camel.clearSelectedRouteNode(workspace);
            updateRoutes();
        };
        $scope.saveRouteXml = function () {
            var routeXml = $scope.source;
            if (routeXml) {
                var jolokia = workspace.jolokia;
                var mbean = Camel.getSelectionCamelContextMBean(workspace);
                if (mbean) {
                    jolokia.execute(mbean, "addOrUpdateRoutesFromXml(java.lang.String)", routeXml, onSuccess(saveWorked));
                } else {
                    notification("error", "Could not find CamelContext MBean!");
                }
            }
        };
    }
    Camel.SourceController = SourceController;
})(Camel || (Camel = {}));
var Camel;
(function (Camel) {
    function TraceRouteController($scope, workspace, jolokia, localStorage) {
        $scope.camelMaximumTraceOrDebugBodyLength = Camel.maximumTraceOrDebugBodyLength(localStorage);
        $scope.tracing = false;
        $scope.messages = [];
        $scope.graphView = null;
        $scope.tableView = null;
        $scope.mode = 'text';
        $scope.messageDialog = new Core.Dialog();
        $scope.gridOptions = Camel.createBrowseGridOptions();
        $scope.gridOptions.selectWithCheckboxOnly = false;
        $scope.gridOptions.showSelectionCheckbox = false;
        $scope.gridOptions.afterSelectionChange = onSelectionChanged;
        $scope.gridOptions.columnDefs.push({
            field: 'toNode',
            displayName: 'To Node'
        });
        $scope.startTracing = function () {
            setTracing(true);
        };
        $scope.stopTracing = function () {
            setTracing(false);
        };
        $scope.$watch('workspace.selection', function () {
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            $scope.messages = [];
            reloadTracingFlag();
        });
        $scope.openMessageDialog = function (message) {
            var idx = Core.pathGet(message, [
                "rowIndex"
            ]);
            $scope.selectRowIndex(idx);
            if ($scope.row) {
                $scope.mode = CodeEditor.detectTextFormat($scope.row.body);
                $scope.messageDialog.open();
            }
        };
        $scope.selectRowIndex = function (idx) {
            $scope.rowIndex = idx;
            var selected = $scope.gridOptions.selectedItems;
            selected.splice(0, selected.length);
            if (idx >= 0 && idx < $scope.messages.length) {
                $scope.row = $scope.messages[idx];
                if ($scope.row) {
                    selected.push($scope.row);
                }
            } else {
                $scope.row = null;
            }
            onSelectionChanged();
        };
        function reloadTracingFlag() {
            $scope.tracing = false;
            closeHandle($scope, jolokia);
            var mbean = Camel.getSelectionCamelTraceMBean(workspace);
            if (mbean) {
                $scope.tracing = jolokia.getAttribute(mbean, "Enabled", onSuccess(null));
                if ($scope.tracing) {
                    var traceMBean = mbean;
                    if (traceMBean) {
                        var query = {
                            type: 'exec',
                            mbean: traceMBean,
                            operation: 'dumpAllTracedMessagesAsXml'
                        };
                        scopeStoreJolokiaHandle($scope, jolokia, jolokia.register(populateRouteMessages, query));
                    }
                    $scope.graphView = "app/camel/html/routes.html";
                    $scope.tableView = "app/camel/html/browseMessages.html";
                } else {
                    $scope.messages = [];
                    $scope.graphView = null;
                    $scope.tableView = null;
                }
                console.log("Tracing is now " + $scope.tracing);
            }
        }
        function populateRouteMessages(response) {
            var selectedRouteId = Camel.getSelectedRouteId(workspace);
            var first = $scope.messages.length === 0;
            var xml = response.value;
            if (angular.isString(xml)) {
                var doc = $.parseXML(xml);
                var allMessages = $(doc).find("fabricTracerEventMessage");
                if (!allMessages || !allMessages.length) {
                    allMessages = $(doc).find("backlogTracerEventMessage");
                }
                allMessages.each(function (idx, message) {
                    var routeId = $(message).find("routeId").text();
                    if (routeId === selectedRouteId) {
                        var messageData = Camel.createMessageFromXml(message);
                        var toNode = $(message).find("toNode").text();
                        if (toNode) {
                            messageData["toNode"] = toNode;
                        }
                        $scope.messages.push(messageData);
                        Core.$apply($scope);
                    }
                });
            }
        }
        function onSelectionChanged() {
            angular.forEach($scope.gridOptions.selectedItems, function (selected) {
                if (selected) {
                    var toNode = selected["toNode"];
                    if (toNode) {
                        var nodes = d3.select("svg").selectAll("g .node");
                        nodes.attr("class", "node");
                        nodes.filter(function (item) {
                            if (item) {
                                var cid = item["cid"];
                                var rid = item["rid"];
                                if (cid) {
                                    return toNode === cid;
                                } else {
                                    return toNode === rid;
                                }
                            }
                            return null;
                        }).attr("class", "node selected");
                    }
                }
            });
        }
        function tracingChanged(response) {
            reloadTracingFlag();
            Core.$apply($scope);
        }
        function setTracing(flag) {
            var mbean = Camel.getSelectionCamelTraceMBean(workspace);
            if (mbean) {
                if (mbean.toString().endsWith("BacklogTracer")) {
                    var max = $scope.camelMaximumTraceOrDebugBodyLength;
                    jolokia.setAttribute(mbean, "BodyMaxChars", max);
                }
                jolokia.setAttribute(mbean, "Enabled", flag, onSuccess(tracingChanged));
            }
        }
    }
    Camel.TraceRouteController = TraceRouteController;
})(Camel || (Camel = {}));
var Camel;
(function (Camel) {
    function TreeController($scope, $location, workspace) {
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateSelectionFromURL, 50);
        });
        $scope.$watch('workspace.tree', function () {
            reloadFunction();
        });
        $scope.$on('jmxTreeUpdated', function () {
            reloadFunction();
        });
        function reloadFunction() {
            console.log("reloading the camel tree!!!");
            var children = [];
            var domainName = "org.apache.camel";
            var tree = workspace.tree;
            if (tree) {
                var rootFolder = new Folder("Camel Contexts");
                rootFolder.addClass = "org-apache-camel-context-folder";
                rootFolder.children = children;
                rootFolder.typeName = "context";
                rootFolder.key = "camelContexts";
                rootFolder.domain = domainName;
                var folder = tree.get(domainName);
                if (folder) {
                    angular.forEach(folder.children, function (value, key) {
                        var entries = value.map;
                        if (entries) {
                            var contextsFolder = entries["context"];
                            var routesNode = entries["routes"];
                            var endpointsNode = entries["endpoints"];
                            if (contextsFolder) {
                                var contextNode = contextsFolder.children[0];
                                if (contextNode) {
                                    var folder = new Folder(contextNode.title);
                                    folder.addClass = "org-apache-camel-context";
                                    folder.domain = domainName;
                                    folder.objectName = contextNode.objectName;
                                    folder.entries = contextNode.entries;
                                    folder.typeName = contextNode.typeName;
                                    folder.key = contextNode.key;
                                    if (routesNode) {
                                        var routesFolder = new Folder("Routes");
                                        routesFolder.addClass = "org-apache-camel-routes-folder";
                                        routesFolder.children = routesNode.children;
                                        angular.forEach(routesFolder.children, function (n) {
                                            return n.addClass = "org-apache-camel-routes";
                                        });
                                        folder.children.push(routesFolder);
                                        routesFolder.typeName = "routes";
                                        routesFolder.key = routesNode.key;
                                        routesFolder.domain = routesNode.domain;
                                    }
                                    if (endpointsNode) {
                                        var endpointsFolder = new Folder("Endpoints");
                                        endpointsFolder.addClass = "org-apache-camel-endpoints-folder";
                                        endpointsFolder.children = endpointsNode.children;
                                        angular.forEach(endpointsFolder.children, function (n) {
                                            n.addClass = "org-apache-camel-endpoints";
                                            if (!Camel.getContextId(n)) {
                                                n.entries["context"] = contextNode.entries["context"];
                                            }
                                        });
                                        folder.children.push(endpointsFolder);
                                        endpointsFolder.entries = contextNode.entries;
                                        endpointsFolder.typeName = "endpoints";
                                        endpointsFolder.key = endpointsNode.key;
                                        endpointsFolder.domain = endpointsNode.domain;
                                    }
                                    var jmxNode = new Folder("MBeans");
                                    angular.forEach(entries, function (jmxChild, name) {
                                        if (name !== "context" && name !== "routes" && name !== "endpoints") {
                                            jmxNode.children.push(jmxChild);
                                        }
                                    });
                                    if (jmxNode.children.length > 0) {
                                        jmxNode.sortChildren(false);
                                        folder.children.push(jmxNode);
                                    }
                                    folder.parent = rootFolder;
                                    children.push(folder);
                                }
                            }
                        }
                    });
                }
                var treeElement = $("#cameltree");
                Jmx.enableTree($scope, $location, workspace, treeElement, [
                    rootFolder
                ], true);
                setTimeout(updateSelectionFromURL, 50);
            }
        }
        function updateSelectionFromURL() {
            camelUpdateTreeSelectionFromURL($location, $("#cameltree"), true);
        }
    }
    Camel.TreeController = TreeController;
    function camelUpdateTreeSelectionFromURL($location, treeElement, activateIfNoneSelected) {
        if (typeof activateIfNoneSelected === "undefined") { activateIfNoneSelected = false; }
        var dtree = treeElement.dynatree("getTree");
        if (dtree) {
            var node = null;
            var key = $location.search()['nid'];
            if (key) {
                try  {
                    node = dtree.activateKey(key);
                } catch (e) {
                }
            }
            if (node) {
                node.expand(true);
            } else {
                if (!treeElement.dynatree("getActiveNode")) {
                    var root = treeElement.dynatree("getRoot");
                    var children = root ? root.getChildren() : null;
                    if (children && children.length) {
                        if (children.length === 1) {
                            var first = children[0];
                            first.expand(true);
                            var contexts = first.getChildren();
                            if (contexts && contexts.length === 1) {
                                first = contexts[0];
                                first.expand(true);
                                children = first.getChildren();
                                if (children && children.length) {
                                    var routes = children[0];
                                    if (routes.data.typeName === 'routes') {
                                        first = routes;
                                        first.expand(true);
                                    }
                                }
                            }
                            if (activateIfNoneSelected) {
                                first.activate();
                            }
                        } else {
                            var first = children[0];
                            first.expand(true);
                            if (activateIfNoneSelected) {
                                first.activate();
                            }
                        }
                    }
                }
            }
        }
    }
    Camel.camelUpdateTreeSelectionFromURL = camelUpdateTreeSelectionFromURL;
})(Camel || (Camel = {}));
var Camin;
(function (Camin) {
    var pluginName = 'camin';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'ngGrid', 
        'hawtioCore'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/camin', {
            templateUrl: 'app/camin/html/camin.html'
        }).when('/camin/:exchangeId', {
            templateUrl: 'app/camin/html/camin.html'
        });
    }).run(function (workspace, viewRegistry, helpRegistry) {
        viewRegistry["camin"] = "app/camin/html/layoutCamin.html";
        helpRegistry.addUserDoc('camin', 'app/camin/doc/help.md', function () {
            return Fabric.hasFabric(workspace);
        });
        workspace.topLevelTabs.push({
            content: "Camel",
            title: "Insight into Camel",
            isValid: function (workspace) {
                return Fabric.hasFabric(workspace);
            },
            href: function () {
                return "#/camin";
            },
            isActive: function (workspace) {
                return workspace.isLinkActive("camin");
            }
        });
    });
    hawtioPluginLoader.addModule(pluginName);
})(Camin || (Camin = {}));
var Camin;
(function (Camin) {
    function Controller($scope, jolokia, localStorage, $routeParams) {
        $scope.query = "";
        $scope.result = "";
        $scope.breadcrumbs = [];
        $scope.onQueryChange = function () {
            $scope.result = "Querying exchanges related to " + $scope.query;
            $scope.breadcrumbs = [
                $scope.query
            ];
            request();
        };
        var request = function () {
            var queryStr = "exchange.id:\"" + $scope.breadcrumbs.join("\" or exchange.id:\"") + "\" or " + "exchange.in.headers.ExtendedBreadcrumb:\"" + $scope.breadcrumbs.join("\" or exchange.in.headers.ExtendedBreadcrumb:\"") + "\" or " + "exchange.out.headers.ExtendedBreadcrumb:\"" + $scope.breadcrumbs.join("\" or exchange.out.headers.ExtendedBreadcrumb:\"") + "\"";
            var query = {
                "query": {
                    "query_string": {
                        "query": queryStr
                    }
                },
                "fields": [
                    "exchange.id", 
                    "exchange.in.headers.ExtendedBreadcrumb", 
                    "exchange.out.headers.ExtendedBreadcrumb"
                ],
                "from": 0,
                "size": 1000
            };
            var jreq = {
                type: 'exec',
                mbean: 'org.elasticsearch:service=restjmx',
                operation: 'exec',
                arguments: [
                    'POST', 
                    '/_all/camel/_search', 
                    angular.toJson(query)
                ]
            };
            jolokia.request(jreq, {
                method: 'POST',
                error: function (response) {
                    $scope.result = $scope.result + "<br/>" + "Error: " + angular.toJson(response);
                },
                success: function (response) {
                    var data = jQuery.parseJSON(response.value);
                    var oldsize = $scope.breadcrumbs.length;
                    for(var i = 0; i < data['hits']['hits'].length; i++) {
                        var fields = data['hits']['hits'][i].fields;
                        var concat = function (breadcrumbs) {
                            if (breadcrumbs) {
                                if (typeof breadcrumbs === 'string') {
                                    breadcrumbs = [
                                        breadcrumbs
                                    ];
                                }
                                for(var j = 0; j < breadcrumbs.length; j++) {
                                    var id = breadcrumbs[j];
                                    if ($scope.breadcrumbs.indexOf(id) < 0) {
                                        $scope.breadcrumbs.push(id);
                                    }
                                }
                            }
                        };
                        concat(fields["exchange.in.headers.ExtendedBreadcrumb"]);
                        concat(fields["exchange.out.headers.ExtendedBreadcrumb"]);
                    }
                    $scope.result = $scope.result + "<br/>" + "Found " + data.hits.total + " ids";
                    if (oldsize != $scope.breadcrumbs.length) {
                        request();
                    } else {
                        var ids = [];
                        for(var i = 0; i < data['hits']['hits'].length; i++) {
                            var id = data['hits']['hits'][i].fields["exchange.id"];
                            if (ids.indexOf(id) < 0) {
                                ids.push(id);
                            }
                        }
                        var queryStr = "exchange.id:\"" + ids.join("\" or exchange.id:\"") + "\"";
                        $scope.result = $scope.result + "<br/>" + query;
                        var query = {
                            "query": {
                                "query_string": {
                                    "query": queryStr
                                }
                            },
                            "from": 0,
                            "size": 1000,
                            "sort": [
                                "timestamp"
                            ]
                        };
                        var jreq = {
                            type: 'exec',
                            mbean: 'org.elasticsearch:service=restjmx',
                            operation: 'exec',
                            arguments: [
                                'POST', 
                                '/_all/camel/_search', 
                                angular.toJson(query)
                            ]
                        };
                        jolokia.request(jreq, {
                            method: 'POST',
                            error: function (response) {
                                $scope.result = $scope.result + "<br/>" + "Error: " + angular.toJson(response);
                            },
                            success: function (response) {
                                var data = jQuery.parseJSON(response.value);
                                $scope.result = $scope.result + "<br/>" + "Found " + data['hits']['total'] + " exchanges";
                                var events = [];
                                for(var i = 0; i < data['hits']['hits'].length; i++) {
                                    var e = data['hits']['hits'][i]._source;
                                    events.push(e);
                                }
                                draw(events);
                            }
                        });
                    }
                }
            });
        };
        var isoDate = function (date) {
            var timestamp, struct, minutesOffset = 0;
            var numericKeys = [
                1, 
                4, 
                5, 
                6, 
                7, 
                10, 
                11
            ];
            if ((struct = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(date))) {
                for(var i = 0, k; (k = numericKeys[i]); ++i) {
                    struct[k] = +struct[k] || 0;
                }
                struct[2] = (+struct[2] || 1) - 1;
                struct[3] = +struct[3] || 1;
                if (struct[8] !== 'Z' && struct[9] !== undefined) {
                    minutesOffset = struct[10] * 60 + struct[11];
                    if (struct[9] === '+') {
                        minutesOffset = 0 - minutesOffset;
                    }
                }
                timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]);
            } else {
                timestamp = Date.parse(date);
            }
            return timestamp;
        };
        var buildSequence = function (events) {
            var sequence = new Camin.Sequence();
            var exchangeToExec = {};
            events = events.sort(function (a, b) {
                return isoDate(a.timestamp) - isoDate(b.timestamp);
            });
            for(var i = 0; i < events.length; i++) {
                if (events[i].event === 'Created') {
                    var evtCreated = events[i];
                    var evtCompleted = null;
                    for(var j = 0; j < events.length; j++) {
                        if (events[j].event === 'Completed' && evtCreated.exchange.id === events[j].exchange.id) {
                            evtCompleted = events[j];
                            break;
                        }
                    }
                    if (evtCompleted === null) {
                        console.log('Could not find matching Completed exchange for ' + evtCreated.exchange.id);
                        continue;
                    }
                    var endpoint = sequence.endpoint(evtCompleted.exchange.fromEndpoint, evtCompleted.exchange.routeId, evtCompleted.exchange.contextId, evtCompleted.host);
                    var exec = sequence.exec(evtCreated.exchange.id, endpoint, isoDate(evtCreated.timestamp), isoDate(evtCompleted.timestamp));
                    exchangeToExec[evtCreated.exchange.id] = exec;
                }
            }
            var calls = {};
            for(var i = 0; i < events.length; i++) {
                if (events[i].event === 'Sending' && events[i].exchange.in && events[i].exchange.in.headers) {
                    var callId = events[i].exchange.in.headers.AuditCallId;
                    if (callId && calls[callId] === undefined) {
                        var evtSending = events[i];
                        var evtSent = null;
                        var evtCreated = null;
                        for(var j = 0; j < events.length; j++) {
                            if (events[j].event === 'Sent' && evtSending.exchange.id === events[j].exchange.id && events[j].exchange.in.headers.AuditCallId === callId) {
                                evtSent = events[j];
                                break;
                            }
                        }
                        for(var j = 0; j < events.length; j++) {
                            if (events[j].event === 'Created' && evtSending.exchange.id !== events[j].exchange.id && events[j].exchange.in.headers.AuditCallId === callId) {
                                evtCreated = events[j];
                                break;
                            }
                        }
                        var execA = exchangeToExec[evtSending.exchange.id];
                        var execB = evtCreated ? exchangeToExec[evtCreated.exchange.id] : null;
                        if (evtSent !== null && evtCreated !== null && execA !== null && execB != null) {
                            var call = sequence.call(callId, execA, execB, isoDate(evtSending.timestamp), isoDate(evtSent.timestamp));
                            calls[callId] = call;
                        } else {
                            console.log("Could not find Execution for exchange " + evtSending.exchange.id);
                        }
                    }
                }
            }
            return sequence;
        };
        var buildDiagram = function (sequence) {
            var diagram = new Camin.Diagram();
            var actors = {};
            var signals = [];
            var base = sequence.start();
            for(var i = 0; i < sequence.endpoints.length; i++) {
                var actor = diagram.actor("ep" + i);
                var ep = sequence.endpoints[i];
                var key = ep.url + "|" + ep.routeId + "|" + ep.contextId + "|" + ep.host;
                actors[key] = actor;
            }
            for(var i = 0; i < sequence.calls.length; i++) {
                var call = sequence.calls[i];
                if (call.execB) {
                    var epA = call.execA.endpoint;
                    var keyA = epA.url + "|" + epA.routeId + "|" + epA.contextId + "|" + epA.host;
                    var epB = call.execB.endpoint;
                    var keyB = epB.url + "|" + epB.routeId + "|" + epB.contextId + "|" + epB.host;
                    var actorA = actors[keyA];
                    var actorB = actors[keyB];
                    var start1 = call.start - base;
                    var stop1 = call.execB.start - base;
                    var start2 = call.execB.stop - base;
                    var stop2 = call.stop - base;
                    signals.push({
                        actorA: actorA,
                        actorB: actorB,
                        message: start1 + "ms - " + stop1 + "ms",
                        timestamp: start1
                    });
                    signals.push({
                        actorA: actorB,
                        actorB: actorA,
                        message: start2 + "ms - " + stop2 + "ms",
                        timestamp: start2
                    });
                }
            }
            signals = signals.sort(function (a, b) {
                return a.timestamp - b.timestamp;
            });
            for(var i = 0; i < signals.length; i++) {
                diagram.signal(signals[i].actorA, signals[i].actorB, signals[i].message);
            }
            return diagram;
        };
        var buildGantt = function (sequence) {
            var gantt = new Camin.Gantt();
            for(var i = 0; i < sequence.endpoints.length; i++) {
                var endpoint = sequence.endpoints[i];
                var resource = gantt.resource(endpoint);
                for(var j = 0; j < sequence.execs.length; j++) {
                    var exec = sequence.execs[j];
                    if (exec.endpoint === endpoint) {
                        gantt.task(resource, exec.start, exec.stop, exec);
                    }
                }
            }
            for(var i = 0; i < sequence.calls.length; i++) {
                var call = sequence.calls[i];
                if (call.execB) {
                    var taskA = gantt.taskByData(call.execA);
                    var taskB = gantt.taskByData(call.execB);
                    gantt.link(call.start, taskA, call.stop, taskB, call);
                }
            }
            gantt.layout();
            return gantt;
        };
        var eventTypeValue = {
            "Created": 0,
            "Sending": 1,
            "Sent": 2,
            "Completed": 3
        };
        var draw = function (events) {
            $scope.definition = "";
            events = events.sort(function (a, b) {
                return isoDate(a.timestamp) - isoDate(b.timestamp);
            });
            console.log(events);
            var sequence = buildSequence(events);
            console.log(sequence);
            var gantt = buildGantt(sequence);
            console.log(gantt);
            $('#gantt').html('');
            drawGantt('#gantt', gantt);
            var diagram = buildDiagram(sequence);
            console.log(diagram);
            $('#diagram').html('');
            drawDiagram('#diagram', diagram);
        };
        var drawDiagram = function (container, diagram) {
            var arrow_size = 10;
            var margin = 10;
            var actor_width = 100;
            var actor_margin = 30;
            var actor_height = 40;
            var signal_height = 30;
            var actor_font = 20;
            var signal_font = 14;
            var width = diagram.actors.length * (actor_width + actor_margin * 2);
            var height = (diagram.signals.length + 1) * signal_height + actor_height * 2 + margin * 2;
            var svg = d3.select(container).append('svg').attr('width', width + 2 * margin).attr('height', height + 2 * margin);
            var g = svg.append('g').attr('text-anchor', 'middle');
            for(var i = 0; i < diagram.actors.length; i++) {
                var actor = diagram.actors[i];
                var gu = g.append('g').attr('transform', 'translate(' + (i * (actor_width + actor_margin * 2) + actor_margin) + ',' + actor_height + ')');
                gu.append('rect').attr('width', actor_width).attr('height', actor_height).attr('stroke', '#000').attr('stroke-width', '2').attr('fill', '#FFFFFF');
                gu.append('text').attr('x', actor_width / 2).attr('y', actor_height / 2).attr('stroke-width', '0').attr('dominant-baseline', 'middle').attr('font-size', actor_font).text(actor.name);
                g.append('line').attr('x1', i * (actor_width + actor_margin * 2) + actor_width / 2 + actor_margin).attr('y1', actor_height * 2).attr('x2', i * (actor_width + actor_margin * 2) + actor_width / 2 + actor_margin).attr('y2', height - actor_height).attr('stroke', '#000').attr('stroke-width', '2');
                var gu = g.append('g').attr('transform', 'translate(' + (i * (actor_width + actor_margin * 2) + actor_margin) + ',' + (height - actor_height) + ')');
                gu.append('rect').attr('width', actor_width).attr('height', actor_height).attr('stroke', '#000').attr('stroke-width', '2').attr('fill', 'white');
                gu.append('text').attr('x', actor_width / 2).attr('y', actor_height / 2).attr('stroke-width', '0').attr('dominant-baseline', 'middle').attr('font-size', actor_font).text(actor.name);
            }
            for(var i = 0; i < diagram.signals.length; i++) {
                var x;
                var y;
                var length;
                var direction;
                var text;
                x = diagram.signals[i].actorA.index * (actor_width + actor_margin * 2) + actor_width / 2 + actor_margin;
                y = (i + 1) * signal_height + actor_height * 2;
                length = Math.abs(diagram.signals[i].actorA.index - diagram.signals[i].actorB.index) * (actor_width + actor_margin * 2);
                direction = diagram.signals[i].actorB.index > diagram.signals[i].actorA.index ? +1 : -1;
                text = diagram.signals[i].message;
                var gu = g.append('g').attr('transform', 'translate(' + x + ',' + y + ')').attr('stroke-width', '2');
                gu.append('rect').attr('x', Math.min(3, length * direction + 3)).attr('y', '-16').attr('width', Math.abs((length - 6) * direction)).attr('height', '19').attr('stroke', 'white').attr('stroke-width', '0').attr('fill', 'white');
                gu.append('line').attr('x1', 0).attr('y1', 0).attr('x2', length * direction).attr('y2', 0).attr('stroke', '#000').attr('stroke-width', '2');
                gu.append('line').attr('x1', length * direction - arrow_size * direction).attr('y1', -arrow_size).attr('x2', length * direction).attr('y2', 0).attr('stroke', '#000').attr('stroke-width', '2');
                gu.append('line').attr('x1', length * direction).attr('y1', 0).attr('x2', length * direction - arrow_size * direction).attr('y2', arrow_size).attr('stroke', '#000').attr('stroke-width', '2');
                gu.append('text').attr('x', length * direction / 2).attr('y', -8).attr('stroke-width', '0').attr('dominant-baseline', 'middle').attr('font-size', signal_font).text(text);
            }
        };
        var drawGantt = function (container, gantt) {
            var lineHeight = 35;
            var lineMargin = 3;
            var arrowWidth = 4;
            var width = 800;
            var height = lineHeight * gantt.resources.length;
            var margin = {
                top: 20,
                right: 40,
                bottom: 20,
                left: 250
            };
            var begin = gantt.start;
            var end = gantt.stop;
            var x = d3.scale.linear().domain([
                begin - (end - begin) * 0.1, 
                end + (end - begin) * 0.1
            ]).range([
                0, 
                width
            ]);
            var yt = function (t) {
                return t.resource.index * lineHeight + lineMargin + t.index * (lineHeight - 2 * lineMargin) / (t.max + 1);
            };
            var ht = function (t) {
                return 2 * (lineHeight - 2 * lineMargin) / (t.max + 1);
            };
            var svg = d3.select(container).append('svg').attr('width', width + margin.left + margin.right).attr('height', height + margin.top + margin.bottom);
            var text = svg.append('g').attr('width', width).attr('height', height).attr('transform', 'translate(0,' + margin.top + ')').selectAll('text').data(gantt.resources).enter();
            text.append('text').attr('x', 0).attr('y', function (r) {
                return r.index * lineHeight + lineHeight / 2;
            }).attr('dy', '-0.2em').attr('text-anchor', 'start').text(function (r) {
                var endpoint = r.data;
                var text = endpoint.url;
                if (text.indexOf("Endpoint[") == 0) {
                    text = text.substring(9, text.length - 1);
                }
                return text;
            });
            text.append('text').attr('x', 0).attr('y', function (r) {
                return r.index * lineHeight + lineHeight / 2;
            }).attr('dy', '0.8em').attr('text-anchor', 'start').text(function (r) {
                var endpoint = r.data;
                return endpoint.host + "/" + endpoint.contextId + "/" + endpoint.routeId;
            });
            var g = svg.append('g').attr('width', width).attr('height', height).attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
            g.append('g').attr('width', width).attr('height', height).selectAll('rect').data(gantt.tasks).enter().append('rect').attr('rx', lineMargin * 2).attr('ry', lineMargin * 2).attr('x', function (t) {
                return x(t.start);
            }).attr('y', yt).attr('height', ht).attr('width', function (t) {
                return x(t.stop) - x(t.start);
            }).attr('stroke', '#000000').attr('stroke-width', '2').attr('fill', function (t) {
                return d3.hsl(Math.random() * 360, 0.8, 0.8).toString();
            });
            var lines = g.append('g').attr('width', width).attr('height', height).attr('stroke', '#404040').attr('stroke-width', '2').selectAll('line').data(gantt.links).enter();
            lines.append('line').attr('x1', function (l) {
                return x(l.start);
            }).attr('y1', function (l) {
                return yt(l.taskA) + ht(l.taskA);
            }).attr('x2', function (l) {
                return x(l.start);
            }).attr('y2', function (l) {
                return yt(l.taskB) + ht(l.taskB) / 2;
            });
            lines.append('line').attr('x1', function (l) {
                return x(l.start);
            }).attr('y1', function (l) {
                return yt(l.taskB) + ht(l.taskB) / 2;
            }).attr('x2', function (l) {
                return x(l.taskB.start);
            }).attr('y2', function (l) {
                return yt(l.taskB) + ht(l.taskB) / 2;
            });
            lines.append('line').attr('x1', function (l) {
                return x(l.taskB.start);
            }).attr('y1', function (l) {
                return yt(l.taskB) + ht(l.taskB) / 2;
            }).attr('x2', function (l) {
                return x(l.taskB.start) - arrowWidth;
            }).attr('y2', function (l) {
                return yt(l.taskB) + ht(l.taskB) / 2 - arrowWidth;
            });
            lines.append('line').attr('x1', function (l) {
                return x(l.taskB.start);
            }).attr('y1', function (l) {
                return yt(l.taskB) + ht(l.taskB) / 2;
            }).attr('x2', function (l) {
                return x(l.taskB.start) - arrowWidth;
            }).attr('y2', function (l) {
                return yt(l.taskB) + ht(l.taskB) / 2 + arrowWidth;
            });
            lines.append('line').attr('x1', function (l) {
                return x(l.taskB.stop);
            }).attr('y1', function (l) {
                return yt(l.taskB) + ht(l.taskB) / 2;
            }).attr('x2', function (l) {
                return x(l.stop);
            }).attr('y2', function (l) {
                return yt(l.taskB) + ht(l.taskB) / 2;
            });
            lines.append('line').attr('x1', function (l) {
                return x(l.stop);
            }).attr('y1', function (l) {
                return yt(l.taskB) + ht(l.taskB) / 2;
            }).attr('x2', function (l) {
                return x(l.stop);
            }).attr('y2', function (l) {
                return yt(l.taskA) + ht(l.taskA);
            });
            lines.append('line').attr('x1', function (l) {
                return x(l.stop);
            }).attr('y1', function (l) {
                return yt(l.taskA) + ht(l.taskA);
            }).attr('x2', function (l) {
                return x(l.stop) - arrowWidth;
            }).attr('y2', function (l) {
                return yt(l.taskA) + ht(l.taskA) + arrowWidth;
            });
            lines.append('line').attr('x1', function (l) {
                return x(l.stop);
            }).attr('y1', function (l) {
                return yt(l.taskA) + ht(l.taskA);
            }).attr('x2', function (l) {
                return x(l.stop) + arrowWidth;
            }).attr('y2', function (l) {
                return yt(l.taskA) + ht(l.taskA) + arrowWidth;
            });
        };
        if ($routeParams["exchangeId"]) {
            $scope.query = $routeParams["exchangeId"];
            $scope.onQueryChange();
        }
    }
    Camin.Controller = Controller;
})(Camin || (Camin = {}));
var Camin;
(function (Camin) {
    var Diagram = (function () {
        function Diagram() {
            this.actors = [];
            this.signals = [];
        }
        Diagram.prototype.actor = function (name) {
            for(var i = 0; i < this.actors.length; i++) {
                if (this.actors[i].name === name) {
                    return this.actors[i];
                }
            }
            var actor = new Actor(name, this.actors.length);
            this.actors.push(actor);
            return actor;
        };
        Diagram.prototype.signal = function (actorA, actorB, message) {
            var signal = new Signal(actorA, actorB, message);
            this.signals.push(signal);
            return signal;
        };
        return Diagram;
    })();
    Camin.Diagram = Diagram;    
    var Actor = (function () {
        function Actor(name, index) {
            this.name = name;
            this.index = index;
        }
        return Actor;
    })();
    Camin.Actor = Actor;    
    var Signal = (function () {
        function Signal(actorA, actorB, message) {
            this.actorA = actorA;
            this.actorB = actorB;
            this.message = message;
        }
        Signal.prototype.isSelf = function () {
            return this.actorA.index === this.actorB.index;
        };
        return Signal;
    })();
    Camin.Signal = Signal;    
})(Camin || (Camin = {}));
var Camin;
(function (Camin) {
    var Gantt = (function () {
        function Gantt() {
            this.resources = [];
            this.tasks = [];
            this.links = [];
        }
        Gantt.prototype.resource = function (data) {
            var resource = new Resource(data, this.resources.length);
            this.resources.push(resource);
            return resource;
        };
        Gantt.prototype.task = function (resource, start, stop, data) {
            var task = resource.task(start, stop, data);
            this.tasks.push(task);
            return task;
        };
        Gantt.prototype.link = function (start, taskA, stop, taskB, data) {
            var link = new Link(start, taskA, stop, taskB, data);
            this.links.push(link);
            return link;
        };
        Gantt.prototype.layout = function () {
            for(var i = 0; i < this.resources.length; i++) {
                this.resources[i].layout();
                this.start = this.start ? Math.min(this.start, this.resources[i].start) : this.resources[i].start;
                this.stop = this.stop ? Math.max(this.stop, this.resources[i].stop) : this.resources[i].stop;
            }
            for(var i = 0; i < this.links.length; i++) {
                this.start = this.start ? Math.min(this.start, this.links[i].start) : this.links[i].start;
                this.stop = this.stop ? Math.max(this.stop, this.links[i].stop) : this.links[i].stop;
            }
        };
        Gantt.prototype.taskByData = function (data) {
            for(var i = 0; i < this.tasks.length; i++) {
                if (this.tasks[i].data === data) {
                    return this.tasks[i];
                }
            }
            return undefined;
        };
        return Gantt;
    })();
    Camin.Gantt = Gantt;    
    var Resource = (function () {
        function Resource(data, index) {
            this.tasks = [];
            this.index = index;
            this.data = data;
        }
        Resource.prototype.task = function (start, stop, data) {
            var task = new Task(start, stop, data, this);
            this.tasks.push(task);
            return task;
        };
        Resource.prototype.layout = function () {
            this.tasks.sort(function (ta, tb) {
                return ta.start - tb.start;
            });
            var bands = [];
            for(var i = 0; i < this.tasks.length; i++) {
                this.start = this.start ? Math.min(this.start, this.tasks[i].start) : this.tasks[i].start;
                this.stop = this.stop ? Math.max(this.stop, this.tasks[i].stop) : this.tasks[i].stop;
                for(var j = 0; j < bands.length; j++) {
                    if (bands[j] < this.tasks[i].start) {
                        bands[j] = this.tasks[i].stop;
                        this.tasks[i].index = j;
                        break;
                    }
                }
                if (!this.tasks[i].index) {
                    var index = bands.length;
                    this.tasks[i].index = index;
                    bands[index] = this.tasks[i].stop;
                }
            }
            for(var i = 0; i < this.tasks.length; i++) {
                this.tasks[i].max = bands.length;
            }
        };
        return Resource;
    })();
    Camin.Resource = Resource;    
    var Task = (function () {
        function Task(start, stop, data, resource) {
            this.start = start;
            this.stop = stop;
            this.data = data;
            this.resource = resource;
        }
        return Task;
    })();
    Camin.Task = Task;    
    var Link = (function () {
        function Link(start, taskA, stop, taskB, data) {
            this.start = start;
            this.stop = stop;
            this.taskA = taskA;
            this.taskB = taskB;
            this.data = data;
        }
        return Link;
    })();
    Camin.Link = Link;    
})(Camin || (Camin = {}));
var Camin;
(function (Camin) {
    var Sequence = (function () {
        function Sequence() {
            this.endpoints = [];
            this.execs = [];
            this.calls = [];
        }
        Sequence.prototype.endpoint = function (url, routeId, contextId, host) {
            for(var i = 0; i < this.endpoints.length; i++) {
                if (this.endpoints[i].url === url && this.endpoints[i].routeId === routeId && this.endpoints[i].contextId === contextId && this.endpoints[i].host === host) {
                    return this.endpoints[i];
                }
            }
            var endpoint = new Endpoint(url, routeId, contextId, host);
            this.endpoints.push(endpoint);
            return endpoint;
        };
        Sequence.prototype.exec = function (exchangeId, endpoint, start, stop) {
            var exec = new Execution(exchangeId, endpoint, start, stop);
            this.execs.push(exec);
            return exec;
        };
        Sequence.prototype.call = function (callId, execA, execB, start, stop) {
            var call = new Call(callId, execA, execB, start, stop);
            this.calls.push(call);
            return call;
        };
        Sequence.prototype.start = function () {
            var start;
            for(var i = 0; i < this.execs.length; i++) {
                start = start ? Math.min(start, this.execs[i].start) : this.execs[i].start;
            }
            for(var i = 0; i < this.calls.length; i++) {
                start = start ? Math.min(start, this.calls[i].start) : this.calls[i].start;
            }
            return start;
        };
        Sequence.prototype.stop = function () {
            var stop;
            for(var i = 0; i < this.execs.length; i++) {
                stop = stop ? Math.max(stop, this.execs[i].stop) : this.execs[i].stop;
            }
            for(var i = 0; i < this.calls.length; i++) {
                stop = stop ? Math.max(stop, this.calls[i].stop) : this.calls[i].stop;
            }
            return stop;
        };
        return Sequence;
    })();
    Camin.Sequence = Sequence;    
    var Endpoint = (function () {
        function Endpoint(url, routeId, contextId, host) {
            this.url = url;
            this.routeId = routeId;
            this.contextId = contextId;
            this.host = host;
        }
        return Endpoint;
    })();
    Camin.Endpoint = Endpoint;    
    var Execution = (function () {
        function Execution(exchangeId, endpoint, start, stop) {
            this.exchangeId = exchangeId;
            this.endpoint = endpoint;
            this.start = start;
            this.stop = stop;
        }
        return Execution;
    })();
    Camin.Execution = Execution;    
    var Call = (function () {
        function Call(callId, execA, execB, start, stop) {
            this.callId = callId;
            this.execA = execA;
            this.execB = execB;
            this.start = start;
            this.stop = stop;
        }
        return Call;
    })();
    Camin.Call = Call;    
})(Camin || (Camin = {}));
var CodeEditor;
(function (CodeEditor) {
    CodeEditor.GlobalCodeMirrorOptions = {
        theme: "default",
        tabSize: 4,
        lineNumbers: true,
        indentWithTabs: true,
        lineWrapping: true,
        autoCloseTags: true
    };
    function PreferencesController($scope, workspace, localStorage, $templateCache) {
        $scope.exampleText = $templateCache.get("exampleText");
        $scope.codeMirrorEx = $templateCache.get("codeMirrorExTemplate");
        $scope.javascript = "javascript";
        $scope.preferences = CodeEditor.GlobalCodeMirrorOptions;
        $scope.$watch("preferences", function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $scope.codeMirrorEx += " ";
                localStorage['CodeMirrorOptions'] = angular.toJson(angular.extend(CodeEditor.GlobalCodeMirrorOptions, $scope.preferences));
            }
        }, true);
    }
    CodeEditor.PreferencesController = PreferencesController;
    function detectTextFormat(value) {
        var answer = "text";
        if (value) {
            answer = "javascript";
            var trimmed = value.toString().trimLeft().trimRight();
            if (trimmed && trimmed.first() === '<' && trimmed.last() === '>') {
                answer = "xml";
            }
        }
        return answer;
    }
    CodeEditor.detectTextFormat = detectTextFormat;
    function autoFormatEditor(editor) {
        if (editor) {
            var totalLines = editor.lineCount();
            var start = {
                line: 0,
                ch: 0
            };
            var end = {
                line: totalLines - 1,
                ch: editor.getLine(totalLines - 1).length
            };
            editor.autoFormatRange(start, end);
            editor.setSelection(start, start);
        }
    }
    CodeEditor.autoFormatEditor = autoFormatEditor;
    function createEditorSettings(options) {
        if (typeof options === "undefined") { options = {}; }
        options.extraKeys = options.extraKeys || {};
        (function (mode) {
            mode = mode || {
                name: "text"
            };
            if (typeof mode !== "object") {
                mode = {
                    name: mode
                };
            }
            var modeName = mode.name;
            if (modeName === "javascript") {
                angular.extend(mode, {
                    "json": true
                });
            }
        })(options.mode);
        (function (options) {
            var javascriptFolding = CodeMirror.newFoldFunction(CodeMirror.braceRangeFinder);
            var xmlFolding = CodeMirror.newFoldFunction(CodeMirror.tagRangeFinder);
            var foldFunction = function (codeMirror, line) {
                var mode = codeMirror.getOption("mode");
                var modeName = mode["name"];
                if (!mode || !modeName) {
                    return;
                }
                if (modeName === 'javascript') {
                    javascriptFolding(codeMirror, line);
                } else if (modeName === "xml" || modeName.startsWith("html")) {
                    xmlFolding(codeMirror, line);
                }
                ;
            };
            options.onGutterClick = foldFunction;
            options.extraKeys = angular.extend(options.extraKeys, {
                "Ctrl-Q": function (codeMirror) {
                    foldFunction(codeMirror, codeMirror.getCursor().line);
                }
            });
        })(options);
        var readOnly = options.readOnly;
        if (!readOnly) {
            options.matchBrackets = true;
        }
        angular.extend(options, CodeEditor.GlobalCodeMirrorOptions);
        return options;
    }
    CodeEditor.createEditorSettings = createEditorSettings;
})(CodeEditor || (CodeEditor = {}));
var Core;
(function (Core) {
    function ConsoleController($scope, $element, $templateCache) {
        var _this = this;
        $scope.setHandler = function (clip) {
            clip.addEventListener('mouseDown', function (client, args) {
                var icon = $element.find('.icon-copy');
                if (this !== icon.get(0)) {
                    return;
                }
                var text = $templateCache.get("logClipboardTemplate").lines();
                text.removeAt(0);
                text.removeAt(text.length - 1);
                $element.find('#log-panel-statements').children().each(function (index, child) {
                    text.push('  <li>' + child.innerHTML + '</li>');
                });
                text.push('</ul>');
                clip.setText(text.join('\n'));
                Core.$apply($scope);
            });
        };
    }
    Core.ConsoleController = ConsoleController;
    function AppController($scope, $location, workspace, jolokia, jolokiaStatus, $document, pageTitle, localStorage, userDetails, lastLocation, jolokiaUrl, branding) {
        if (userDetails.username === null) {
            $location.url(defaultPage());
        }
        $scope.collapse = '';
        $scope.match = null;
        $scope.pageTitle = [];
        $scope.userDetails = userDetails;
        $scope.confirmLogout = false;
        $scope.connectionFailed = false;
        $scope.connectFailure = {};
        $scope.appName = branding.appName;
        $scope.appLogo = branding.appLogo;
        $scope.$watch('jolokiaStatus.xhr', function () {
            var failure = jolokiaStatus.xhr;
            $scope.connectionFailed = failure ? true : false;
            $scope.connectFailure.summaryMessage = null;
            if ($scope.connectionFailed) {
                $scope.connectFailure.status = failure.status;
                $scope.connectFailure.statusText = failure.statusText;
                var text = failure.responseText;
                if (text) {
                    try  {
                        var html = $(text);
                        var markup = html.find("body");
                        if (markup && markup.length) {
                            html = markup;
                        }
                        html.each(function (idx, e) {
                            var name = e.localName;
                            if (name && name.startsWith("h")) {
                                $(e).addClass("ajaxError");
                            }
                        });
                        var container = $("<div></div>");
                        container.append(html);
                        $scope.connectFailure.summaryMessage = container.html();
                        console.log("Found HTML: " + $scope.connectFailure.summaryMessage);
                    } catch (e) {
                        if (text.indexOf('<') < 0) {
                            $scope.connectFailure.summaryMessage = "<p>" + text + "</p>";
                        }
                    }
                }
            }
        });
        $scope.confirmConnectionFailed = function () {
            window.close();
        };
        $scope.setPageTitle = function () {
            $scope.pageTitle = pageTitle.getTitleArrayExcluding([
                branding.appName
            ]);
            var tab = workspace.getActiveTab();
            if (tab && tab.content) {
                Core.setPageTitleWithTab($document, pageTitle, tab.content);
            } else {
                Core.setPageTitle($document, pageTitle);
            }
        };
        $scope.setRegexIndicator = function () {
            try  {
                var regexs = angular.fromJson(localStorage['regexs']);
                if (regexs) {
                    regexs.reverse().each(function (regex) {
                        var r = new RegExp(regex.regex, 'g');
                        if (r.test($location.absUrl())) {
                            $scope.match = {
                                name: regex.name,
                                color: regex.color
                            };
                        }
                    });
                }
            } catch (e) {
            }
        };
        $scope.loggedIn = function () {
            return userDetails.username !== null && userDetails.username !== 'public';
        };
        $scope.showLogout = function () {
            return $scope.loggedIn() && angular.isDefined(userDetails.loginDetails);
        };
        $scope.logout = function () {
            $scope.confirmLogout = true;
        };
        $scope.getUsername = function () {
            if (userDetails.username && !userDetails.username.isBlank()) {
                return userDetails.username;
            } else {
                return 'user';
            }
        };
        $scope.doLogout = function () {
            $scope.confirmLogout = false;
            Core.logout(jolokiaUrl, userDetails, localStorage, $scope);
        };
        $scope.$watch(function () {
            return localStorage['regexs'];
        }, $scope.setRegexIndicator);
        $scope.maybeRedirect = function () {
            if (userDetails.username === null) {
                var currentUrl = $location.url();
                if (!currentUrl.startsWith('/login')) {
                    lastLocation.url = currentUrl;
                    $location.url('/login');
                }
            } else {
                if ($location.url().startsWith('/login')) {
                    var url = defaultPage();
                    if (angular.isDefined(lastLocation.url)) {
                        url = lastLocation.url;
                    }
                    $location.url(url);
                }
            }
        };
        $scope.$watch('userDetails', function (newValue, oldValue) {
            $scope.maybeRedirect();
        }, true);
        $scope.$on('$routeChangeStart', function () {
            $scope.maybeRedirect();
        });
        $scope.$on('$routeChangeSuccess', function () {
            $scope.setPageTitle();
            $scope.setRegexIndicator();
        });
        $scope.fullScreen = function () {
            if ($location.url().startsWith("/login")) {
                return branding.fullscreenLogin;
            }
            var tab = $location.search()['tab'];
            if (tab) {
                return tab === "fullscreen";
            }
            return false;
        };
        $scope.login = function () {
            return $location.url().startsWith("/login");
        };
        function defaultPage() {
            return Perspective.defaultPage($location, workspace, jolokia, localStorage);
        }
    }
    Core.AppController = AppController;
})(Core || (Core = {}));
var logQueryMBean = 'org.fusesource.insight:type=LogQuery';
var _urlPrefix = null;
var numberTypeNames = {
    'byte': true,
    'short': true,
    'int': true,
    'long': true,
    'float': true,
    'double': true,
    'java.lang.Byte': true,
    'java.lang.Short': true,
    'java.lang.Integer': true,
    'java.lang.Long': true,
    'java.lang.Float': true,
    'java.lang.Double': true
};
function lineCount(value) {
    var rows = 0;
    if (value) {
        rows = 1;
        value.toString().each(/\n/, function () {
            return rows++;
        });
    }
    return rows;
}
function url(path) {
    if (path) {
        if (path.startsWith && path.startsWith("/")) {
            if (_urlPrefix === null) {
                _urlPrefix = window.location.pathname || "";
                if (_urlPrefix) {
                    var idx = _urlPrefix.lastIndexOf("/");
                    if (idx >= 0) {
                        _urlPrefix = _urlPrefix.substring(0, idx);
                    }
                }
                console.log("URI prefix is " + _urlPrefix);
            }
            return _urlPrefix + path;
        }
    }
    return path;
}
function humanizeValue(value) {
    if (value) {
        var text = value.toString();
        try  {
            text = text.underscore();
        } catch (e) {
        }
        try  {
            text = text.humanize();
        } catch (e) {
        }
        return trimQuotes(text);
    }
    return value;
}
function safeNull(value) {
    if (value) {
        return value;
    } else {
        return "";
    }
}
function trimQuotes(text) {
    while(text.endsWith('"') || text.endsWith("'")) {
        text = text.substring(0, text.length - 1);
    }
    while(text.startsWith('"') || text.startsWith("'")) {
        text = text.substring(1, text.length);
    }
    return text;
}
function toSearchArgumentArray(value) {
    if (value) {
        if (angular.isArray(value)) {
            return value;
        }
        if (angular.isString(value)) {
            return value.split(',');
        }
    }
    return [];
}
function folderMatchesPatterns(node, patterns) {
    if (node) {
        var folderNames = node.folderNames;
        if (folderNames) {
            return patterns.any(function (ignorePaths) {
                for(var i = 0; i < ignorePaths.length; i++) {
                    var folderName = folderNames[i];
                    var ignorePath = ignorePaths[i];
                    if (!folderName) {
                        return false;
                    }
                    var idx = ignorePath.indexOf(folderName);
                    if (idx < 0) {
                        return false;
                    }
                }
                return true;
            });
        }
    }
    return false;
}
function scopeStoreJolokiaHandle($scope, jolokia, jolokiaHandle) {
    if (jolokiaHandle) {
        $scope.$on('$destroy', function () {
            closeHandle($scope, jolokia);
        });
        $scope.jolokiaHandle = jolokiaHandle;
    }
}
function closeHandle($scope, jolokia) {
    var jolokiaHandle = $scope.jolokiaHandle;
    if (jolokiaHandle) {
        jolokia.unregister(jolokiaHandle);
        $scope.jolokiaHandle = null;
    }
}
function onSuccess(fn, options) {
    if (typeof options === "undefined") { options = {}; }
    options['mimeType'] = 'application/json';
    if (angular.isDefined(fn)) {
        options['success'] = fn;
    }
    if (!options['method']) {
        options['method'] = "POST";
    }
    options['canonicalNaming'] = false;
    options['canonicalProperties'] = false;
    if (!options['error']) {
        options['error'] = function (response) {
            var stacktrace = response.stacktrace;
            if (stacktrace) {
                var silent = options['silent'];
                if (!silent) {
                    var operation = Core.pathGet(response, [
                        'request', 
                        'operation'
                    ]) || "unknown";
                    if (stacktrace.indexOf("javax.management.InstanceNotFoundException") >= 0 || stacktrace.indexOf("javax.management.AttributeNotFoundException") >= 0 || stacktrace.indexOf("java.lang.IllegalArgumentException: No operation") >= 0) {
                        Core.log.debug("Operation ", operation, " failed due to: ", response['error']);
                        Core.log.debug("Stack trace: ", Logger.formatStackTraceString(response['stacktrace']));
                    } else {
                        Core.log.warn("Operation ", operation, " failed due to: ", response['error']);
                        Core.log.info("Stack trace: ", Logger.formatStackTraceString(response['stacktrace']));
                    }
                }
            }
        };
    }
    return options;
}
function supportsLocalStorage() {
    try  {
        return 'localStorage' in window && window['localStorage'] !== null;
    } catch (e) {
        return false;
    }
}
function isNumberTypeName(typeName) {
    if (typeName) {
        var text = typeName.toString().toLowerCase();
        var flag = numberTypeNames[text];
        return flag;
    }
    return false;
}
function encodeMBeanPath(mbean) {
    return mbean.replace(/\//g, '!/').replace(':', '/').escapeURL();
}
function escapeMBeanPath(mbean) {
    return mbean.replace(/\//g, '!/').replace(':', '/');
}
function encodeMBean(mbean) {
    return mbean.replace(/\//g, '!/').escapeURL();
}
function escapeDots(text) {
    return text.replace(/\./g, '-');
}
function escapeTreeCssStyles(text) {
    return escapeDots(text).replace(/span/g, 'sp-an');
}
function showLogPanel() {
    var log = $("#log-panel");
    var body = $('body');
    localStorage['showLog'] = 'true';
    log.css({
        'bottom': '50%'
    });
    body.css({
        'overflow-y': 'hidden'
    });
}
function notification(type, message, options) {
    if (typeof options === "undefined") { options = null; }
    var w = window;
    if (options === null) {
        options = {};
    }
    if (type === 'error' || type === 'warning') {
        if (!angular.isDefined(options.onclick)) {
            options.onclick = showLogPanel;
        }
    }
    w.toastr[type](message, '', options);
}
function clearNotifications() {
    var w = window;
    w.toastr.clear();
}
function logLevelClass(level) {
    if (level) {
        var first = level[0];
        if (first === 'w' || first === "W") {
            return "warning";
        } else if (first === 'e' || first === "E") {
            return "error";
        } else if (first === 'd' || first === "d") {
            return "info";
        }
    }
    return "";
}
if (!Object.keys) {
    Object.keys = function (obj) {
        var keys = [], k;
        for(k in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, k)) {
                keys.push(k);
            }
        }
        return keys;
    };
}
var Core;
(function (Core) {
    function parseMBean(mbean) {
        var answer = {};
        var parts = mbean.split(":");
        if (parts.length > 1) {
            answer['domain'] = parts.first();
            parts = parts.exclude(parts.first());
            parts = parts.join(":");
            answer['attributes'] = {};
            var nameValues = parts.split(",");
            nameValues.forEach(function (str) {
                var nameValue = str.split('=');
                var name = nameValue.first().trim();
                nameValue = nameValue.exclude(nameValue.first());
                answer['attributes'][name] = nameValue.join('=').trim();
            });
        }
        return answer;
    }
    Core.parseMBean = parseMBean;
    function logout(jolokiaUrl, userDetails, localStorage, $scope, successCB, errorCB) {
        if (typeof successCB === "undefined") { successCB = null; }
        if (typeof errorCB === "undefined") { errorCB = null; }
        var url = jolokiaUrl.replace("jolokia", "auth/logout/");
        $.ajax(url, {
            type: "POST",
            success: function () {
                userDetails.username = null;
                userDetails.password = null;
                userDetails.loginDetails = null;
                userDetails.rememberMe = false;
                localStorage[jolokiaUrl] = angular.toJson(userDetails);
                if (successCB && angular.isFunction(successCB)) {
                    successCB();
                }
                Core.$apply($scope);
            },
            error: function (xhr, textStatus, error) {
                switch(xhr.status) {
                    case 401:
                        Core.log.error('Failed to log out, ', error);
                        break;
                    case 403:
                        Core.log.error('Failed to log out, ', error);
                        break;
                    default:
                        Core.log.error('Failed to log out, ', error);
                        break;
                }
                if (errorCB && angular.isFunction(errorCB)) {
                    errorCB();
                }
                Core.$apply($scope);
            }
        });
    }
    Core.logout = logout;
    function isBlank(str) {
        if (!str) {
            return true;
        }
        return str.isBlank();
    }
    Core.isBlank = isBlank;
    Core.log = Logger.get("Core");
    function createHref($location, href, removeParams) {
        if (typeof removeParams === "undefined") { removeParams = null; }
        var hashMap = angular.copy($location.search());
        if (removeParams) {
            angular.forEach(removeParams, function (param) {
                return delete hashMap[param];
            });
        }
        var hash = Core.hashToString(hashMap);
        if (hash) {
            var prefix = (href.indexOf("?") >= 0) ? "&" : "?";
            href += prefix + hash;
        }
        return href;
    }
    Core.createHref = createHref;
    function trimLeading(text, prefix) {
        if (text && prefix) {
            if (text.startsWith(prefix)) {
                return text.substring(prefix.length);
            }
        }
        return text;
    }
    Core.trimLeading = trimLeading;
    function trimTrailing(text, postfix) {
        if (text && postfix) {
            if (text.endsWith(postfix)) {
                return text.substring(0, text.length - postfix.length);
            }
        }
        return text;
    }
    Core.trimTrailing = trimTrailing;
    function hashToString(hash) {
        var keyValuePairs = [];
        angular.forEach(hash, function (value, key) {
            keyValuePairs.push(key + "=" + value);
        });
        var params = keyValuePairs.join("&");
        return encodeURI(params);
    }
    Core.hashToString = hashToString;
    function stringToHash(hashAsString) {
        var entries = {};
        if (hashAsString) {
            var text = decodeURI(hashAsString);
            var items = text.split('&');
            angular.forEach(items, function (item) {
                var kv = item.split('=');
                var key = kv[0];
                var value = kv[1] || key;
                entries[key] = value;
            });
        }
        return entries;
    }
    Core.stringToHash = stringToHash;
    function register(jolokia, scope, arguments, callback) {
        if (!angular.isDefined(scope.$jhandle) || !angular.isArray(scope.$jhandle)) {
            scope.$jhandle = [];
        }
        if (angular.isDefined(scope.$on)) {
            scope.$on('$destroy', function (event) {
                unregister(jolokia, scope);
            });
        }
        if (angular.isArray(arguments)) {
            if (arguments.length >= 1) {
                var args = [
                    callback
                ];
                angular.forEach(arguments, function (value) {
                    return args.push(value);
                });
                var registerFn = jolokia.register;
                var handle = registerFn.apply(jolokia, args);
                scope.$jhandle.push(handle);
                jolokia.request(arguments, callback);
            }
        } else {
            var handle = jolokia.register(callback, arguments);
            scope.$jhandle.push(handle);
            jolokia.request(arguments, callback);
        }
    }
    Core.register = register;
    function registerSearch(jolokia, scope, mbeanPattern, callback) {
        if (!angular.isDefined(scope.$jhandle) || !angular.isArray(scope.$jhandle)) {
            scope.$jhandle = [];
        }
        if (angular.isDefined(scope.$on)) {
            scope.$on('$destroy', function (event) {
                unregister(jolokia, scope);
            });
        }
        if (angular.isArray(arguments)) {
            if (arguments.length >= 1) {
                var args = [
                    callback
                ];
                angular.forEach(arguments, function (value) {
                    return args.push(value);
                });
                var registerFn = jolokia.register;
                var handle = registerFn.apply(jolokia, args);
                scope.$jhandle.push(handle);
                jolokia.search(mbeanPattern, callback);
            }
        } else {
            var handle = jolokia.register(callback, arguments);
            scope.$jhandle.push(handle);
            jolokia.search(mbeanPattern, callback);
        }
    }
    Core.registerSearch = registerSearch;
    function unregister(jolokia, scope) {
        if (angular.isDefined(scope.$jhandle)) {
            scope.$jhandle.forEach(function (handle) {
                jolokia.unregister(handle);
            });
            delete scope.$jhandle;
        }
    }
    Core.unregister = unregister;
    function xmlNodeToString(xmlNode) {
        try  {
            return (new XMLSerializer()).serializeToString(xmlNode);
        } catch (e) {
            try  {
                return xmlNode.xml;
            } catch (e) {
                console.log('WARNING: XMLSerializer not supported');
            }
        }
        return false;
    }
    Core.xmlNodeToString = xmlNodeToString;
    function isTextNode(node) {
        return node && node.nodeType === 3;
    }
    Core.isTextNode = isTextNode;
    function $applyNowOrLater($scope) {
        if ($scope.$$phase || $scope.$root.$$phase) {
            setTimeout(function () {
                Core.$apply($scope);
            }, 50);
        } else {
            $scope.$apply();
        }
    }
    Core.$applyNowOrLater = $applyNowOrLater;
    function $applyLater($scope, timeout) {
        if (typeof timeout === "undefined") { timeout = 50; }
        setTimeout(function () {
            Core.$apply($scope);
        }, timeout);
    }
    Core.$applyLater = $applyLater;
    function $apply($scope) {
        var phase = $scope.$$phase || $scope.$root.$$phase;
        if (!phase) {
            $scope.$apply();
        }
    }
    Core.$apply = $apply;
    function $digest($scope) {
        var phase = $scope.$$phase || $scope.$root.$$phase;
        if (!phase) {
            $scope.$digest();
        }
    }
    Core.$digest = $digest;
    function fileExtension(name, defaultValue) {
        if (typeof defaultValue === "undefined") { defaultValue = ""; }
        var extension = defaultValue;
        if (name) {
            var idx = name.lastIndexOf(".");
            if (idx > 0) {
                extension = name.substring(idx + 1, name.length).toLowerCase();
            }
        }
        return extension;
    }
    Core.fileExtension = fileExtension;
    function parseIntValue(value, description) {
        if (angular.isString(value)) {
            try  {
                return parseInt(value);
            } catch (e) {
                console.log("Failed to parse " + description + " with text '" + value + "'");
            }
        }
        return null;
    }
    Core.parseIntValue = parseIntValue;
    function parseFloatValue(value, description) {
        if (angular.isString(value)) {
            try  {
                return parseFloat(value);
            } catch (e) {
                console.log("Failed to parse " + description + " with text '" + value + "'");
            }
        }
        return null;
    }
    Core.parseFloatValue = parseFloatValue;
    function getOrCreateElements(domElement, arrayOfElementNames) {
        var element = domElement;
        angular.forEach(arrayOfElementNames, function (name) {
            if (element) {
                var children = $(element).children(name);
                if (!children || !children.length) {
                    $("<" + name + "></" + name + ">").appendTo(element);
                    children = $(element).children(name);
                }
                element = children;
            }
        });
        return element;
    }
    Core.getOrCreateElements = getOrCreateElements;
    function getUUID() {
        var d = new Date();
        var ms = (d.getTime() * 1000) + d.getUTCMilliseconds();
        var random = Math.floor((1 + Math.random()) * 0x10000);
        return ms.toString(16) + random.toString(16);
    }
    Core.getUUID = getUUID;
    function pathGet(object, paths) {
        var pathArray = (angular.isArray(paths)) ? paths : (paths || "").split(".");
        var value = object;
        angular.forEach(pathArray, function (name) {
            if (value) {
                try  {
                    value = value[name];
                } catch (e) {
                    return null;
                }
            } else {
                return null;
            }
        });
        return value;
    }
    Core.pathGet = pathGet;
    function pathSet(object, paths, newValue) {
        var pathArray = (angular.isArray(paths)) ? paths : (paths || "").split(".");
        var value = object;
        var lastIndex = pathArray.length - 1;
        angular.forEach(pathArray, function (name, idx) {
            var next = value[name];
            if (!angular.isObject(next)) {
                next = (idx < lastIndex) ? {} : newValue;
                value[name] = next;
            }
            value = next;
        });
        return value;
    }
    Core.pathSet = pathSet;
    var _escapeHtmlChars = {
        "#": "&#35;",
        "'": "&#39;",
        "<": "&lt;",
        "\"": "&quot;"
    };
    function unescapeHtml(str) {
        angular.forEach(_escapeHtmlChars, function (value, key) {
            var regex = new RegExp(value, "g");
            str = str.replace(regex, key);
        });
        str = str.replace(/&gt;/g, ">");
        return str;
    }
    Core.unescapeHtml = unescapeHtml;
    function escapeHtml(str) {
        if (angular.isString(str)) {
            var newStr = "";
            for(var i = 0; i < str.length; i++) {
                var ch = str.charAt(i);
                var ch = _escapeHtmlChars[ch] || ch;
                newStr += ch;
            }
            return newStr;
        } else {
            return str;
        }
    }
    Core.escapeHtml = escapeHtml;
    var _versionRegex = /[^\d]*(\d+)\.(\d+)(\.(\d+))?.*/;
    function parseVersionNumbers(text) {
        if (text) {
            var m = text.match(_versionRegex);
            if (m && m.length > 4) {
                var m1 = m[1];
                var m2 = m[2];
                var m4 = m[4];
                if (angular.isDefined(m4)) {
                    return [
                        parseInt(m1), 
                        parseInt(m2), 
                        parseInt(m4)
                    ];
                } else if (angular.isDefined(m2)) {
                    return [
                        parseInt(m1), 
                        parseInt(m2)
                    ];
                } else if (angular.isDefined(m1)) {
                    return [
                        parseInt(m1)
                    ];
                }
            }
        }
        return null;
    }
    Core.parseVersionNumbers = parseVersionNumbers;
    function versionToSortableString(version, maxDigitsBetweenDots) {
        if (typeof maxDigitsBetweenDots === "undefined") { maxDigitsBetweenDots = 4; }
        return (version || "").split(".").map(function (x) {
            var length = x.length;
            return (length >= maxDigitsBetweenDots) ? x : x.padLeft(' ', maxDigitsBetweenDots - length);
        }).join(".");
    }
    Core.versionToSortableString = versionToSortableString;
    function time(message, fn) {
        var start = new Date().getTime();
        var answer = fn();
        var elapsed = new Date().getTime() - start;
        console.log(message + " " + elapsed);
        return answer;
    }
    Core.time = time;
    function compareVersionNumberArrays(v1, v2) {
        if (v1 && !v2) {
            return 1;
        }
        if (!v1 && v2) {
            return -1;
        }
        if (v1 === v2) {
            return 0;
        }
        for(var i = 0; i < v1.length; i++) {
            var n1 = v1[i];
            if (i >= v2.length) {
                return 1;
            }
            var n2 = v2[i];
            if (!angular.isDefined(n1)) {
                return -1;
            }
            if (!angular.isDefined(n2)) {
                return 1;
            }
            if (n1 > n2) {
                return 1;
            } else if (n1 < n2) {
                return -1;
            }
        }
        return 0;
    }
    Core.compareVersionNumberArrays = compareVersionNumberArrays;
    function asArray(value) {
        return angular.isArray(value) ? value : [
            value
        ];
    }
    Core.asArray = asArray;
    function valueToHtml(value) {
        if (angular.isArray(value)) {
            var size = value.length;
            if (!size) {
                return "";
            } else if (size === 1) {
                return valueToHtml(value[0]);
            } else {
                var buffer = "<ul>";
                angular.forEach(value, function (childValue) {
                    buffer += "<li>" + valueToHtml(childValue) + "</li>";
                });
                return buffer + "</ul>";
            }
        } else if (angular.isObject(value)) {
            var buffer = "<table>";
            angular.forEach(value, function (childValue, key) {
                buffer += "<tr><td>" + key + "</td><td>" + valueToHtml(childValue) + "</td></tr>";
            });
            return buffer + "</table>";
        } else if (angular.isString(value)) {
            var uriPrefixes = [
                "http://", 
                "https://", 
                "file://", 
                "mailto:"
            ];
            var answer = value;
            angular.forEach(uriPrefixes, function (prefix) {
                if (answer.startsWith(prefix)) {
                    answer = "<a href='" + value + "'>" + value + "</a>";
                }
            });
            return answer;
        }
        return value;
    }
    Core.valueToHtml = valueToHtml;
    function tryParseJson(text) {
        text = text.trim();
        if ((text.startsWith("[") && text.endsWith("]")) || (text.startsWith("{") && text.endsWith("}"))) {
            try  {
                return JSON.parse(text);
            } catch (e) {
            }
        }
        return null;
    }
    Core.tryParseJson = tryParseJson;
    function maybePlural(count, word) {
        var pluralWord = (count === 1) ? word : word.pluralize();
        return "" + count + " " + pluralWord;
    }
    Core.maybePlural = maybePlural;
    function objectNameProperties(objectName) {
        var entries = {};
        if (objectName) {
            var idx = objectName.indexOf(":");
            if (idx > 0) {
                var path = objectName.substring(idx + 1);
                var items = path.split(',');
                angular.forEach(items, function (item) {
                    var kv = item.split('=');
                    var key = kv[0];
                    var value = kv[1] || key;
                    entries[key] = value;
                });
            }
        }
        return entries;
    }
    Core.objectNameProperties = objectNameProperties;
    function setPageTitle($document, title) {
        $document.attr('title', title.getTitleWithSeparator(' '));
    }
    Core.setPageTitle = setPageTitle;
    function setPageTitleWithTab($document, title, tab) {
        $document.attr('title', title.getTitleWithSeparator(' ') + " " + tab);
    }
    Core.setPageTitleWithTab = setPageTitleWithTab;
    function getMBeanTypeFolder(workspace, domain, typeName) {
        if (workspace) {
            var mbeanTypesToDomain = workspace.mbeanTypesToDomain || {};
            var types = mbeanTypesToDomain[typeName] || {};
            var answer = types[domain];
            if (angular.isArray(answer) && answer.length) {
                return answer[0];
            }
            return answer;
        }
        return null;
    }
    Core.getMBeanTypeFolder = getMBeanTypeFolder;
    function getMBeanTypeObjectName(workspace, domain, typeName) {
        var folder = Core.getMBeanTypeFolder(workspace, domain, typeName);
        return Core.pathGet(folder, [
            "objectName"
        ]);
    }
    Core.getMBeanTypeObjectName = getMBeanTypeObjectName;
    function toSafeDomID(text) {
        return text ? text.replace(/(\/|\.)/g, "_") : text;
    }
    Core.toSafeDomID = toSafeDomID;
    function forEachLeafFolder(folders, fn) {
        angular.forEach(folders, function (folder) {
            var children = folder["children"];
            if (angular.isArray(children) && children.length > 0) {
                forEachLeafFolder(children, fn);
            } else {
                fn(folder);
            }
        });
    }
    Core.forEachLeafFolder = forEachLeafFolder;
    function extractHashURL(url) {
        var parts = url.split('#');
        if (parts.length === 0) {
            return url;
        }
        var answer = parts[1];
        if (parts.length > 1) {
            var remaining = parts.last(parts.length - 2);
            remaining.forEach(function (part) {
                answer = answer + "#" + part;
            });
        }
        return answer;
    }
    Core.extractHashURL = extractHashURL;
    function getBasicAuthHeader(username, password) {
        var authInfo = username + ":" + password;
        authInfo = btoa(authInfo);
        return "Basic " + authInfo;
    }
    Core.getBasicAuthHeader = getBasicAuthHeader;
    var ConnectToServerOptions = (function () {
        function ConnectToServerOptions() {
            this.useProxy = true;
        }
        return ConnectToServerOptions;
    })();
    Core.ConnectToServerOptions = ConnectToServerOptions;    
    function getDocHeight() {
        var D = document;
        return Math.max(Math.max(D.body.scrollHeight, D.documentElement.scrollHeight), Math.max(D.body.offsetHeight, (D.documentElement).offsetHeight), Math.max(D.body.clientHeight, D.documentElement.clientHeight));
    }
    Core.getDocHeight = getDocHeight;
    function useProxyIfExternal(connectUrl) {
        var host = window.location.host;
        if (!connectUrl.startsWith("http://" + host + "/") && !connectUrl.startsWith("https://" + host + "/")) {
            var idx = connectUrl.indexOf("://");
            if (idx > 0) {
                connectUrl = connectUrl.substring(idx + 3);
            }
            connectUrl = connectUrl.replace(":", "/");
            connectUrl = Core.trimLeading(connectUrl, "/");
            connectUrl = Core.trimTrailing(connectUrl, "/");
            connectUrl = url("/proxy/" + connectUrl);
        }
        return connectUrl;
    }
    Core.useProxyIfExternal = useProxyIfExternal;
    function connectToServer(localStorage, options) {
        var connectUrl = options.jolokiaUrl;
        var userDetails = {
            username: null,
            password: null
        };
        if (options.userName) {
            userDetails.username = options.userName;
        }
        if (options.password) {
            userDetails.password = options.password;
        }
        var json = angular.toJson(userDetails);
        if (connectUrl) {
            localStorage[connectUrl] = json;
        }
        var view = options.view;
        var full = "";
        if (connectUrl) {
            if (options.useProxy) {
                var idx = connectUrl.indexOf("://");
                if (idx > 0) {
                    connectUrl = connectUrl.substring(idx + 3);
                }
                connectUrl = connectUrl.replace(":", "/");
                connectUrl = Core.trimLeading(connectUrl, "/");
                connectUrl = Core.trimTrailing(connectUrl, "/");
                connectUrl = url("/proxy/" + connectUrl);
            } else {
                if (connectUrl.indexOf("://") < 0) {
                    connectUrl = "http://" + connectUrl;
                }
            }
            console.log("going to server: " + connectUrl + " as user " + options.userName);
            localStorage[connectUrl] = json;
            full = "?url=" + encodeURIComponent(connectUrl);
            if (view) {
                full += "#" + view;
            }
        } else {
            var host = options.host || "localhost";
            var port = options.port;
            var path = Core.trimLeading(options.path || "jolokia", "/");
            path = Core.trimTrailing(path, "/");
            if (port > 0) {
                host += ":" + port;
            }
            var connectUrl = host + "/" + path;
            localStorage[connectUrl] = json;
            if (options.useProxy) {
                connectUrl = url("/proxy/" + connectUrl);
            } else {
                if (connectUrl.indexOf("://") < 0) {
                    connectUrl = "http://" + connectUrl;
                }
            }
            console.log("going to server: " + connectUrl + " as user " + options.userName);
            localStorage[connectUrl] = json;
            full = "?url=" + encodeURIComponent(connectUrl);
            if (view) {
                full += "#" + view;
            }
        }
        if (full) {
            Core.log.info("Full URL is: " + full);
            window.open(full);
        }
    }
    Core.connectToServer = connectToServer;
    function bindModelToSearchParam($scope, $location, modelName, paramName, initialValue) {
        if (typeof initialValue === "undefined") { initialValue = null; }
        function currentValue() {
            return $location.search()[paramName] || initialValue;
        }
        var value = currentValue();
        Core.pathSet($scope, modelName, value);
        $scope.$watch(modelName, function () {
            var current = Core.pathGet($scope, modelName);
            if (current) {
                var params = $location.search();
                var old = currentValue();
                if (current !== old) {
                    $location.search(paramName, current);
                }
            } else {
                $location.search(paramName, null);
            }
        });
    }
    Core.bindModelToSearchParam = bindModelToSearchParam;
    function reloadWhenParametersChange($route, $scope, $location, parameters) {
        if (typeof parameters === "undefined") { parameters = [
            "nid"
        ]; }
        var initial = angular.copy($location.search());
        $scope.$on('$routeUpdate', function () {
            var current = $location.search();
            var changed = [];
            angular.forEach(parameters, function (param) {
                if (current[param] !== initial[param]) {
                    changed.push(param);
                }
            });
            if (changed.length) {
                Core.log.info("Reloading page due to change to parameters: " + changed);
                $route.reload();
            }
        });
    }
    Core.reloadWhenParametersChange = reloadWhenParametersChange;
    function createJolokia(url, username, password) {
        var jolokiaParams = {
            url: url,
            username: username,
            password: password,
            canonicalNaming: false,
            ignoreErrors: true,
            mimeType: 'application/json'
        };
        return new Jolokia(jolokiaParams);
    }
    Core.createJolokia = createJolokia;
    function throttled(fn, millis) {
        var nextInvokeTime = 0;
        var lastAnswer = null;
        return function () {
            var now = Date.now();
            if (nextInvokeTime < now) {
                nextInvokeTime = now + millis;
                lastAnswer = fn();
            } else {
                Core.log.debug("Not invoking function as we did call " + (now - (nextInvokeTime - millis)) + " ms ago");
            }
            return lastAnswer;
        };
    }
    Core.throttled = throttled;
    function parseJsonText(text, message) {
        if (typeof message === "undefined") { message = "JSON"; }
        var answer = null;
        try  {
            answer = angular.fromJson(text);
        } catch (e) {
            Core.log.info("Failed to parse " + message + " from: " + text + ". " + e);
        }
        return answer;
    }
    Core.parseJsonText = parseJsonText;
})(Core || (Core = {}));
var _this = this;
var Core;
(function (Core) {
    Core.pluginName = 'hawtioCore';
})(Core || (Core = {}));
var jolokiaUrls = [
    "/" + window.location.pathname.split('/')[1] + "/jolokia", 
    "/hawtio/jolokia", 
    "/jolokia"
];
var jolokiaUrl = getJolokiaUrl();
console.log("jolokiaUrl " + jolokiaUrl);
function getJolokiaUrl() {
    var query = hawtioPluginLoader.parseQueryString();
    var uri = query['url'];
    if (angular.isArray(uri)) {
        uri = uri[0];
    }
    return uri ? decodeURIComponent(uri) : null;
}
if (!jolokiaUrl) {
    jolokiaUrl = jolokiaUrls.find(function (url) {
        var jqxhr = $.ajax(url, {
            async: false,
            username: 'public',
            password: 'biscuit'
        });
        return jqxhr.status === 200 || jqxhr.status === 401 || jqxhr.status === 403;
    });
}
hawtioPluginLoader.addUrl("/hawtio/plugin");
if (jolokiaUrl) {
}
hawtioPluginLoader.addModule(Core.pluginName);
angular.module(Core.pluginName, [
    'bootstrap', 
    'ngResource', 
    'ui', 
    'ui.bootstrap.dialog', 
    'hawtio-ui'
]).config(function ($routeProvider, $dialogProvider) {
    $dialogProvider.options({
        backdropFade: true,
        dialogFade: true
    });
    $routeProvider.when('/login', {
        templateUrl: 'app/core/html/login.html'
    }).when('/preferences', {
        templateUrl: 'app/core/html/preferences.html'
    }).when('/help', {
        redirectTo: '/help/index'
    }).when('/help/:topic/', {
        templateUrl: 'app/core/html/help.html'
    }).when('/help/:topic/:subtopic', {
        templateUrl: 'app/core/html/help.html'
    }).otherwise({
        redirectTo: '/perspective/defaultPage'
    });
}).constant('layoutTree', 'app/core/html/layoutTree.html').constant('layoutFull', 'app/core/html/layoutFull.html').service('localStorage', function () {
    var storage = window.localStorage || (function () {
        return {};
    })();
    return storage;
}).factory('marked', function () {
    marked.setOptions({
        gfm: true,
        tables: true,
        breaks: false,
        pedantic: true,
        sanitize: false,
        smartLists: true,
        langPrefix: 'language-'
    });
    return marked;
}).factory('pageTitle', function () {
    var answer = new Core.PageTitle();
    return answer;
}).factory('viewRegistry', function () {
    return {};
}).factory('lastLocation', function () {
    return {};
}).factory('helpRegistry', function ($rootScope) {
    return new Core.HelpRegistry($rootScope);
}).factory('jolokiaUrl', function () {
    return jolokiaUrl;
}).factory('jolokiaStatus', function () {
    return {
        xhr: null
    };
}).factory('jolokiaParams', function (jolokiaUrl) {
    return {
        url: jolokiaUrl,
        canonicalNaming: false,
        ignoreErrors: true,
        mimeType: 'application/json'
    };
}).factory('branding', function () {
    return {
        appName: 'hawtio',
        appLogo: 'img/logo-16px.png',
        loginBg: 'img/fire.jpg',
        fullscreenLogin: false
    };
}).factory('userDetails', function (jolokiaUrl, localStorage) {
    var answer = angular.fromJson(localStorage[jolokiaUrl]);
    if (!angular.isDefined(answer)) {
        return {
            username: '',
            password: ''
        };
    } else {
        return answer;
    }
}).factory('jolokia', function ($location, localStorage, jolokiaStatus, $rootScope, userDetails, jolokiaParams) {
    console.log("Jolokia URL is " + jolokiaUrl);
    if (jolokiaUrl) {
        var credentials = hawtioPluginLoader.getCredentials(jolokiaUrl);
        var username = null;
        var password = null;
        if (credentials.length === 2) {
            username = credentials[0];
            password = credentials[1];
        } else if (angular.isDefined(userDetails) && angular.isDefined(userDetails.username) && angular.isDefined(userDetails.password)) {
            username = userDetails.username;
            password = userDetails.password;
        } else if (angular.isDefined(userDetails) && angular.isDefined(userDetails.userName) && angular.isDefined(userDetails.password)) {
            username = userDetails.userName;
            password = userDetails.password;
        } else {
            var search = hawtioPluginLoader.parseQueryString();
            username = search["_user"];
            password = search["_pwd"];
            if (angular.isArray(username)) {
                username = username[0];
            }
            if (angular.isArray(password)) {
                password = password[0];
            }
        }
        if (username && password) {
            userDetails.username = username;
            userDetails.password = password;
            $.ajaxSetup({
                beforeSend: function (xhr) {
                    xhr.setRequestHeader('Authorization', Core.getBasicAuthHeader(userDetails.username, userDetails.password));
                }
            });
            var loginUrl = jolokiaUrl.replace("jolokia", "auth/login/");
            $.ajax(loginUrl, {
                type: "POST",
                success: function (response) {
                    userDetails.loginDetails = response;
                },
                error: function (xhr, textStatus, error) {
                }
            });
        }
        jolokiaParams['ajaxError'] = function (xhr, textStatus, error) {
            if (xhr.status === 401 || xhr.status === 403) {
                userDetails.username = null;
                userDetails.password = null;
            } else {
                jolokiaStatus.xhr = xhr;
                if (!xhr.responseText && error) {
                    xhr.responseText = error.stack;
                }
            }
            Core.$apply($rootScope);
        };
        var jolokia = new Jolokia(jolokiaParams);
        localStorage['url'] = jolokiaUrl;
        jolokia.stop();
        return jolokia;
    } else {
        return {
            request: function () {
                return null;
            },
            register: function () {
                return null;
            },
            list: function () {
                return null;
            },
            search: function () {
                return null;
            },
            read: function () {
                return null;
            },
            execute: function () {
                return null;
            },
            start: function () {
                _this.running = true;
                return null;
            },
            stop: function () {
                _this.running = false;
                return null;
            },
            isRunning: function () {
                return _this.running;
            },
            jobs: function () {
                return [];
            }
        };
    }
}).factory('toastr', function () {
    return (window).toastr;
}).factory('xml2json', function ($window) {
    var jquery = $;
    return jquery.xml2json;
}).factory('workspace', function ($location, jmxTreeLazyLoadRegistry, $compile, $templateCache, localStorage, jolokia, jolokiaStatus, $rootScope) {
    var answer = new Workspace(jolokia, jolokiaStatus, jmxTreeLazyLoadRegistry, $location, $compile, $templateCache, localStorage, $rootScope);
    answer.loadTree();
    return answer;
}).filter("valueToHtml", function () {
    return Core.valueToHtml;
}).filter('humanize', function () {
    return humanizeValue;
}).directive('autofill', [
    '$timeout', 
    function ($timeout) {
        return {
            restrict: "A",
            require: 'ngModel',
            link: function (scope, elem, attrs, ctrl) {
                var ngModel = attrs["ngModel"];
                if (ngModel) {
                    var log = Logger.get("Core");
                    function checkForDifference() {
                        var modelValue = scope.$eval(ngModel);
                        var value = elem.val();
                        if (value && !modelValue) {
                            Core.pathSet(scope, ngModel, value);
                        } else {
                            elem.trigger('input');
                            elem.trigger('change');
                            if (elem.length) {
                                var firstElem = $(elem[0]);
                                firstElem.trigger('input');
                                firstElem.trigger('change');
                            }
                        }
                    }
                    $timeout(checkForDifference, 200);
                    $timeout(checkForDifference, 800);
                    $timeout(checkForDifference, 1500);
                }
            }
        };
    }]).run(function ($rootScope, $routeParams, jolokia, workspace, localStorage, viewRegistry, layoutFull, helpRegistry, pageTitle, branding, toastr) {
    $.support.cors = true;
    $rootScope.lineCount = lineCount;
    $rootScope.params = $routeParams;
    $rootScope.is = function (type, value) {
        return angular['is' + type](value);
    };
    $rootScope.empty = function (value) {
        return $.isEmptyObject(value);
    };
    $rootScope.$on('UpdateRate', function (event, rate) {
        jolokia.stop();
        if (rate > 0) {
            jolokia.start(rate);
        }
        Core.log.info("Set update rate to: ", rate);
    });
    $rootScope.$emit('UpdateRate', localStorage['updateRate']);
    $rootScope.log = function (variable) {
        console.log(variable);
    };
    $rootScope.alert = function (text) {
        alert(text);
    };
    viewRegistry['fullscreen'] = layoutFull;
    viewRegistry['notree'] = layoutFull;
    viewRegistry['help'] = layoutFull;
    viewRegistry['preferences'] = layoutFull;
    viewRegistry['login'] = layoutFull;
    helpRegistry.addUserDoc('index', 'app/core/doc/overview.md');
    helpRegistry.addSubTopic('index', 'faq', 'app/core/doc/FAQ.md');
    helpRegistry.addSubTopic('index', 'changes', 'app/core/doc/CHANGES.md');
    helpRegistry.addSubTopic('index', 'developer', 'app/core/doc/developer.md');
    helpRegistry.addDevDoc('Core', 'app/core/doc/coreDeveloper.md');
    var opts = localStorage['CodeMirrorOptions'];
    if (opts) {
        opts = angular.fromJson(opts);
        CodeEditor.GlobalCodeMirrorOptions = angular.extend(CodeEditor.GlobalCodeMirrorOptions, opts);
    }
    toastr.options = {
        'closeButton': true,
        'showMethod': 'slideDown',
        'hideMethod': 'slideUp'
    };
    window['logInterceptors'].push(function (level, message) {
        if (level === "WARN") {
            notification('warning', message);
        }
        if (level === "ERROR") {
            notification('error', message);
        }
    });
    setTimeout(function () {
        $("#main-body").fadeIn(2000).after(function () {
            Core.log.info("<strong>Hawtio started!</strong>");
        });
    }, 500);
}).directive('compile', [
    '$compile', 
    function ($compile) {
        return function (scope, element, attrs) {
            scope.$watch(function (scope) {
                return scope.$eval(attrs.compile);
            }, function (value) {
                element.html(value);
                $compile(element.contents())(scope);
            });
        };
    }]).directive('noClick', function () {
    return function ($scope, $element, $attrs) {
        $element.click(function (event) {
            event.preventDefault();
        });
    };
}).directive('gridStyle', function ($window) {
    return new Core.GridStyle($window);
}).directive('logToggler', function (localStorage) {
    return {
        restrict: 'A',
        link: function ($scope, $element, $attr) {
            $element.click(function () {
                var log = $("#log-panel");
                var body = $('body');
                if (log.height() !== 0) {
                    localStorage['showLog'] = 'false';
                    log.css({
                        'bottom': '110%'
                    });
                    body.css({
                        'overflow-y': 'auto'
                    });
                } else {
                    localStorage['showLog'] = 'true';
                    log.css({
                        'bottom': '50%'
                    });
                    body.css({
                        'overflow-y': 'hidden'
                    });
                }
                return false;
            });
        }
    };
});
$(function () {
    $("a[title]").tooltip({
        selector: '',
        delay: {
            show: 1000,
            hide: 100
        }
    });
});
var adjustHeight = function () {
    var windowHeight = $(window).height();
    var headerHeight = $("#main-nav").height();
    var containerHeight = windowHeight - headerHeight;
    $("#main").css("min-height", "" + containerHeight + "px");
};
$(function () {
    hawtioPluginLoader.loadPlugins(function () {
        var doc = $(document);
        angular.bootstrap(doc, hawtioPluginLoader.getModules());
        $(document.documentElement).attr('xmlns:ng', "http://angularjs.org");
        $(document.documentElement).attr('ng-app', 'hawtioCore');
        adjustHeight();
        $(window).resize(adjustHeight);
    });
});
var Core;
(function (Core) {
    var Dialog = (function () {
        function Dialog() {
            this.show = false;
            this.options = {
                backdropFade: true,
                dialogFade: true
            };
        }
        Dialog.prototype.open = function () {
            this.show = true;
        };
        Dialog.prototype.close = function () {
            this.show = false;
            this.removeBackdropFadeDiv();
            setTimeout(this.removeBackdropFadeDiv, 100);
        };
        Dialog.prototype.removeBackdropFadeDiv = function () {
            $("div.modal-backdrop").remove();
        };
        return Dialog;
    })();
    Core.Dialog = Dialog;    
})(Core || (Core = {}));
var Core;
(function (Core) {
    function EditorController($scope, workspace) {
        var options = {
            readOnly: true,
            mode: {
                name: CodeEditor.detectTextFormat($scope.row.Text)
            }
        };
        $scope.codeMirrorOptions = CodeEditor.createEditorSettings(options);
    }
    Core.EditorController = EditorController;
})(Core || (Core = {}));
var __extends = this.__extends || function (d, b) {
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var Core;
(function (Core) {
    var Folder = (function () {
        function Folder(title) {
            this.title = title;
            this.key = null;
            this.typeName = null;
            this.children = [];
            this.folderNames = [];
            this.domain = null;
            this.objectName = null;
            this.map = {};
            this.entries = {};
            this.addClass = null;
            this.parent = null;
            this.isLazy = false;
            this.icon = null;
            this.tooltip = null;
            this.entity = null;
            this.addClass = escapeTreeCssStyles(title);
        }
        Folder.prototype.get = function (key) {
            return this.map[key];
        };
        Folder.prototype.isFolder = function () {
            return this.children.length > 0;
        };
        Folder.prototype.navigate = function () {
            var paths = [];
            for (var _i = 0; _i < (arguments.length - 0); _i++) {
                paths[_i] = arguments[_i + 0];
            }
            var node = this;
            paths.forEach(function (path) {
                if (node) {
                    node = node.get(path);
                }
            });
            return node;
        };
        Folder.prototype.hasEntry = function (key, value) {
            var entries = this.entries;
            if (entries) {
                var actual = entries[key];
                return actual && value === actual;
            }
            return false;
        };
        Folder.prototype.parentHasEntry = function (key, value) {
            if (this.parent) {
                return this.parent.hasEntry(key, value);
            }
            return false;
        };
        Folder.prototype.ancestorHasEntry = function (key, value) {
            var parent = this.parent;
            while(parent) {
                if (parent.hasEntry(key, value)) {
                    return true;
                }
                parent = parent.parent;
            }
            return false;
        };
        Folder.prototype.ancestorHasType = function (typeName) {
            var parent = this.parent;
            while(parent) {
                if (typeName === parent.typeName) {
                    return true;
                }
                parent = parent.parent;
            }
            return false;
        };
        Folder.prototype.getOrElse = function (key, defaultValue) {
            if (typeof defaultValue === "undefined") { defaultValue = new Folder(key); }
            var answer = this.map[key];
            if (!answer) {
                answer = defaultValue;
                this.map[key] = answer;
                this.children.push(answer);
                answer.parent = this;
                this.children = this.children.sortBy("title");
            }
            return answer;
        };
        Folder.prototype.sortChildren = function (recursive) {
            var children = this.children;
            if (children) {
                this.children = children.sortBy("title");
                if (recursive) {
                    angular.forEach(children, function (child) {
                        return child.sortChildren(recursive);
                    });
                }
            }
        };
        Folder.prototype.moveChild = function (child) {
            if (child && child.parent !== this) {
                child.detach();
                child.parent = this;
                this.children.push(child);
            }
        };
        Folder.prototype.detach = function () {
            var oldParent = this.parent;
            if (oldParent) {
                var oldParentChildren = oldParent.children;
                if (oldParentChildren) {
                    var idx = oldParentChildren.indexOf(this);
                    if (idx < 0) {
                        oldParent.children = oldParent.children.remove({
                            key: this.key
                        });
                    } else {
                        oldParentChildren.splice(idx, 1);
                    }
                }
                this.parent = null;
            }
        };
        Folder.prototype.findDescendant = function (filter) {
            if (filter(this)) {
                return this;
            }
            var answer = null;
            angular.forEach(this.children, function (child) {
                if (!answer) {
                    answer = child.findDescendant(filter);
                }
            });
            return answer;
        };
        return Folder;
    })();
    Core.Folder = Folder;    
})(Core || (Core = {}));
;
var Folder = (function (_super) {
    __extends(Folder, _super);
    function Folder() {
        _super.apply(this, arguments);

    }
    return Folder;
})(Core.Folder);
;
var Core;
(function (Core) {
    function d3ForceGraph(scope, nodes, links, canvasElement) {
        if (scope.graphForce) {
            scope.graphForce.stop();
        }
        if (!canvasElement) {
            canvasElement = $("#canvas")[0];
        }
        var canvasDiv = $(canvasElement);
        canvasDiv.children("svg").remove();
        if (nodes.length) {
            var width = canvasDiv.parent().width();
            var height = canvasDiv.parent().height();
            if (height < 100) {
                var offset = canvasDiv.offset();
                height = $(document).height() - 5;
                if (offset) {
                    height -= offset['top'];
                }
            }
            var svg = d3.select(canvasDiv[0]).append("svg").attr("width", width).attr("height", height);
            var force = d3.layout.force().distance(100).charge(-120 * 10).linkDistance(50).size([
                width, 
                height
            ]);
            scope.graphForce = force;
            svg.append("svg:defs").selectAll("marker").data([
                "from"
            ]).enter().append("svg:marker").attr("id", String).attr("viewBox", "0 -5 10 10").attr("refX", 25).attr("refY", -1.5).attr("markerWidth", 6).attr("markerHeight", 6).attr("orient", "auto").append("svg:path").attr("d", "M0,-5L10,0L0,5");
            force.nodes(nodes).links(links).start();
            var link = svg.selectAll(".link").data(links).enter().append("line").attr("class", "link");
            link.attr("class", "link from");
            link.attr("marker-end", "url(#from)");
            var node = svg.selectAll(".node").data(nodes).enter().append("g").attr("class", "node").call(force.drag);
            node.append("image").attr("xlink:href", function (d) {
                return d.imageUrl;
            }).attr("x", -15).attr("y", -15).attr("width", 30).attr("height", 30);
            node.append("text").attr("dx", 20).attr("dy", ".35em").text(function (d) {
                return d.label;
            });
            force.on("tick", function () {
                link.attr("x1", function (d) {
                    return d.source.x;
                }).attr("y1", function (d) {
                    return d.source.y;
                }).attr("x2", function (d) {
                    return d.target.x;
                }).attr("y2", function (d) {
                    return d.target.y;
                });
                node.attr("transform", function (d) {
                    return "translate(" + d.x + "," + d.y + ")";
                });
            });
        }
    }
    Core.d3ForceGraph = d3ForceGraph;
    function createGraphStates(nodes, links, transitions) {
        var stateKeys = {};
        nodes.forEach(function (node) {
            var idx = node.id;
            if (idx === undefined) {
                console.log("No node found for node " + JSON.stringify(node));
            } else {
                if (node.edges === undefined) {
                    node.edges = [];
                }
                if (!node.label) {
                    node.label = "node " + idx;
                }
                stateKeys[idx] = node;
            }
        });
        var states = d3.values(stateKeys);
        links.forEach(function (d) {
            var source = stateKeys[d.source];
            var target = stateKeys[d.target];
            if (source === undefined || target === undefined) {
                console.log("Bad link!  " + source + " target " + target + " for " + d);
            } else {
                var edge = {
                    source: source,
                    target: target
                };
                transitions.push(edge);
                source.edges.push(edge);
                target.edges.push(edge);
            }
        });
        return states;
    }
    Core.createGraphStates = createGraphStates;
    function dagreLayoutGraph(nodes, links, width, height, svgElement) {
        var nodePadding = 10;
        var transitions = [];
        var states = Core.createGraphStates(nodes, links, transitions);
        function spline(e) {
            var points = e.dagre.points.slice(0);
            var source = dagre.util.intersectRect(e.source.dagre, points.length > 0 ? points[0] : e.source.dagre);
            var target = dagre.util.intersectRect(e.target.dagre, points.length > 0 ? points[points.length - 1] : e.source.dagre);
            points.unshift(source);
            points.push(target);
            return d3.svg.line().x(function (d) {
                return d.x;
            }).y(function (d) {
                return d.y;
            }).interpolate("linear")(points);
        }
        function translateEdge(e, dx, dy) {
            e.dagre.points.forEach(function (p) {
                p.x = Math.max(0, Math.min(svgBBox.width, p.x + dx));
                p.y = Math.max(0, Math.min(svgBBox.height, p.y + dy));
            });
        }
        var svg = svgElement ? d3.select(svgElement) : d3.select("svg");
        if (svgElement) {
            $(svgElement).children("g").remove();
        }
        $(svg).children("g").remove();
        var svgGroup = svg.append("g").attr("transform", "translate(5, 5)");
        var nodes = svgGroup.selectAll("g .node").data(states).enter().append("g").attr("class", "node").attr("data-cid", function (d) {
            return d.cid;
        }).attr("id", function (d) {
            return "node-" + d.label;
        });
        nodes.append("title").text(function (d) {
            return d.tooltip || "";
        });
        var edges = svgGroup.selectAll("path .edge").data(transitions).enter().append("path").attr("class", "edge").attr("marker-end", "url(#arrowhead)");
        var rects = nodes.append("rect").attr("rx", "5").attr("ry", "5").attr("filter", "url(#drop-shadow)");
        var images = nodes.append("image").attr("xlink:href", function (d) {
            return d.imageUrl;
        }).attr("x", -12).attr("y", -20).attr("height", 24).attr("width", 24);
        var counters = nodes.append("text").attr("text-anchor", "end").attr("class", "counter").attr("x", 0).attr("dy", 0).text(_counterFunction);
        var labels = nodes.append("text").attr("text-anchor", "middle").attr("x", 0);
        labels.append("tspan").attr("x", 0).attr("dy", 28).text(function (d) {
            return d.label;
        });
        var labelPadding = 12;
        var minLabelwidth = 80;
        labels.each(function (d) {
            var bbox = this.getBBox();
            d.bbox = bbox;
            if (bbox.width < minLabelwidth) {
                bbox.width = minLabelwidth;
            }
            d.width = bbox.width + 2 * nodePadding;
            d.height = bbox.height + 2 * nodePadding + labelPadding;
        });
        rects.attr("x", function (d) {
            return -(d.bbox.width / 2 + nodePadding);
        }).attr("y", function (d) {
            return -(d.bbox.height / 2 + nodePadding + (labelPadding / 2));
        }).attr("width", function (d) {
            return d.width;
        }).attr("height", function (d) {
            return d.height;
        });
        images.attr("x", function (d) {
            return -(d.bbox.width) / 2;
        });
        labels.attr("x", function (d) {
            return -d.bbox.width / 2;
        }).attr("y", function (d) {
            return -d.bbox.height / 2;
        });
        counters.attr("x", function (d) {
            var w = d.bbox.width;
            return w / 2;
        });
        dagre.layout().nodeSep(50).edgeSep(10).rankSep(50).nodes(states).edges(transitions).debugLevel(1).run();
        nodes.attr("transform", function (d) {
            return 'translate(' + d.dagre.x + ',' + d.dagre.y + ')';
        });
        edges.attr('id', function (e) {
            return e.dagre.id;
        }).attr("d", function (e) {
            return spline(e);
        });
        var svgNode = svg.node();
        if (svgNode) {
            var svgBBox = svgNode.getBBox();
            if (svgBBox) {
                svg.attr("width", svgBBox.width + 10);
                svg.attr("height", svgBBox.height + 10);
            }
        }
        var nodeDrag = d3.behavior.drag().origin(function (d) {
            return d.pos ? {
                x: d.pos.x,
                y: d.pos.y
            } : {
                x: d.dagre.x,
                y: d.dagre.y
            };
        }).on('drag', function (d, i) {
            var prevX = d.dagre.x, prevY = d.dagre.y;
            d.dagre.x = Math.max(d.width / 2, Math.min(svgBBox.width - d.width / 2, d3.event.x));
            d.dagre.y = Math.max(d.height / 2, Math.min(svgBBox.height - d.height / 2, d3.event.y));
            d3.select(this).attr('transform', 'translate(' + d.dagre.x + ',' + d.dagre.y + ')');
            var dx = d.dagre.x - prevX, dy = d.dagre.y - prevY;
            d.edges.forEach(function (e) {
                translateEdge(e, dx, dy);
                d3.select('#' + e.dagre.id).attr('d', spline(e));
            });
        });
        var edgeDrag = d3.behavior.drag().on('drag', function (d, i) {
            translateEdge(d, d3.event.dx, d3.event.dy);
            d3.select(this).attr('d', spline(d));
        });
        nodes.call(nodeDrag);
        edges.call(edgeDrag);
        return states;
    }
    Core.dagreLayoutGraph = dagreLayoutGraph;
    function dagreUpdateGraphData(data) {
        var svg = d3.select("svg");
        svg.selectAll("text.counter").text(_counterFunction);
        svg.selectAll("g .node title").text(function (d) {
            return d.tooltip || "";
        });
    }
    Core.dagreUpdateGraphData = dagreUpdateGraphData;
    function _counterFunction(d) {
        return d.counter || "";
    }
})(Core || (Core = {}));
var Core;
(function (Core) {
    var GridStyle = (function () {
        function GridStyle($window) {
            this.$window = $window;
            var _this = this;
            this.restrict = 'C';
            this.link = function (scope, element, attrs) {
                return _this.doLink(scope, element, attrs);
            };
        }
        GridStyle.prototype.doLink = function (scope, element, attrs) {
            var lastHeight = 0;
            var resizeFunc = angular.bind(this, function (scope) {
                var top = element.position().top;
                var windowHeight = $(this.$window).height();
                var height = windowHeight - top - 15;
                var heightStr = height + 'px';
                element.css({
                    'min-height': heightStr,
                    'height': heightStr
                });
                if (lastHeight !== height) {
                    lastHeight = height;
                    element.trigger('resize');
                }
            });
            resizeFunc();
            scope.$watch(resizeFunc);
            $(this.$window).resize(function () {
                resizeFunc();
                Core.$apply(scope);
                return false;
            });
        };
        return GridStyle;
    })();
    Core.GridStyle = GridStyle;    
})(Core || (Core = {}));
var Core;
(function (Core) {
    function HelpController($scope, $routeParams, marked, helpRegistry, branding) {
        $scope.branding = branding;
        $scope.topics = helpRegistry.getTopics();
        if ('topic' in $routeParams) {
            $scope.topic = $routeParams['topic'];
        } else {
            $scope.topic = 'index';
        }
        if ('subtopic' in $routeParams) {
            $scope.subTopic = $routeParams['subtopic'];
        } else {
            $scope.subTopic = Object.extended($scope.topics[$scope.topic]).keys().first();
        }
        Core.log.debug("topic: ", $scope.topic, " subtopic: ", $scope.subTopic);
        var isIndex = $scope.topic === "index";
        var filterSubTopic = $scope.subTopic;
        if (isIndex && filterSubTopic !== "developer") {
            filterSubTopic = "user";
        }
        $scope.breadcrumbs = [
            {
                topic: "index",
                subTopic: "user",
                label: "User Guide"
            }, 
            {
                topic: "index",
                subTopic: "faq",
                label: "FAQ"
            }, 
            {
                topic: "index",
                subTopic: "changes",
                label: "Changes"
            }, 
            {
                topic: "index",
                subTopic: "developer",
                label: "Developers"
            }
        ];
        var activeBreadcrumb = $scope.breadcrumbs.find(function (b) {
            return b.topic === $scope.topic && b.subTopic === $scope.subTopic;
        });
        if (activeBreadcrumb) {
            activeBreadcrumb.active = true;
        }
        $scope.sections = [];
        angular.forEach($scope.topics, function (details, topic) {
            if (topic !== "index" && details[filterSubTopic]) {
                $scope.sections.push({
                    topic: topic,
                    subTopic: filterSubTopic,
                    label: helpRegistry.mapTopicName(topic),
                    active: topic === $scope.topic
                });
            }
        });
        $scope.sections = $scope.sections.sortBy("label");
        $scope.$on('hawtioNewHelpTopic', function () {
            $scope.topics = helpRegistry.getTopics();
        });
        $scope.$watch('topics', function (newValue, oldValue) {
            Core.log.debug("Topics: ", $scope.topics);
        });
        if (!angular.isDefined($scope.topics[$scope.topic])) {
            $scope.html = "Unable to download help data for " + $scope.topic;
        } else {
            $.ajax({
                url: $scope.topics[$scope.topic][$scope.subTopic],
                dataType: 'html',
                cache: false,
                success: function (data, textStatus, jqXHR) {
                    $scope.html = "Unable to download help data for " + $scope.topic;
                    if (angular.isDefined(data)) {
                        $scope.html = marked(data);
                    }
                    Core.$apply($scope);
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    $scope.html = "Unable to download help data for " + $scope.topic;
                    Core.$apply($scope);
                }
            });
        }
    }
    Core.HelpController = HelpController;
})(Core || (Core = {}));
var Core;
(function (Core) {
    var HelpRegistry = (function () {
        function HelpRegistry($rootScope) {
            this.$rootScope = $rootScope;
            this.discoverableDocTypes = {
                user: 'help.md'
            };
            this.topicNameMappings = {
                activemq: 'ActiveMQ',
                camel: 'Camel',
                jboss: 'JBoss',
                jclouds: 'jclouds',
                jmx: 'JMX',
                jvm: 'JVM',
                log: 'Logs',
                openejb: 'OpenEJB'
            };
            this.subTopicNameMappings = {
                user: 'For Users',
                developer: 'For Developers',
                faq: 'FAQ'
            };
            this.pluginNameMappings = {
                hawtioCore: 'core',
                'hawtio-branding': 'branding',
                forceGraph: 'forcegraph',
                'hawtio-ui': 'ui',
                'hawtio-forms': 'forms',
                elasticjs: 'elasticsearch'
            };
            this.ignoredPlugins = [
                'core', 
                'branding', 
                'datatable', 
                'forcegraph', 
                'forms', 
                'perspective', 
                'tree', 
                'ui'
            ];
            this.topics = {};
        }
        HelpRegistry.prototype.addUserDoc = function (topic, path, isValid) {
            if (typeof isValid === "undefined") { isValid = null; }
            this.addSubTopic(topic, 'user', path, isValid);
        };
        HelpRegistry.prototype.addDevDoc = function (topic, path, isValid) {
            if (typeof isValid === "undefined") { isValid = null; }
            this.addSubTopic(topic, 'developer', path, isValid);
        };
        HelpRegistry.prototype.addSubTopic = function (topic, subtopic, path, isValid) {
            if (typeof isValid === "undefined") { isValid = null; }
            this.getOrCreateTopic(topic, isValid)[subtopic] = path;
        };
        HelpRegistry.prototype.getOrCreateTopic = function (topic, isValid) {
            if (typeof isValid === "undefined") { isValid = null; }
            if (!angular.isDefined(this.topics[topic])) {
                if (isValid === null) {
                    isValid = function () {
                        return true;
                    };
                }
                this.topics[topic] = {
                    isValid: isValid
                };
                this.$rootScope.$broadcast('hawtioNewHelpTopic');
            }
            return this.topics[topic];
        };
        HelpRegistry.prototype.mapTopicName = function (name) {
            if (angular.isDefined(this.topicNameMappings[name])) {
                return this.topicNameMappings[name];
            }
            return name.capitalize();
        };
        HelpRegistry.prototype.mapSubTopicName = function (name) {
            if (angular.isDefined(this.subTopicNameMappings[name])) {
                return this.subTopicNameMappings[name];
            }
            return name.capitalize();
        };
        HelpRegistry.prototype.getTopics = function () {
            var answer = {};
            angular.forEach(this.topics, function (value, key) {
                if (value.isValid()) {
                    Core.log.debug(key, " is available");
                    answer[key] = angular.fromJson(angular.toJson(value));
                } else {
                    Core.log.debug(key, " is not available");
                }
            });
            return answer;
        };
        HelpRegistry.prototype.disableAutodiscover = function (name) {
            this.ignoredPlugins.push(name);
        };
        HelpRegistry.prototype.discoverHelpFiles = function (plugins) {
            var self = this;
            console.log("Ignored plugins: ", self.ignoredPlugins);
            plugins.forEach(function (plugin) {
                var pluginName = self.pluginNameMappings[plugin];
                if (!angular.isDefined(pluginName)) {
                    pluginName = plugin;
                }
                if (!self.ignoredPlugins.any(function (p) {
                    return p === pluginName;
                })) {
                    angular.forEach(self.discoverableDocTypes, function (value, key) {
                        if (!angular.isDefined(self[pluginName]) || !angular.isDefined(self[pluginName][key])) {
                            var target = 'app/' + pluginName + '/doc/' + value;
                            console.log("checking: ", target);
                            $.ajax(target, {
                                type: 'HEAD',
                                statusCode: {
                                    200: function () {
                                        self.getOrCreateTopic(plugin)[key] = target;
                                    }
                                }
                            });
                        }
                    });
                }
            });
        };
        return HelpRegistry;
    })();
    Core.HelpRegistry = HelpRegistry;    
})(Core || (Core = {}));
var Core;
(function (Core) {
    Core.username = null;
    Core.password = null;
    function LoginController($scope, jolokia, userDetails, jolokiaUrl, workspace, localStorage, branding) {
        jolokia.stop();
        $scope.entity = {
            username: '',
            password: ''
        };
        $scope.backstretch = ($).backstretch(branding.loginBg);
        $scope.rememberMe = false;
        $scope.branding = branding;
        var details = angular.fromJson(localStorage[jolokiaUrl]);
        if (details) {
            $scope.entity.username = details['username'];
            $scope.entity.password = details['password'];
            $scope.rememberMe = details['rememberMe'];
        }
        $scope.$on('$routeChangeStart', function () {
            if ($scope.backstretch) {
                $scope.backstretch.destroy();
            }
        });
        $scope.doLogin = function () {
            var url = jolokiaUrl.replace("jolokia", "auth/login/");
            $.ajax(url, {
                type: "POST",
                success: function (response) {
                    userDetails.username = $scope.entity.username;
                    userDetails.password = $scope.entity.password;
                    userDetails.rememberMe = $scope.rememberMe;
                    userDetails.loginDetails = response;
                    Core.username = $scope.entity.username;
                    Core.password = $scope.entity.password;
                    if ($scope.rememberMe) {
                        localStorage[jolokiaUrl] = angular.toJson(userDetails);
                    } else {
                        delete localStorage[jolokiaUrl];
                    }
                    jolokia.start();
                    workspace.loadTree();
                    Core.$apply($scope);
                },
                error: function (xhr, textStatus, error) {
                    switch(xhr.status) {
                        case 401:
                            notification('error', 'Failed to log in, ' + error);
                            break;
                        case 403:
                            notification('error', 'Failed to log in, ' + error);
                            break;
                        default:
                            notification('error', 'Failed to log in, ' + error);
                            break;
                    }
                    Core.$apply($scope);
                },
                beforeSend: function (xhr) {
                    xhr.setRequestHeader('Authorization', Core.getBasicAuthHeader($scope.entity.username, $scope.entity.password));
                }
            });
        };
    }
    Core.LoginController = LoginController;
})(Core || (Core = {}));
var Core;
(function (Core) {
    function NavBarController($scope, $location, workspace, $route, jolokia, localStorage) {
        $scope.hash = workspace.hash();
        $scope.topLevelTabs = [];
        $scope.subLevelTabs = workspace.subLevelTabs;
        $scope.currentPerspective = null;
        $scope.perspectiveDetails = {
            perspective: null
        };
        $scope.topLevelTabs = function () {
            reloadPerspective();
            return workspace.topLevelTabs;
        };
        $scope.$on('jmxTreeUpdated', function () {
            reloadPerspective();
        });
        $scope.validSelection = function (uri) {
            return workspace.validSelection(uri);
        };
        $scope.isValid = function (nav) {
            return nav && nav.isValid(workspace);
        };
        $scope.switchPerspective = function (perspective) {
            var searchPerspectiveId = $location.search()[Perspective.perspectiveSearchId];
            if (perspective && ($scope.currentPerspective !== perspective || perspective.id !== searchPerspectiveId)) {
                Logger.debug("Changed the perspective to " + JSON.stringify(perspective) + " from search id " + searchPerspectiveId);
                if ($scope.currentPerspective) {
                    $scope.currentPerspective.lastPage = $location.url();
                }
                var pid = perspective.id;
                $location.search(Perspective.perspectiveSearchId, pid);
                Logger.debug("Setting perspective to " + pid);
                $scope.currentPerspective = perspective;
                reloadPerspective();
                $scope.topLevelTabs = Perspective.topLevelTabs($location, workspace, jolokia, localStorage);
                if (perspective.lastPage) {
                    var path = Core.trimLeading(perspective.lastPage, "#");
                    var idx = path.indexOf("?p=") || path.indexOf("&p=");
                    if (idx > 0) {
                        path = path.substring(0, idx);
                    }
                    var sep = (path.indexOf("?") >= 0) ? "&" : "?";
                    path += sep + "p=" + pid;
                    $location.url(path);
                }
            }
        };
        $scope.$watch('hash', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                Core.log.debug("hash changed from ", oldValue, " to ", newValue);
            }
        });
        $scope.$on('$routeChangeSuccess', function () {
            $scope.hash = workspace.hash();
            reloadPerspective();
        });
        $scope.link = function (nav) {
            var href;
            if (angular.isString(nav)) {
                href = nav;
            } else {
                href = nav.href();
            }
            var removeParams = [
                'tab', 
                'nid'
            ];
            if (href.indexOf("?p=") >= 0 || href.indexOf("&p=") >= 0) {
                removeParams.push("p");
            }
            return Core.createHref($location, href, removeParams);
        };
        $scope.fullScreenLink = function () {
            var href = "#" + $location.path() + "?tab=notree";
            return Core.createHref($location, href, [
                'tab'
            ]);
        };
        $scope.addToDashboardLink = function () {
            var href = "#" + $location.path() + workspace.hash();
            var answer = "#/dashboard/add?tab=dashboard&href=" + encodeURIComponent(href);
            if ($location.url().has("/jmx/charts")) {
                var size = {
                    size_x: 4,
                    size_y: 3
                };
                answer += "&size=" + encodeURIComponent(angular.toJson(size));
            }
            return answer;
        };
        $scope.isActive = function (nav) {
            if (angular.isString(nav)) {
                return workspace.isLinkActive(nav);
            }
            var fn = nav.isActive;
            if (fn) {
                return fn(workspace);
            }
            return workspace.isLinkActive(nav.href());
        };
        $scope.isTopTabActive = function (nav) {
            if (angular.isString(nav)) {
                return workspace.isTopTabActive(nav);
            }
            var fn = nav.isActive;
            if (fn) {
                return fn(workspace);
            }
            return workspace.isTopTabActive(nav.href());
        };
        $scope.activeLink = function () {
            var tabs = $scope.topLevelTabs();
            if (!tabs) {
                return "Loading...";
            }
            var tab = tabs.find(function (nav) {
                return $scope.isActive(nav);
            });
            return tab ? tab['content'] : "";
        };
        function reloadPerspective() {
            var perspectives = Perspective.getPerspectives($location, workspace, jolokia, localStorage);
            var currentId = Perspective.currentPerspectiveId($location, workspace, jolokia, localStorage);
            console.log("reloading perspectives for " + currentId);
            if (currentId != $scope.perspectiveId || angular.toJson($scope.perspectives) !== angular.toJson(perspectives)) {
                $scope.perspectiveId = currentId;
                $scope.perspectives = perspectives;
                $scope.perspectiveDetails.perspective = $scope.perspectives.find(function (p) {
                    return p['id'] === currentId;
                });
                console.log("Current perspective ID: " + currentId);
                $scope.topLevelTabs = Perspective.topLevelTabs($location, workspace, jolokia, localStorage);
            }
        }
    }
    Core.NavBarController = NavBarController;
})(Core || (Core = {}));
var Core;
(function (Core) {
    function PreferencesController($scope, localStorage, userDetails, jolokiaUrl, branding) {
        $scope.branding = branding;
        if (!angular.isDefined(localStorage['logLevel'])) {
            localStorage['logLevel'] = '{"value": 2, "name": "INFO"}';
        }
        $scope.localStorage = localStorage;
        $scope.logBuffer = 0;
        if ('logBuffer' in localStorage) {
            $scope.logBuffer = parseInt(localStorage['logBuffer']);
        }
        $scope.$watch('localStorage.logLevel', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                var level = JSON.parse(newValue);
                Logger.setLevel(level);
            }
        });
        $scope.$watch('logBuffer', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                localStorage['logBuffer'] = newValue;
                window['LogBuffer'] = newValue;
            }
        });
        $scope.updateRate = localStorage['updateRate'];
        $scope.url = localStorage['url'];
        $scope.autoRefresh = localStorage['autoRefresh'] === "true";
        $scope.hosts = [];
        $scope.newHost = {};
        $scope.addRegexDialog = false;
        $scope.hostSchema = {
            properties: {
                'name': {
                    description: 'Indicator name',
                    type: 'string'
                },
                'regex': {
                    description: 'Indicator regex',
                    type: 'string'
                }
            }
        };
        $scope.delete = function (index) {
            $scope.hosts.removeAt(index);
        };
        $scope.moveUp = function (index) {
            var tmp = $scope.hosts[index];
            $scope.hosts[index] = $scope.hosts[index - 1];
            $scope.hosts[index - 1] = tmp;
        };
        $scope.moveDown = function (index) {
            var tmp = $scope.hosts[index];
            $scope.hosts[index] = $scope.hosts[index + 1];
            $scope.hosts[index + 1] = tmp;
        };
        $scope.onOk = function () {
            $scope.newHost['color'] = UI.colors.sample();
            if (!angular.isArray($scope.hosts)) {
                $scope.hosts = [
                    Object.clone($scope.newHost)
                ];
            } else {
                $scope.hosts.push(Object.clone($scope.newHost));
            }
            $scope.newHost = {};
        };
        function parsePerferencesJson(value, key) {
            var answer = null;
            if (angular.isDefined(value)) {
                answer = Core.parseJsonText(value, "localStorage for " + key);
            }
            return answer;
        }
        $scope.$watch('hosts', function (oldValue, newValue) {
            if (!Object.equal(oldValue, newValue)) {
                if (angular.isDefined($scope.hosts)) {
                    localStorage['regexs'] = angular.toJson($scope.hosts);
                } else {
                    delete localStorage['regexs'];
                }
            } else {
                $scope.hosts = parsePerferencesJson(localStorage['regexs'], "hosts") || {};
            }
        }, true);
        var defaults = {
            logCacheSize: 1000,
            fabricAlwaysPrompt: false,
            fabricEnableMaps: true,
            camelIgnoreIdForLabel: false,
            camelMaximumLabelWidth: Camel.defaultMaximumLabelWidth,
            camelMaximumTraceOrDebugBodyLength: Camel.defaultCamelMaximumTraceOrDebugBodyLength
        };
        var converters = {
            logCacheSize: parseInt,
            fabricAlwaysPrompt: Core.parseBooleanValue,
            fabricEnableMaps: Core.parseBooleanValue,
            camelIgnoreIdForLabel: Core.parseBooleanValue,
            camelMaximumLabelWidth: parseInt,
            camelMaximumTraceOrDebugBodyLength: parseInt
        };
        $scope.$watch('updateRate', function () {
            localStorage['updateRate'] = $scope.updateRate;
            $scope.$emit('UpdateRate', $scope.updateRate);
        });
        $scope.$watch('autoRefresh', function (newValue, oldValue) {
            if (newValue === oldValue) {
                return;
            }
            localStorage['autoRefresh'] = $scope.autoRefresh;
        });
        var names = [
            "gitUserName", 
            "gitUserEmail", 
            "activemqUserName", 
            "activemqPassword", 
            "logCacheSize", 
            "fabricAlwaysPrompt", 
            "fabricEnableMaps", 
            "camelIgnoreIdForLabel", 
            "camelMaximumLabelWidth", 
            "camelMaximumTraceOrDebugBodyLength"
        ];
        angular.forEach(names, function (name) {
            if (angular.isDefined(localStorage[name])) {
                $scope[name] = localStorage[name];
                var converter = converters[name];
                if (converter) {
                    $scope[name] = converter($scope[name]);
                }
            } else {
                $scope[name] = defaults[name] || "";
            }
            $scope.$watch(name, function () {
                var value = $scope[name];
                if (angular.isDefined(value)) {
                    var actualValue = value;
                    var converter = converters[name];
                    if (converter) {
                        actualValue = converter(value);
                    }
                    localStorage[name] = actualValue;
                }
            });
        });
        console.log("logCacheSize " + $scope.logCacheSize);
        $scope.doReset = function () {
            var doReset = function () {
                localStorage.clear();
                setTimeout(function () {
                    window.location.reload();
                }, 10);
            };
            if (Core.isBlank(userDetails.username) && Core.isBlank(userDetails.password)) {
                doReset();
            } else {
                Core.logout(jolokiaUrl, userDetails, localStorage, $scope, doReset);
            }
        };
    }
    Core.PreferencesController = PreferencesController;
})(Core || (Core = {}));
var Core;
(function (Core) {
    var TableWidget = (function () {
        function TableWidget(scope, workspace, dataTableColumns, config) {
            if (typeof config === "undefined") { config = {}; }
            this.scope = scope;
            this.workspace = workspace;
            this.dataTableColumns = dataTableColumns;
            this.config = config;
            var _this = this;
            this.ignoreColumnHash = {};
            this.flattenColumnHash = {};
            this.detailTemplate = null;
            this.openMessages = [];
            this.addedExpandNodes = false;
            this.tableElement = null;
            this.sortColumns = null;
            this.dataTableConfig = {
                bPaginate: false,
                sDom: 'Rlfrtip',
                bDestroy: true,
                bAutoWidth: true
            };
            this.dataTable = null;
            angular.forEach(config.ignoreColumns, function (name) {
                _this.ignoreColumnHash[name] = true;
            });
            angular.forEach(config.flattenColumns, function (name) {
                _this.flattenColumnHash[name] = true;
            });
            var templateId = config.rowDetailTemplateId;
            if (templateId) {
                this.detailTemplate = workspace.$templateCache.get(templateId);
            }
        }
        TableWidget.prototype.addData = function (newData) {
            var dataTable = this.dataTable;
            dataTable.fnAddData(newData);
        };
        TableWidget.prototype.populateTable = function (data) {
            var _this = this;
            var $scope = this.scope;
            if (!data) {
                $scope.messages = [];
            } else {
                $scope.messages = data;
                var formatMessageDetails = function (dataTable, parentRow) {
                    var oData = dataTable.fnGetData(parentRow);
                    var div = $('<div>');
                    div.addClass('innerDetails');
                    _this.populateDetailDiv(oData, div);
                    return div;
                };
                var array = data;
                if (angular.isArray(data)) {
                } else if (angular.isObject(data)) {
                    array = [];
                    angular.forEach(data, function (object) {
                        return array.push(object);
                    });
                }
                var tableElement = this.tableElement;
                if (!tableElement) {
                    tableElement = $('#grid');
                }
                var tableTr = Core.getOrCreateElements(tableElement, [
                    "thead", 
                    "tr"
                ]);
                var tableBody = Core.getOrCreateElements(tableElement, [
                    "tbody"
                ]);
                var ths = $(tableTr).find("th");
                var columns = [];
                angular.forEach(this.dataTableColumns, function (value) {
                    return columns.push(value);
                });
                var addColumn = function (key, title) {
                    columns.push({
                        "sDefaultContent": "",
                        "mData": null,
                        mDataProp: key
                    });
                    if (tableTr) {
                        $("<th>" + title + "</th>").appendTo(tableTr);
                    }
                };
                var checkForNewColumn = function (value, key, prefix) {
                    var found = _this.ignoreColumnHash[key] || columns.any(function (k, v) {
                        return "mDataProp" === k && v === key;
                    });
                    if (!found) {
                        if (_this.flattenColumnHash[key]) {
                            if (angular.isObject(value)) {
                                var childPrefix = prefix + key + ".";
                                angular.forEach(value, function (value, key) {
                                    return checkForNewColumn(value, key, childPrefix);
                                });
                            }
                        } else {
                            addColumn(prefix + key, humanizeValue(key));
                        }
                    }
                };
                if (!this.config.disableAddColumns && angular.isArray(array) && array.length > 0) {
                    var first = array[0];
                    if (angular.isObject(first)) {
                        angular.forEach(first, function (value, key) {
                            return checkForNewColumn(value, key, "");
                        });
                    }
                }
                if (columns.length > 1) {
                    var col0 = columns[0];
                    if (!this.sortColumns && !col0["mDataProp"] && !col0["mData"]) {
                        var sortOrder = [
                            [
                                1, 
                                "asc"
                            ]
                        ];
                        this.sortColumns = sortOrder;
                    }
                }
                if (array.length && !angular.isArray(array[0])) {
                    this.dataTableConfig["aaData"] = array;
                } else {
                    this.dataTableConfig["aaData"] = array;
                }
                this.dataTableConfig["aoColumns"] = columns;
                if (this.sortColumns) {
                    this.dataTableConfig["aaSorting"] = this.sortColumns;
                }
                if (this.dataTable) {
                    this.dataTable.fnClearTable(false);
                    this.dataTable.fnAddData(array);
                    this.dataTable.fnDraw();
                } else {
                    this.dataTable = tableElement.dataTable(this.dataTableConfig);
                }
                var widget = this;
                if (this.dataTable) {
                    var keys = new KeyTable({
                        "table": tableElement[0],
                        "datatable": this.dataTable
                    });
                    keys.fnSetPosition(0, 0);
                    if (angular.isArray(data) && data.length) {
                        var selected = data[0];
                        var selectHandler = widget.config.selectHandler;
                        if (selected && selectHandler) {
                            selectHandler(selected);
                        }
                    }
                }
                $(tableElement).focus();
                var widget = this;
                var expandCollapseNode = function () {
                    var dataTable = widget.dataTable;
                    var parentRow = this.parentNode;
                    var openMessages = widget.openMessages;
                    var i = $.inArray(parentRow, openMessages);
                    var element = $('i', this);
                    if (i === -1) {
                        element.removeClass('icon-plus');
                        element.addClass('icon-minus');
                        var dataDiv = formatMessageDetails(dataTable, parentRow);
                        var detailsRow = $(dataTable.fnOpen(parentRow, dataDiv, 'details'));
                        detailsRow.css("padding", "0");
                        setTimeout(function () {
                            detailsRow.find(".innerDetails").slideDown(400, function () {
                                $(parentRow).addClass('opened');
                                openMessages.push(parentRow);
                            });
                        }, 20);
                    } else {
                        $(parentRow.nextSibling).find(".innerDetails").slideUp(400, function () {
                            $(parentRow).removeClass('opened');
                            element.removeClass('icon-minus');
                            element.addClass('icon-plus');
                            dataTable.fnClose(parentRow);
                            openMessages.splice(i, 1);
                        });
                    }
                    Core.$apply($scope);
                };
                if (!this.addedExpandNodes) {
                    this.addedExpandNodes = true;
                    $(tableElement).on("click", "td.control", expandCollapseNode);
                    keys.event.action(0, null, function (node) {
                        expandCollapseNode.call(node);
                    });
                }
                keys.event.focus(null, null, function (node) {
                    var dataTable = widget.dataTable;
                    var row = node;
                    if (node) {
                        var nodeName = node.nodeName;
                        if (nodeName) {
                            if (nodeName.toLowerCase() === "td") {
                                row = $(node).parents("tr")[0];
                            }
                            var selected = dataTable.fnGetData(row);
                            var selectHandler = widget.config.selectHandler;
                            if (selected && selectHandler) {
                                selectHandler(selected);
                            }
                        }
                    }
                });
                $(tableElement).on("click", "td.control", function () {
                    var dataTable = widget.dataTable;
                    if ($(this).hasClass('selected')) {
                        $(this).removeClass('focus selected');
                    } else {
                        if (!widget.config.multiSelect) {
                            dataTable.$('td.selected').removeClass('focus selected');
                        }
                        $(this).addClass('focus selected');
                        var row = $(this).parents("tr")[0];
                        var selected = dataTable.fnGetData(row);
                        var selectHandler = widget.config.selectHandler;
                        if (selected && selectHandler) {
                            selectHandler(selected);
                        }
                    }
                });
            }
            Core.$apply($scope);
        };
        TableWidget.prototype.populateDetailDiv = function (row, div) {
            delete row["0"];
            var scope = this.scope.$new();
            scope.row = row;
            scope.templateDiv = div;
            var template = this.detailTemplate;
            if (!template) {
                var templateId = this.config.rowDetailTemplateId;
                if (templateId) {
                    this.detailTemplate = this.workspace.$templateCache.get(templateId);
                    template = this.detailTemplate;
                }
            }
            if (template) {
                div.html(template);
                this.workspace.$compile(div.contents())(scope);
            }
        };
        return TableWidget;
    })();
    Core.TableWidget = TableWidget;    
})(Core || (Core = {}));
var TableWidget = (function (_super) {
    __extends(TableWidget, _super);
    function TableWidget() {
        _super.apply(this, arguments);

    }
    return TableWidget;
})(Core.TableWidget);
;
;
;
var Core;
(function (Core) {
    function ViewController($scope, $route, $location, layoutTree, layoutFull, viewRegistry) {
        findViewPartial();
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            findViewPartial();
        });
        function searchRegistry(path) {
            var answer = undefined;
            Object.extended(viewRegistry).keys(function (key, value) {
                if (!answer) {
                    if (key.startsWith("/") && key.endsWith("/")) {
                        var text = key.substring(1, key.length - 1);
                        try  {
                            var reg = new RegExp(text, "");
                            if (reg.exec(path)) {
                                answer = value;
                            }
                        } catch (e) {
                            console.log("Invalid RegExp " + text + " for viewRegistry value: " + value);
                        }
                    } else {
                        if (path.startsWith(key)) {
                            answer = value;
                        }
                    }
                }
            });
            return answer;
        }
        function findViewPartial() {
            var answer = null;
            var hash = $location.search();
            var tab = hash['tab'];
            if (angular.isString(tab)) {
                answer = searchRegistry(tab);
            }
            if (!answer) {
                var path = $location.path();
                if (path) {
                    if (path.startsWith("/")) {
                        path = path.substring(1);
                    }
                    answer = searchRegistry(path);
                }
            }
            if (!answer) {
                answer = layoutTree;
            }
            $scope.viewPartial = answer;
            console.log("Using view partial: " + answer);
            return answer;
        }
    }
    Core.ViewController = ViewController;
})(Core || (Core = {}));
var Core;
(function (Core) {
    var Workspace = (function () {
        function Workspace(jolokia, jolokiaStatus, jmxTreeLazyLoadRegistry, $location, $compile, $templateCache, localStorage, $rootScope) {
            this.jolokia = jolokia;
            this.jolokiaStatus = jolokiaStatus;
            this.jmxTreeLazyLoadRegistry = jmxTreeLazyLoadRegistry;
            this.$location = $location;
            this.$compile = $compile;
            this.$templateCache = $templateCache;
            this.localStorage = localStorage;
            this.$rootScope = $rootScope;
            this.operationCounter = 0;
            this.tree = new Core.Folder('MBeans');
            this.treeResponse = {};
            this.mbeanTypesToDomain = {};
            this.mbeanServicesToDomain = {};
            this.attributeColumnDefs = {};
            this.treePostProcessors = [];
            this.topLevelTabs = [];
            this.subLevelTabs = [];
            this.keyToNodeMap = {};
            this.pluginRegisterHandle = null;
            this.pluginUpdateCounter = null;
            this.treeWatchRegisterHandle = null;
            this.treeWatcherCounter = null;
            this.treeElement = null;
            if (!('autoRefresh' in localStorage)) {
                localStorage['autoRefresh'] = true;
            }
            if (!('updateRate' in localStorage)) {
                localStorage['updateRate'] = 5000;
            }
        }
        Workspace.prototype.createChildWorkspace = function (location) {
            var child = new Workspace(this.jolokia, this.jolokiaStatus, this.jmxTreeLazyLoadRegistry, this.$location, this.$compile, this.$templateCache, this.localStorage, this.$rootScope);
            angular.forEach(this, function (value, key) {
                return child[key] = value;
            });
            child.$location = location;
            return child;
        };
        Workspace.prototype.getLocalStorage = function (key) {
            return this.localStorage[key];
        };
        Workspace.prototype.setLocalStorage = function (key, value) {
            this.localStorage[key] = value;
        };
        Workspace.prototype.loadTree = function () {
            var flags = {
                ignoreErrors: true,
                maxDepth: 2
            };
            var data = this.jolokia.list(null, onSuccess(null, flags));
            if (data) {
                this.jolokiaStatus.xhr = null;
            }
            this.populateTree({
                value: data
            });
        };
        Workspace.prototype.addTreePostProcessor = function (processor) {
            this.treePostProcessors.push(processor);
            var tree = this.tree;
            if (tree) {
                processor(tree);
            }
        };
        Workspace.prototype.maybeMonitorPlugins = function () {
            if (this.treeContainsDomainAndProperties("hawtio", {
                type: "registry"
            })) {
                if (this.pluginRegisterHandle === null) {
                    this.pluginRegisterHandle = this.jolokia.register(angular.bind(this, this.maybeUpdatePlugins), {
                        type: "read",
                        mbean: "hawtio:type=registry",
                        attribute: "UpdateCounter"
                    });
                }
            } else {
                if (this.pluginRegisterHandle !== null) {
                    this.jolokia.unregister(this.pluginRegisterHandle);
                    this.pluginRegisterHandle = null;
                    this.pluginUpdateCounter = null;
                }
            }
            if (this.treeContainsDomainAndProperties("hawtio", {
                type: "TreeWatcher"
            })) {
                if (this.treeWatchRegisterHandle === null) {
                    this.treeWatchRegisterHandle = this.jolokia.register(angular.bind(this, this.maybeReloadTree), {
                        type: "read",
                        mbean: "hawtio:type=TreeWatcher",
                        attribute: "Counter"
                    });
                } else {
                }
            }
        };
        Workspace.prototype.maybeUpdatePlugins = function (response) {
            if (this.pluginUpdateCounter === null) {
                this.pluginUpdateCounter = response.value;
                return;
            }
            if (this.pluginUpdateCounter !== response.value) {
                if (Core.parseBooleanValue(localStorage['autoRefresh'])) {
                    window.location.reload();
                }
            }
        };
        Workspace.prototype.maybeReloadTree = function (response) {
            var counter = response.value;
            if (this.treeWatcherCounter === null) {
                this.treeWatcherCounter = counter;
                return;
            }
            if (this.treeWatcherCounter !== counter) {
                this.treeWatcherCounter = counter;
                var workspace = this;
                function wrapInValue(response) {
                    var wrapper = {
                        value: response
                    };
                    workspace.populateTree(wrapper);
                }
                this.jolokia.list(null, onSuccess(wrapInValue, {
                    ignoreErrors: true,
                    maxDepth: 2
                }));
            }
        };
        Workspace.prototype.folderGetOrElse = function (folder, value) {
            if (folder) {
                try  {
                    return folder.getOrElse(value);
                } catch (e) {
                    Core.log.warn("Failed to find value " + value + " on folder " + folder);
                }
            }
            return null;
        };
        Workspace.prototype.populateTree = function (response) {
            if (!Object.equal(this.treeResponse, response.value)) {
                this.treeResponse = response.value;
                Core.log.debug("JMX tree has been loaded!");
                var rootId = 'root';
                var separator = '-';
                this.mbeanTypesToDomain = {};
                this.mbeanServicesToDomain = {};
                this.keyToNodeMap = {};
                var tree = new Core.Folder('MBeans');
                tree.key = rootId;
                var domains = response.value;
                for(var domain in domains) {
                    var domainClass = escapeDots(domain);
                    var mbeans = domains[domain];
                    for(var path in mbeans) {
                        var entries = {};
                        var folder = this.folderGetOrElse(tree, domain);
                        folder.domain = domain;
                        if (!folder.key) {
                            folder.key = rootId + separator + domain;
                        }
                        var folderNames = [
                            domain
                        ];
                        folder.folderNames = folderNames;
                        folderNames = folderNames.clone();
                        var items = path.split(',');
                        var paths = [];
                        var typeName = null;
                        var serviceName = null;
                        items.forEach(function (item) {
                            var kv = item.split('=');
                            var key = kv[0];
                            var value = kv[1] || key;
                            entries[key] = value;
                            var moveToFront = false;
                            var lowerKey = key.toLowerCase();
                            if (lowerKey === "type") {
                                typeName = value;
                                if (folder.map[value]) {
                                    moveToFront = true;
                                }
                            }
                            if (lowerKey === "service") {
                                serviceName = value;
                            }
                            if (moveToFront) {
                                paths.splice(0, 0, value);
                            } else {
                                paths.push(value);
                            }
                        });
                        var configureFolder = function (folder, name) {
                            folder.domain = domain;
                            if (!folder.key) {
                                folder.key = rootId + separator + folderNames.join(separator);
                            }
                            this.keyToNodeMap[folder.key] = folder;
                            folder.folderNames = folderNames.clone();
                            var classes = "";
                            var entries = folder.entries;
                            var entryKeys = Object.keys(entries).filter(function (n) {
                                return n.toLowerCase().indexOf("type") >= 0;
                            });
                            if (entryKeys.length) {
                                angular.forEach(entryKeys, function (entryKey) {
                                    var entryValue = entries[entryKey];
                                    if (!folder.ancestorHasEntry(entryKey, entryValue)) {
                                        classes += " " + domainClass + separator + entryValue;
                                    }
                                });
                            } else {
                                var kindName = folderNames.last();
                                if (kindName === name) {
                                    kindName += "-folder";
                                }
                                if (kindName) {
                                    classes += " " + domainClass + separator + kindName;
                                }
                            }
                            folder.addClass = escapeTreeCssStyles(classes);
                            return folder;
                        };
                        var lastPath = paths.pop();
                        var ws = this;
                        paths.forEach(function (value) {
                            folder = ws.folderGetOrElse(folder, value);
                            if (folder) {
                                folderNames.push(value);
                                angular.bind(ws, configureFolder, folder, value)();
                            }
                        });
                        var key = rootId + separator + folderNames.join(separator) + separator + lastPath;
                        var objectName = domain + ":" + path;
                        if (folder) {
                            folder = this.folderGetOrElse(folder, lastPath);
                            if (folder) {
                                folder.entries = entries;
                                folder.key = key;
                                angular.bind(this, configureFolder, folder, lastPath)();
                                folder.title = trimQuotes(lastPath);
                                folder.objectName = objectName;
                                folder.typeName = typeName;
                                var addFolderByDomain = function (owner, typeName) {
                                    var map = owner[typeName];
                                    if (!map) {
                                        map = {};
                                        owner[typeName] = map;
                                    }
                                    var value = map[domain];
                                    if (!value) {
                                        map[domain] = folder;
                                    } else {
                                        var array = null;
                                        if (angular.isArray(value)) {
                                            array = value;
                                        } else {
                                            array = [
                                                value
                                            ];
                                            map[domain] = array;
                                        }
                                        array.push(folder);
                                    }
                                };
                                if (serviceName) {
                                    angular.bind(this, addFolderByDomain, this.mbeanServicesToDomain, serviceName)();
                                }
                                if (typeName) {
                                    angular.bind(this, addFolderByDomain, this.mbeanTypesToDomain, typeName)();
                                }
                            }
                        } else {
                            Core.log.info("No folder found for lastPath: " + lastPath);
                        }
                    }
                }
                tree.sortChildren(true);
                this.enableLazyLoading(tree);
                this.tree = tree;
                var processors = this.treePostProcessors;
                angular.forEach(processors, function (processor) {
                    return processor(tree);
                });
                this.maybeMonitorPlugins();
                var rootScope = this.$rootScope;
                if (rootScope) {
                    rootScope.$broadcast('jmxTreeUpdated');
                }
            }
        };
        Workspace.prototype.enableLazyLoading = function (folder) {
            var _this = this;
            var children = folder.children;
            if (children && children.length) {
                angular.forEach(children, function (child) {
                    _this.enableLazyLoading(child);
                });
            } else {
                var lazyFunction = Jmx.findLazyLoadingFunction(this, folder);
                if (lazyFunction) {
                    folder.isLazy = true;
                }
            }
        };
        Workspace.prototype.hash = function () {
            var hash = this.$location.search();
            var params = Core.hashToString(hash);
            if (params) {
                return "?" + params;
            }
            return "";
        };
        Workspace.prototype.getActiveTab = function () {
            var workspace = this;
            return this.topLevelTabs.find(function (tab) {
                if (!angular.isDefined(tab.isActive)) {
                    return workspace.isLinkActive(tab.href());
                } else {
                    return tab.isActive(workspace);
                }
            });
        };
        Workspace.prototype.getStrippedPathName = function () {
            var pathName = Core.trimLeading((this.$location.path() || '/'), "#");
            pathName = Core.trimLeading(pathName, "/");
            return pathName;
        };
        Workspace.prototype.linkContains = function () {
            var words = [];
            for (var _i = 0; _i < (arguments.length - 0); _i++) {
                words[_i] = arguments[_i + 0];
            }
            var pathName = this.getStrippedPathName();
            return words.all(function (word) {
                return pathName.has(word);
            });
        };
        Workspace.prototype.isLinkActive = function (href) {
            var pathName = this.getStrippedPathName();
            var link = Core.trimLeading(href, "#");
            link = Core.trimLeading(link, "/");
            var idx = link.indexOf('?');
            if (idx >= 0) {
                link = link.substring(0, idx);
            }
            if (!pathName.length) {
                return link === pathName;
            } else {
                return pathName.startsWith(link);
            }
        };
        Workspace.prototype.isTopTabActive = function (path) {
            var tab = this.$location.search()['tab'];
            if (angular.isString(tab)) {
                return tab.startsWith(path);
            }
            return this.isLinkActive(path);
        };
        Workspace.prototype.getSelectedMBeanName = function () {
            var selection = this.selection;
            if (selection) {
                return selection.objectName;
            }
            return null;
        };
        Workspace.prototype.validSelection = function (uri) {
            var workspace = this;
            var filter = function (t) {
                var fn = t.href;
                if (fn) {
                    var href = fn();
                    if (href) {
                        if (href.startsWith("#/")) {
                            href = href.substring(2);
                        }
                        return href === uri;
                    }
                }
                return false;
            };
            var tab = this.subLevelTabs.find(filter);
            if (!tab) {
                tab = this.topLevelTabs.find(filter);
            }
            if (tab) {
                var validFn = tab.isValid;
                return !angular.isDefined(validFn) || validFn(workspace);
            } else {
                Core.log.info("Could not find tab for " + uri);
                return false;
            }
        };
        Workspace.prototype.removeAndSelectParentNode = function () {
            var selection = this.selection;
            if (selection) {
                var parent = selection.parent;
                if (parent) {
                    var idx = parent.children.indexOf(selection);
                    if (idx < 0) {
                        idx = parent.children.findIndex({
                            key: selection.key
                        });
                    }
                    if (idx >= 0) {
                        parent.children.splice(idx, 1);
                    }
                    this.updateSelectionNode(parent);
                }
            }
        };
        Workspace.prototype.selectParentNode = function () {
            var selection = this.selection;
            if (selection) {
                var parent = selection.parent;
                if (parent) {
                    this.updateSelectionNode(parent);
                }
            }
        };
        Workspace.prototype.selectionViewConfigKey = function () {
            return this.selectionConfigKey("view/");
        };
        Workspace.prototype.selectionConfigKey = function (prefix) {
            if (typeof prefix === "undefined") { prefix = ""; }
            var key = null;
            var selection = this.selection;
            if (selection) {
                key = prefix + selection.domain;
                var typeName = selection.typeName;
                if (!typeName) {
                    typeName = selection.title;
                }
                key += "/" + typeName;
                if (selection.isFolder()) {
                    key += "/folder";
                }
            }
            return key;
        };
        Workspace.prototype.moveIfViewInvalid = function () {
            var workspace = this;
            var uri = Core.trimLeading(this.$location.path(), "/");
            if (this.selection) {
                var key = this.selectionViewConfigKey();
                if (this.validSelection(uri)) {
                    this.setLocalStorage(key, uri);
                    return false;
                } else {
                    Core.log.info("the uri '" + uri + "' is not valid for this selection");
                    var defaultPath = this.getLocalStorage(key);
                    if (!defaultPath || !this.validSelection(defaultPath)) {
                        defaultPath = null;
                        angular.forEach(this.subLevelTabs, function (tab) {
                            var fn = tab.isValid;
                            if (!defaultPath && tab.href && angular.isDefined(fn) && fn(workspace)) {
                                defaultPath = tab.href();
                            }
                        });
                    }
                    if (!defaultPath) {
                        defaultPath = "#/jmx/help";
                    }
                    Core.log.info("moving the URL to be " + defaultPath);
                    if (defaultPath.startsWith("#")) {
                        defaultPath = defaultPath.substring(1);
                    }
                    this.$location.path(defaultPath);
                    return true;
                }
            } else {
                return false;
            }
        };
        Workspace.prototype.updateSelectionNode = function (node) {
            var originalSelection = this.selection;
            this.selection = node;
            var key = null;
            if (node) {
                key = node['key'];
            }
            var $location = this.$location;
            var q = $location.search();
            if (key) {
                q['nid'] = key;
            }
            $location.search(q);
            if (originalSelection) {
                key = this.selectionViewConfigKey();
                if (key) {
                    var defaultPath = this.getLocalStorage(key);
                    if (defaultPath) {
                        this.$location.path(defaultPath);
                    }
                }
            }
        };
        Workspace.prototype.redrawTree = function () {
            var treeElement = this.treeElement;
            if (treeElement) {
                treeElement.dynatree("getTree").reload();
            }
        };
        Workspace.prototype.expandSelection = function (flag) {
            var treeElement = this.treeElement;
            if (treeElement) {
                var node = treeElement.dynatree("getActiveNode");
                if (node) {
                    node.expand(flag);
                }
            }
        };
        Workspace.prototype.matchesProperties = function (entries, properties) {
            if (!entries) {
                return false;
            }
            for(var key in properties) {
                var value = properties[key];
                if (!value || entries[key] !== value) {
                    return false;
                }
            }
            return true;
        };
        Workspace.prototype.treeContainsDomainAndProperties = function (domainName, properties) {
            if (typeof properties === "undefined") { properties = null; }
            var _this = this;
            var workspace = this;
            var tree = workspace.tree;
            if (tree) {
                var folder = tree.get(domainName);
                if (folder) {
                    if (properties) {
                        var children = folder.children || [];
                        var checkProperties = function (node) {
                            if (!_this.matchesProperties(node.entries, properties)) {
                                if (node.domain === domainName && node.children && node.children.length > 0) {
                                    return node.children.some(checkProperties);
                                } else {
                                    return false;
                                }
                            } else {
                                return true;
                            }
                        };
                        return children.some(checkProperties);
                    }
                    return true;
                } else {
                }
            } else {
            }
            return false;
        };
        Workspace.prototype.matches = function (folder, properties, propertiesCount) {
            if (folder) {
                var entries = folder.entries;
                if (properties) {
                    if (!entries) {
                        return false;
                    }
                    for(var key in properties) {
                        var value = properties[key];
                        if (!value || entries[key] !== value) {
                            return false;
                        }
                    }
                }
                if (propertiesCount) {
                    return entries && Object.keys(entries).length === propertiesCount;
                }
                return true;
            }
            return false;
        };
        Workspace.prototype.hasDomainAndProperties = function (domainName, properties, propertiesCount) {
            if (typeof properties === "undefined") { properties = null; }
            if (typeof propertiesCount === "undefined") { propertiesCount = null; }
            var node = this.selection;
            if (node) {
                return this.matches(node, properties, propertiesCount) && node.domain === domainName;
            }
            return false;
        };
        Workspace.prototype.findMBeanWithProperties = function (domainName, properties, propertiesCount) {
            if (typeof properties === "undefined") { properties = null; }
            if (typeof propertiesCount === "undefined") { propertiesCount = null; }
            var tree = this.tree;
            if (tree) {
                return this.findChildMBeanWithProperties(tree.get(domainName), properties, propertiesCount);
            }
            return null;
        };
        Workspace.prototype.findChildMBeanWithProperties = function (folder, properties, propertiesCount) {
            if (typeof properties === "undefined") { properties = null; }
            if (typeof propertiesCount === "undefined") { propertiesCount = null; }
            var _this = this;
            var workspace = this;
            if (folder) {
                var children = folder.children;
                if (children) {
                    var answer = children.find(function (node) {
                        return _this.matches(node, properties, propertiesCount);
                    });
                    if (answer) {
                        return answer;
                    }
                    return children.map(function (node) {
                        return workspace.findChildMBeanWithProperties(node, properties, propertiesCount);
                    }).find(function (node) {
                        return node;
                    });
                }
            }
            return null;
        };
        Workspace.prototype.selectionHasDomainAndLastFolderName = function (objectName, lastName) {
            var lastNameLower = (lastName || "").toLowerCase();
            function isName(name) {
                return (name || "").toLowerCase() === lastNameLower;
            }
            var node = this.selection;
            if (node) {
                if (objectName === node.domain) {
                    var folders = node.folderNames;
                    if (folders) {
                        var last = folders.last();
                        return (isName(last) || isName(node.title)) && node.isFolder() && !node.objectName;
                    }
                }
            }
            return false;
        };
        Workspace.prototype.selectionHasDomainAndType = function (objectName, typeName) {
            var node = this.selection;
            if (node) {
                return objectName === node.domain && typeName === node.typeName;
            }
            return false;
        };
        Workspace.prototype.hasFabricMBean = function () {
            return this.hasDomainAndProperties('org.fusesource.fabric', {
                type: 'Fabric'
            });
        };
        Workspace.prototype.isFabricFolder = function () {
            return this.hasDomainAndProperties('org.fusesource.fabric');
        };
        Workspace.prototype.isCamelContext = function () {
            return this.hasDomainAndProperties('org.apache.camel', {
                type: 'context'
            });
        };
        Workspace.prototype.isCamelFolder = function () {
            return this.hasDomainAndProperties('org.apache.camel');
        };
        Workspace.prototype.isEndpointsFolder = function () {
            return this.selectionHasDomainAndLastFolderName('org.apache.camel', 'endpoints');
        };
        Workspace.prototype.isEndpoint = function () {
            return this.hasDomainAndProperties('org.apache.camel', {
                type: 'endpoints'
            });
        };
        Workspace.prototype.isRoutesFolder = function () {
            return this.selectionHasDomainAndLastFolderName('org.apache.camel', 'routes');
        };
        Workspace.prototype.isRoute = function () {
            return this.hasDomainAndProperties('org.apache.camel', {
                type: 'routes'
            });
        };
        Workspace.prototype.isOsgiFolder = function () {
            return this.hasDomainAndProperties('osgi.core');
        };
        Workspace.prototype.isKarafFolder = function () {
            return this.hasDomainAndProperties('org.apache.karaf');
        };
        Workspace.prototype.isOsgiCompendiumFolder = function () {
            return this.hasDomainAndProperties('osgi.compendium');
        };
        return Workspace;
    })();
    Core.Workspace = Workspace;    
})(Core || (Core = {}));
var Workspace = (function (_super) {
    __extends(Workspace, _super);
    function Workspace() {
        _super.apply(this, arguments);

    }
    return Workspace;
})(Core.Workspace);
;
;
var Dashboard;
(function (Dashboard) {
    Dashboard.log = Logger.get('Dashboard');
    function cleanDashboardData(item) {
        var cleanItem = {};
        angular.forEach(item, function (value, key) {
            if (!angular.isString(key) || (!key.startsWith("$") && !key.startsWith("_"))) {
                cleanItem[key] = value;
            }
        });
        return cleanItem;
    }
    Dashboard.cleanDashboardData = cleanDashboardData;
    function decodeURIComponentProperties(hash) {
        if (!hash) {
            return hash;
        }
        var decodeHash = {};
        angular.forEach(hash, function (value, key) {
            decodeHash[key] = value ? decodeURIComponent(value) : value;
        });
        return decodeHash;
    }
    Dashboard.decodeURIComponentProperties = decodeURIComponentProperties;
    function onOperationComplete(result) {
        console.log("Completed adding the dashboard with response " + JSON.stringify(result));
    }
    Dashboard.onOperationComplete = onOperationComplete;
})(Dashboard || (Dashboard = {}));
var Dashboard;
(function (Dashboard) {
    Dashboard.templatePath = 'app/dashboard/html/';
    Dashboard.pluginName = 'dashboard';
    angular.module(Dashboard.pluginName, [
        'bootstrap', 
        'ngResource', 
        'hawtioCore', 
        'hawtio-ui'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/dashboard/add', {
            templateUrl: Dashboard.templatePath + 'addToDashboard.html'
        }).when('/dashboard/edit', {
            templateUrl: Dashboard.templatePath + 'editDashboards.html'
        }).when('/dashboard/idx/:dashboardIndex', {
            templateUrl: Dashboard.templatePath + 'dashboard.html'
        }).when('/dashboard/id/:dashboardId', {
            templateUrl: Dashboard.templatePath + 'dashboard.html'
        }).when('/dashboard/id/:dashboardId/share', {
            templateUrl: Dashboard.templatePath + 'share.html'
        }).when('/dashboard/import', {
            templateUrl: Dashboard.templatePath + 'import.html'
        });
    }).value('ui.config', {
        jq: {
            gridster: {
                widget_margins: [
                    10, 
                    10
                ],
                widget_base_dimensions: [
                    140, 
                    140
                ]
            }
        }
    }).factory('dashboardRepository', function (workspace, jolokia, localStorage) {
        return new Dashboard.DefaultDashboardRepository(workspace, jolokia, localStorage);
    }).directive('hawtioDashboard', function () {
        return new Dashboard.GridsterDirective();
    }).run(function ($location, workspace, viewRegistry, helpRegistry) {
        viewRegistry['dashboard'] = 'app/dashboard/html/layoutDashboard.html';
        helpRegistry.addUserDoc('dashboard', 'app/dashboard/doc/help.md');
        workspace.topLevelTabs.push({
            content: "Dashboard",
            title: "View and edit your own custom dashboards",
            isValid: function (workspace) {
                return true;
            },
            href: function () {
                return "#/dashboard/idx/0?tab=dashboard";
            },
            isActive: function (workspace) {
                return workspace.isTopTabActive("dashboard");
            }
        });
    });
    hawtioPluginLoader.addModule(Dashboard.pluginName);
})(Dashboard || (Dashboard = {}));
var Dashboard;
(function (Dashboard) {
    var defaultDashboards = [
        {
            "title": "Monitor",
            "group": "Personal",
            "widgets": [
                {
                    "id": "w1",
                    "title": "",
                    "row": 1,
                    "col": 1,
                    "size_x": 3,
                    "size_y": 4,
                    "path": "jmx/attributes",
                    "include": "app/jmx/html/attributes.html",
                    "search": {
                        "nid": "root-java.lang-OperatingSystem"
                    },
                    "hash": ""
                }, 
                {
                    "id": "w3",
                    "title": "Java Heap Memory",
                    "row": 1,
                    "col": 6,
                    "size_x": 2,
                    "size_y": 2,
                    "path": "jmx/widget/donut",
                    "include": "app/jmx/html/donutChart.html",
                    "search": {},
                    "hash": "",
                    "routeParams": "{\"type\":\"donut\",\"title\":\"Java Heap Memory\",\"mbean\":\"java.lang:type=Memory\",\"attribute\":\"HeapMemoryUsage\",\"total\":\"Max\",\"terms\":\"Used\",\"remaining\":\"Free\"}"
                }, 
                {
                    "id": "w4",
                    "title": "Java Non Heap Memory",
                    "row": 1,
                    "col": 8,
                    "size_x": 2,
                    "size_y": 2,
                    "path": "jmx/widget/donut",
                    "include": "app/jmx/html/donutChart.html",
                    "search": {},
                    "hash": "",
                    "routeParams": "{\"type\":\"donut\",\"title\":\"Java Non Heap Memory\",\"mbean\":\"java.lang:type=Memory\",\"attribute\":\"NonHeapMemoryUsage\",\"total\":\"Max\",\"terms\":\"Used\",\"remaining\":\"Free\"}"
                }, 
                {
                    "id": "w5",
                    "title": "",
                    "row": 3,
                    "col": 4,
                    "size_x": 6,
                    "size_y": 2,
                    "path": "jmx/charts",
                    "include": "app/jmx/html/charts.html",
                    "search": {
                        "size": "%7B%22size_x%22%3A2%2C%22size_y%22%3A2%7D",
                        "title": "Java%20Non%20Heap%20Memory",
                        "routeParams": "%7B%22type%22%3A%22donut%22%2C%22title%22%3A%22Java%20Non%20Heap%20Memory%22%2C%22mbean%22%3A%22java.lang%3Atype",
                        "nid": "root-java.lang-Threading"
                    },
                    "hash": ""
                }, 
                {
                    "id": "w6",
                    "title": "System CPU Load",
                    "row": 1,
                    "col": 4,
                    "size_x": 2,
                    "size_y": 2,
                    "path": "jmx/widget/area",
                    "include": "app/jmx/html/areaChart.html",
                    "search": {},
                    "hash": "",
                    "routeParams": "{\"type\":\"area\",\"title\":\"System CPU Load\",\"mbean\":\"java.lang:type=OperatingSystem\",\"attribute\":\"SystemCpuLoad\"}"
                }
            ],
            "id": "4e9d116173ca41767e"
        }
    ];
    var DefaultDashboardRepository = (function () {
        function DefaultDashboardRepository(workspace, jolokia, localStorage) {
            this.workspace = workspace;
            this.jolokia = jolokia;
            this.localStorage = localStorage;
            this.repository = null;
        }
        DefaultDashboardRepository.prototype.putDashboards = function (array, commitMessage, fn) {
            this.getRepository().putDashboards(array, commitMessage, fn);
        };
        DefaultDashboardRepository.prototype.deleteDashboards = function (array, fn) {
            this.getRepository().deleteDashboards(array, fn);
        };
        DefaultDashboardRepository.prototype.getDashboards = function (fn) {
            this.getRepository().getDashboards(function (values) {
                fn(values);
            });
        };
        DefaultDashboardRepository.prototype.getDashboard = function (id, onLoad) {
            this.getRepository().getDashboard(id, onLoad);
        };
        DefaultDashboardRepository.prototype.createDashboard = function (options) {
            return this.getRepository().createDashboard(options);
        };
        DefaultDashboardRepository.prototype.cloneDashboard = function (dashboard) {
            return this.getRepository().cloneDashboard(dashboard);
        };
        DefaultDashboardRepository.prototype.getType = function () {
            return this.getRepository().getType();
        };
        DefaultDashboardRepository.prototype.isValid = function () {
            return this.getRepository().isValid();
        };
        DefaultDashboardRepository.prototype.getRepository = function () {
            if (this.repository && this.repository.isValid()) {
                return this.repository;
            }
            if (Fabric.hasFabric(this.workspace)) {
                this.repository = new Dashboard.FabricDashboardRepository(this.workspace, this.jolokia, this.localStorage);
                return this.repository;
            }
            var git = Git.createGitRepository(this.workspace, this.jolokia, this.localStorage);
            if (git) {
                this.repository = new GitDashboardRepository(this.workspace, git);
                return this.repository;
            }
            this.repository = new LocalDashboardRepository(this.workspace);
            return this.repository;
        };
        return DefaultDashboardRepository;
    })();
    Dashboard.DefaultDashboardRepository = DefaultDashboardRepository;    
    var LocalDashboardRepository = (function () {
        function LocalDashboardRepository(workspace) {
            this.workspace = workspace;
            this.localStorage = null;
            this.localStorage = workspace.localStorage;
            if ('userDashboards' in this.localStorage) {
            } else {
                this.storeDashboards(defaultDashboards);
            }
        }
        LocalDashboardRepository.prototype.loadDashboards = function () {
            var answer = angular.fromJson(localStorage['userDashboards']);
            Dashboard.log.debug("returning dashboards: ", answer);
            return answer;
        };
        LocalDashboardRepository.prototype.storeDashboards = function (dashboards) {
            Dashboard.log.debug("storing dashboards: ", dashboards);
            localStorage['userDashboards'] = angular.toJson(dashboards);
            return this.loadDashboards();
        };
        LocalDashboardRepository.prototype.putDashboards = function (array, commitMessage, fn) {
            var dashboards = this.loadDashboards();
            array.forEach(function (dash) {
                var existing = dashboards.findIndex(function (d) {
                    return d.id === dash.id;
                });
                if (existing >= 0) {
                    dashboards[existing] = dash;
                } else {
                    dashboards.push(dash);
                }
            });
            fn(this.storeDashboards(dashboards));
        };
        LocalDashboardRepository.prototype.deleteDashboards = function (array, fn) {
            var dashboards = this.loadDashboards();
            angular.forEach(array, function (item) {
                dashboards.remove(function (i) {
                    return i.id === item.id;
                });
            });
            fn(this.storeDashboards(dashboards));
        };
        LocalDashboardRepository.prototype.getDashboards = function (fn) {
            fn(this.loadDashboards());
        };
        LocalDashboardRepository.prototype.getDashboard = function (id, fn) {
            var dashboards = this.loadDashboards();
            var dashboard = dashboards.find({
                id: id
            });
            fn(dashboard);
        };
        LocalDashboardRepository.prototype.createDashboard = function (options) {
            var answer = {
                title: "New Dashboard",
                group: "Personal",
                widgets: []
            };
            answer = angular.extend(answer, options);
            answer['id'] = Core.getUUID();
            return answer;
        };
        LocalDashboardRepository.prototype.cloneDashboard = function (dashboard) {
            var newDashboard = Object.clone(dashboard);
            newDashboard['id'] = Core.getUUID();
            newDashboard['title'] = "Copy of " + dashboard.title;
            return newDashboard;
        };
        LocalDashboardRepository.prototype.getType = function () {
            return 'container';
        };
        LocalDashboardRepository.prototype.isValid = function () {
            return !Fabric.hasFabric(this.workspace) && !Git.hasGit(this.workspace);
        };
        return LocalDashboardRepository;
    })();
    Dashboard.LocalDashboardRepository = LocalDashboardRepository;    
    var GitDashboardRepository = (function () {
        function GitDashboardRepository(workspace, git) {
            this.workspace = workspace;
            this.git = git;
            this.branch = null;
        }
        GitDashboardRepository.prototype.putDashboards = function (array, commitMessage, fn) {
            var _this = this;
            var toPut = array.length;
            var maybeCallback = function () {
                toPut = toPut - 1;
                if (toPut === 0) {
                    _this.getDashboards(fn);
                }
            };
            angular.forEach(array, function (dash) {
                var path = _this.getDashboardPath(dash);
                var contents = JSON.stringify(dash, null, "  ");
                _this.git.write(_this.branch, path, commitMessage, contents, function () {
                    maybeCallback();
                });
            });
        };
        GitDashboardRepository.prototype.deleteDashboards = function (array, fn) {
            var _this = this;
            var toDelete = array.length;
            var maybeCallback = function () {
                toDelete = toDelete - 1;
                if (toDelete === 0) {
                    _this.getDashboards(fn);
                }
            };
            angular.forEach(array, function (dash) {
                var path = _this.getDashboardPath(dash);
                var commitMessage = "Removing dashboard " + path;
                _this.git.remove(_this.branch, path, commitMessage, function () {
                    maybeCallback();
                });
            });
        };
        GitDashboardRepository.prototype.createDashboard = function (options) {
            var answer = {
                title: "New Dashboard",
                group: "Personal",
                widgets: []
            };
            answer = angular.extend(answer, options);
            answer['id'] = Core.getUUID();
            return answer;
        };
        GitDashboardRepository.prototype.cloneDashboard = function (dashboard) {
            var newDashboard = Object.clone(dashboard);
            newDashboard['id'] = Core.getUUID();
            newDashboard['title'] = "Copy of " + dashboard.title;
            return newDashboard;
        };
        GitDashboardRepository.prototype.getType = function () {
            return 'git';
        };
        GitDashboardRepository.prototype.isValid = function () {
            return Git.hasGit(this.workspace);
        };
        GitDashboardRepository.prototype.getDashboardPath = function (dash) {
            var id = dash.id || Core.getUUID();
            var path = this.getUserDashboardPath(id);
            return path;
        };
        GitDashboardRepository.prototype.getDashboards = function (fn) {
            var _this = this;
            var path = this.getUserDashboardDirectory();
            var dashboards = [];
            this.git.read(this.branch, path, function (details) {
                var files = details.children;
                var toRead = files.length;
                var maybeCallback = function () {
                    toRead = toRead - 1;
                    if (toRead === 0) {
                        fn(dashboards);
                    }
                };
                angular.forEach(files, function (file, idx) {
                    var path = file.path;
                    if (!file.directory && path.endsWith(".json")) {
                        _this.git.read(_this.branch, path, function (details) {
                            var content = details.text;
                            if (content) {
                                try  {
                                    var json = JSON.parse(content);
                                    json.uri = path;
                                    dashboards.push(json);
                                } catch (e) {
                                    console.log("Failed to parse: " + content + " due to: " + e);
                                }
                            }
                            Dashboard.log.debug("git - read ", idx, " files, total: ", files.length);
                            maybeCallback();
                        });
                    }
                });
            });
        };
        GitDashboardRepository.prototype.getDashboard = function (id, fn) {
            var path = this.getUserDashboardPath(id);
            this.git.read(this.branch, path, function (details) {
                var dashboard = null;
                var content = details.text;
                if (content) {
                    try  {
                        dashboard = JSON.parse(content);
                    } catch (e) {
                        console.log("Failed to parse: " + content + " due to: " + e);
                    }
                }
                fn(dashboard);
            });
        };
        GitDashboardRepository.prototype.getUserDashboardDirectory = function () {
            return "/dashboards/team/all";
        };
        GitDashboardRepository.prototype.getUserDashboardPath = function (id) {
            return this.getUserDashboardDirectory() + "/" + id + ".json";
        };
        return GitDashboardRepository;
    })();
    Dashboard.GitDashboardRepository = GitDashboardRepository;    
})(Dashboard || (Dashboard = {}));
var Dashboard;
(function (Dashboard) {
    function EditDashboardsController($scope, $routeParams, $route, $location, $rootScope, dashboardRepository, jolokia, workspace) {
        $scope.hash = workspace.hash();
        $scope.selectedItems = [];
        $scope.repository = dashboardRepository;
        $scope.duplicateDashboards = new Core.Dialog();
        $scope.selectedProfilesDialog = [];
        $scope._dashboards = [];
        $rootScope.$on('dashboardsUpdated', dashboardLoaded);
        $scope.hasUrl = function () {
            return ($scope.url) ? true : false;
        };
        $scope.hasSelection = function () {
            return $scope.selectedItems.length !== 0;
        };
        $scope.gridOptions = {
            selectedItems: $scope.selectedItems,
            showFilter: false,
            showColumnMenu: false,
            filterOptions: {
                filterText: ''
            },
            data: '_dashboards',
            selectWithCheckboxOnly: true,
            showSelectionCheckbox: true,
            columnDefs: [
                {
                    field: 'title',
                    displayName: 'Dashboard',
                    cellTemplate: '<div class="ngCellText"><a ng-href="#/dashboard/id/{{row.getProperty(' + "'id'" + ')}}{{hash}}"><editable-property class="inline-block" on-save="onDashRenamed(row.entity)" property="title" ng-model="row.entity"></editable-property></a></div>'
                }, 
                {
                    field: 'group',
                    displayName: 'Group'
                }
            ]
        };
        $scope.onDashRenamed = function (dash) {
            dashboardRepository.putDashboards([
                dash
            ], "Renamed dashboard", function (dashboards) {
                dashboardLoaded(null, dashboards);
            });
        };
        $scope.usingGit = function () {
            return dashboardRepository.getType() === 'git';
        };
        $scope.usingFabric = function () {
            return dashboardRepository.getType() === 'fabric';
        };
        $scope.usingLocal = function () {
            return dashboardRepository.getType() === 'container';
        };
        if ($scope.usingFabric()) {
            $scope.container = Fabric.getCurrentContainer(jolokia, [
                'versionId', 
                'profileIds'
            ]);
            $scope.gridOptions.columnDefs.add([
                {
                    field: 'versionId',
                    displayName: 'Version'
                }, 
                {
                    field: 'profileId',
                    displayName: 'Profile'
                }, 
                {
                    field: 'fileName',
                    displayName: 'File Name'
                }
            ]);
        }
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateData, 100);
        });
        $scope.goBack = function () {
            var href = Core.trimLeading($scope.url, "#");
            if (href) {
                $location.url(href);
            }
        };
        $scope.duplicateToProfiles = function () {
            if ($scope.hasSelection()) {
                $scope.duplicateDashboards.open();
            }
        };
        $scope.doDuplicateToProfiles = function () {
            $scope.duplicateDashboards.close();
            var newDashboards = [];
            $scope.selectedItems.forEach(function (dashboard) {
                $scope.selectedProfilesDialog.forEach(function (profile) {
                    var newDash = dashboardRepository.cloneDashboard(dashboard);
                    newDash['profileId'] = profile.id;
                    newDash['title'] = dashboard.title;
                    newDashboards.push(newDash);
                });
            });
            var commitMessage = "Duplicating " + $scope.selectedItems.length + " dashboards to " + $scope.selectedProfilesDialog.length + " profiles";
            dashboardRepository.putDashboards(newDashboards, commitMessage, function (dashboards) {
                dashboardLoaded(null, dashboards);
            });
        };
        $scope.addViewToDashboard = function () {
            var nextHref = null;
            angular.forEach($scope.selectedItems, function (selectedItem) {
                var text = $scope.url;
                var query = null;
                if (text) {
                    var idx = text.indexOf('?');
                    if (idx && idx > 0) {
                        query = text.substring(idx + 1);
                        text = text.substring(0, idx);
                    }
                    text = Core.trimLeading(text, "#");
                }
                var search = {};
                if (query) {
                    var expressions = query.split("&");
                    angular.forEach(expressions, function (expression) {
                        if (expression) {
                            var names = expression.split("=");
                            var key = names[0];
                            var value = names.length > 1 ? names[1] : null;
                            if (value) {
                                value = encodeURIComponent(value);
                            }
                            var old = search[key];
                            if (old) {
                                if (!angular.isArray(old)) {
                                    old = [
                                        old
                                    ];
                                    search[key] = old;
                                }
                                old.push(value);
                            } else {
                                search[key] = value;
                            }
                        }
                    });
                }
                if ($route && $route.routes) {
                    var value = $route.routes[text];
                    if (value) {
                        var templateUrl = value["templateUrl"];
                        if (templateUrl) {
                            if (!selectedItem.widgets) {
                                selectedItem.widgets = [];
                            }
                            var nextNumber = selectedItem.widgets.length + 1;
                            var widget = {
                                id: "w" + nextNumber,
                                title: "",
                                row: 1,
                                col: 1,
                                size_x: 1,
                                size_y: 1,
                                path: Core.trimLeading(text, "/"),
                                include: templateUrl,
                                search: search,
                                hash: ""
                            };
                            if ($scope.widgetTitle) {
                                widget.title = $scope.widgetTitle;
                            }
                            var gridWidth = 0;
                            selectedItem.widgets.forEach(function (w) {
                                var rightSide = w.col + w.size_x;
                                if (rightSide > gridWidth) {
                                    gridWidth = rightSide;
                                }
                            });
                            if ($scope.preferredSize) {
                                widget.size_x = parseInt($scope.preferredSize['size_x']);
                                widget.size_y = parseInt($scope.preferredSize['size_y']);
                            }
                            var found = false;
                            var left = function (w) {
                                return w.col;
                            };
                            var right = function (w) {
                                return w.col + w.size_x - 1;
                            };
                            var top = function (w) {
                                return w.row;
                            };
                            var bottom = function (w) {
                                return w.row + w.size_y - 1;
                            };
                            var collision = function (w1, w2) {
                                return !(left(w2) > right(w1) || right(w2) < left(w1) || top(w2) > bottom(w1) || bottom(w2) < top(w1));
                            };
                            if (selectedItem.widgets.isEmpty()) {
                                found = true;
                            }
                            while(!found) {
                                widget.col = 1;
                                for(; (widget.col + widget.size_x) <= gridWidth; widget.col++) {
                                    if (!selectedItem.widgets.any(function (w) {
                                        var c = collision(w, widget);
                                        return c;
                                    })) {
                                        found = true;
                                        break;
                                    }
                                }
                                if (!found) {
                                    widget.row = widget.row + 1;
                                }
                                if (widget.row > 50) {
                                    found = true;
                                }
                            }
                            if ($scope.routeParams) {
                                widget['routeParams'] = $scope.routeParams;
                            }
                            selectedItem.widgets.push(widget);
                            if (!nextHref && selectedItem.id) {
                                nextHref = "/dashboard/id/" + selectedItem.id;
                            }
                        }
                    } else {
                    }
                }
            });
            var commitMessage = "Add widget";
            dashboardRepository.putDashboards($scope.selectedItems, commitMessage, function (dashboards) {
                if (nextHref) {
                    delete $location.search()["href"];
                    $location.path(nextHref);
                    Core.$apply($scope);
                }
            });
        };
        $scope.create = function () {
            var counter = dashboards().length + 1;
            var title = "Untitled" + counter;
            var newDash = dashboardRepository.createDashboard({
                title: title
            });
            dashboardRepository.putDashboards([
                newDash
            ], "Created new dashboard: " + title, function (dashboards) {
                $scope.selectedItems.push(newDash);
                dashboardLoaded(null, dashboards);
            });
        };
        $scope.duplicate = function () {
            var newDashboards = [];
            var commitMessage = "Duplicated dashboard(s) ";
            angular.forEach($scope.selectedItems, function (item, idx) {
                var commitMessage = "Duplicated dashboard " + item.title;
                var newDash = dashboardRepository.cloneDashboard(item);
                newDashboards.push(newDash);
            });
            $scope.selectedItems = [];
            commitMessage = commitMessage + newDashboards.map(function (d) {
                return d.title;
            }).join(',');
            dashboardRepository.putDashboards(newDashboards, commitMessage, function (dashboards) {
                dashboardLoaded(null, dashboards);
            });
        };
        $scope.delete = function () {
            if ($scope.hasSelection()) {
                dashboardRepository.deleteDashboards($scope.selectedItems, function (dashboards) {
                    $scope.selectedItems = [];
                    dashboardLoaded(null, dashboards);
                });
            }
        };
        $scope.gist = function () {
            if ($scope.selectedItems.length > 0) {
                var id = $scope.selectedItems[0].id;
                $location.path("/dashboard/id/" + id + "/share");
            }
        };
        function updateData() {
            var url = $routeParams["href"];
            if (url) {
                $scope.url = decodeURIComponent(url);
            }
            var routeParams = $routeParams["routeParams"];
            if (routeParams) {
                $scope.routeParams = decodeURIComponent(routeParams);
            }
            var size = $routeParams["size"];
            if (size) {
                size = decodeURIComponent(size);
                $scope.preferredSize = angular.fromJson(size);
            }
            var title = $routeParams["title"];
            if (title) {
                title = decodeURIComponent(title);
                $scope.widgetTitle = title;
            }
            dashboardRepository.getDashboards(function (dashboards) {
                dashboardLoaded(null, dashboards);
            });
        }
        function dashboardLoaded(event, dashboards) {
            $scope._dashboards = dashboards;
            if (event === null) {
                $scope.$emit('dashboardsUpdated', dashboards);
            }
            Core.$apply($scope);
        }
        function dashboards() {
            return $scope._dashboards;
        }
        updateData();
    }
    Dashboard.EditDashboardsController = EditDashboardsController;
})(Dashboard || (Dashboard = {}));
var Dashboard;
(function (Dashboard) {
    var FabricDashboardRepository = (function () {
        function FabricDashboardRepository(workspace, jolokia, localStorage) {
            this.workspace = workspace;
            this.jolokia = jolokia;
            this.localStorage = localStorage;
            this.details = this.getBranchAndProfiles();
        }
        FabricDashboardRepository.prototype.getBranchAndProfiles = function () {
            if (Fabric.fabricCreated(this.workspace)) {
                var container = Fabric.getCurrentContainer(this.jolokia, [
                    'id', 
                    'versionId', 
                    'profiles'
                ]);
                var profiles = [];
                if (container.profiles) {
                    profiles = container.profiles.unique();
                    profiles = Fabric.filterProfiles(this.jolokia, container.versionId, profiles);
                }
                return {
                    branch: container.versionId,
                    profiles: profiles
                };
            } else {
                return {
                    branch: "1.0",
                    profiles: []
                };
            }
        };
        FabricDashboardRepository.prototype.putDashboards = function (array, commitMessage, fn) {
            var _this = this;
            var jolokia = this.jolokia;
            var details = this.details;
            var toPut = array.length;
            var maybeCallback = function () {
                toPut = toPut - 1;
                if (toPut === 0) {
                    _this.getDashboards(fn);
                }
            };
            array.forEach(function (dashboard) {
                var data = angular.toJson(dashboard, true);
                var profileId = dashboard.profileId;
                if (!profileId) {
                    profileId = details.profiles.first();
                }
                var fileName = dashboard.fileName;
                if (!fileName) {
                    fileName = Core.getUUID() + ".dashboard";
                }
                Fabric.saveConfigFile(jolokia, details.branch, profileId, fileName, data.encodeBase64(), function () {
                    maybeCallback();
                }, function (response) {
                    Dashboard.log.error("Failed to store dashboard: ", dashboard.title, " due to: ", response.error, " stack trace: ", response.stacktrace);
                    maybeCallback();
                });
            });
        };
        FabricDashboardRepository.prototype.deleteDashboards = function (array, fn) {
            var _this = this;
            var jolokia = this.jolokia;
            var details = this.details;
            var toDelete = array.length;
            var maybeCallback = function () {
                toDelete = toDelete - 1;
                if (toDelete === 0) {
                    _this.getDashboards(fn);
                }
            };
            array.forEach(function (dashboard) {
                var profileId = dashboard.profileId;
                var fileName = dashboard.fileName;
                if (profileId && fileName) {
                    Fabric.deleteConfigFile(jolokia, details.branch, profileId, fileName, function () {
                        maybeCallback();
                    }, function (response) {
                        Dashboard.log.error("Failed to delete dashboard: ", dashboard.title, " due to: ", response.error, " stack trace: ", response.stacktrace);
                        maybeCallback();
                    });
                }
            });
        };
        FabricDashboardRepository.prototype.createDashboard = function (options) {
            var answer = {
                title: "New Dashboard",
                group: "Fabric",
                versionId: this.details.branch,
                profileId: this.details.profiles.first(),
                widgets: []
            };
            answer = angular.extend(answer, options);
            var uuid = Core.getUUID();
            answer['id'] = uuid;
            answer['fileName'] = uuid + ".dashboard";
            return answer;
        };
        FabricDashboardRepository.prototype.cloneDashboard = function (dashboard) {
            var newDashboard = Object.clone(dashboard);
            var uuid = Core.getUUID();
            newDashboard['id'] = uuid;
            newDashboard['fileName'] = uuid + ".dashboard";
            newDashboard['title'] = "Copy of " + dashboard.title;
            return newDashboard;
        };
        FabricDashboardRepository.prototype.getType = function () {
            return 'fabric';
        };
        FabricDashboardRepository.prototype.isValid = function () {
            return Fabric.hasFabric(this.workspace);
        };
        FabricDashboardRepository.prototype.getDashboards = function (fn) {
            var _this = this;
            var jolokia = this.jolokia;
            var details = this.details;
            var dashboards = [];
            jolokia.request({
                type: 'exec',
                mbean: Fabric.managerMBean,
                operation: 'getConfigurationFiles',
                arguments: [
                    details.branch, 
                    details.profiles, 
                    ".*dashboard"
                ]
            }, {
                method: 'POST',
                success: function (response) {
                    angular.forEach(response.value, function (value, profile) {
                        angular.forEach(value, function (value, fileName) {
                            var dashboard = angular.fromJson(value.decodeBase64());
                            dashboard['versionId'] = details.branch;
                            dashboard['profileId'] = profile;
                            dashboard['fileName'] = fileName;
                            dashboards.push(dashboard);
                        });
                    });
                    if (dashboards.isEmpty()) {
                        dashboards.push(_this.createDashboard({}));
                    }
                    fn(dashboards);
                },
                error: function (response) {
                    Dashboard.log.error("Failed to load dashboard data: error: ", response.error, " stack trace: ", response.stacktrace);
                    fn([]);
                }
            });
        };
        FabricDashboardRepository.prototype.getDashboard = function (id, fn) {
            this.getDashboards(function (dashboards) {
                var dashboard = dashboards.find(function (dashboard) {
                    return dashboard.id === id;
                });
                fn(dashboard);
            });
        };
        return FabricDashboardRepository;
    })();
    Dashboard.FabricDashboardRepository = FabricDashboardRepository;    
})(Dashboard || (Dashboard = {}));
var Dashboard;
(function (Dashboard) {
    var GridsterDirective = (function () {
        function GridsterDirective() {
            this.restrict = 'A';
            this.replace = true;
            this.controller = function ($scope, $element, $attrs, $location, $routeParams, $injector, $route, $templateCache, workspace, dashboardRepository, $compile) {
                $scope.route = $route;
                $scope.injector = $injector;
                var gridSize = 150;
                var gridMargin = 6;
                var gridHeight;
                $scope.gridX = gridSize;
                $scope.gridY = gridSize;
                $scope.widgetMap = {};
                $scope.$on('$destroy', function () {
                    angular.forEach($scope.widgetMap, function (value, key) {
                        if ('scope' in value) {
                            var scope = value['scope'];
                            scope.$destroy();
                        }
                    });
                });
                updateWidgets();
                $scope.removeWidget = function (widget) {
                    var gridster = getGridster();
                    var widgetElem = null;
                    var widgetData = $scope.widgetMap[widget.id];
                    if (widgetData) {
                        delete $scope.widgetMap[widget.id];
                        var scope = widgetData.scope;
                        widgetElem = widgetData.widget;
                        if (scope) {
                            scope.$destroy();
                        }
                    }
                    if (!widgetElem) {
                        widgetElem = $("div").find("[data-widgetId='" + widget.id + "']").parent();
                    }
                    if (gridster && widgetElem) {
                        gridster.remove_widget(widgetElem);
                    }
                    if ($scope.dashboard) {
                        var widgets = $scope.dashboard.widgets;
                        if (widgets) {
                            widgets.remove(widget);
                        }
                    }
                    updateDashboardRepository("Removed widget " + widget.title);
                };
                function changeWidgetSize(widget, sizefunc, savefunc) {
                    var gridster = getGridster();
                    var entry = $scope.widgetMap[widget.id];
                    var w = entry.widget;
                    var scope = entry.scope;
                    sizefunc(entry);
                    gridster.resize_widget(w, entry.size_x, entry.size_y);
                    gridster.set_dom_grid_height();
                    setTimeout(function () {
                        var template = $templateCache.get("widgetTemplate");
                        var div = $('<div></div>');
                        div.html(template);
                        w.html($compile(div.contents())(scope));
                        makeResizable();
                        Core.$apply($scope);
                        setTimeout(function () {
                            savefunc(widget);
                        }, 50);
                    }, 30);
                }
                $scope.onWidgetRenamed = function (widget) {
                    updateDashboardRepository("Renamed widget to " + widget.title);
                };
                function updateWidgets() {
                    $scope.id = $routeParams["dashboardId"];
                    $scope.idx = $routeParams["dashboardIndex"];
                    if ($scope.id) {
                        $scope.$emit('loadDashboards');
                        dashboardRepository.getDashboard($scope.id, onDashboardLoad);
                    } else {
                        dashboardRepository.getDashboards(function (dashboards) {
                            $scope.$emit('dashboardsUpdated', dashboards);
                            var idx = $scope.idx ? parseInt($scope.idx) : 0;
                            var id = null;
                            if (dashboards.length > 0) {
                                var dashboard = dashboards.length > idx ? dashboards[idx] : dashboard[0];
                                id = dashboard.id;
                            }
                            if (id) {
                                $location.path("/dashboard/id/" + id);
                            } else {
                                $location.path("/dashboard/edit?tab=dashboard");
                            }
                            Core.$apply($scope);
                        });
                    }
                }
                function onDashboardLoad(dashboard) {
                    $scope.dashboard = dashboard;
                    var widgets = ((dashboard) ? dashboard.widgets : null) || [];
                    var minHeight = 10;
                    var minWidth = 6;
                    angular.forEach(widgets, function (widget) {
                        if (angular.isDefined(widget.row) && minHeight < widget.row) {
                            minHeight = widget.row + 1;
                        }
                        if (angular.isDefined(widget.size_x && angular.isDefined(widget.col))) {
                            var rightEdge = widget.col + widget.size_x;
                            if (rightEdge > minWidth) {
                                minWidth = rightEdge + 1;
                            }
                        }
                    });
                    var gridster = $element.gridster({
                        widget_margins: [
                            gridMargin, 
                            gridMargin
                        ],
                        widget_base_dimensions: [
                            $scope.gridX, 
                            $scope.gridY
                        ],
                        extra_rows: minHeight,
                        extra_cols: minWidth,
                        max_size_x: minWidth,
                        max_size_y: minHeight,
                        draggable: {
                            stop: function (event, ui) {
                                if (serializeDashboard()) {
                                    updateDashboardRepository("Changing dashboard layout");
                                }
                            }
                        }
                    }).data('gridster');
                    var template = $templateCache.get("widgetTemplate");
                    angular.forEach(widgets, function (widget) {
                        var childScope = $scope.$new(false);
                        childScope.widget = widget;
                        var path = widget.path;
                        var search = null;
                        if (widget.search) {
                            search = Dashboard.decodeURIComponentProperties(widget.search);
                        }
                        var hash = widget.hash;
                        var location = new Dashboard.RectangleLocation($location, path, search, hash);
                        var routeParams = null;
                        if (widget.routeParams) {
                            routeParams = angular.fromJson(widget.routeParams);
                        }
                        var childWorkspace = workspace.createChildWorkspace(location);
                        childWorkspace.$location = location;
                        if (search) {
                            var key = location.search()['nid'];
                            if (key && workspace.tree) {
                                childWorkspace.selection = workspace.keyToNodeMap[key];
                                if (!childWorkspace.selection) {
                                    var decodedKey = decodeURIComponent(key);
                                    childWorkspace.selection = workspace.keyToNodeMap[decodedKey];
                                }
                            }
                        }
                        var $$scopeInjections = {
                            workspace: childWorkspace,
                            location: location,
                            $location: location,
                            $routeParams: routeParams
                        };
                        childScope.$$scopeInjections = $$scopeInjections;
                        childScope.inDashboard = true;
                        if (!widget.size_x || widget.size_x < 1) {
                            widget.size_x = 1;
                        }
                        if (!widget.size_y || widget.size_y < 1) {
                            widget.size_y = 1;
                        }
                        var div = $('<div></div>');
                        div.html(template);
                        var outerDiv = $('<li class="grid-block" style="display: list-item; position: absolute"></li>');
                        outerDiv.html($compile(div.contents())(childScope));
                        var w = gridster.add_widget(outerDiv, widget.size_x, widget.size_y, widget.col, widget.row);
                        $scope.widgetMap[widget.id] = {
                            widget: w,
                            scope: childScope
                        };
                    });
                    makeResizable();
                    getGridster().enable();
                    Core.$apply($scope);
                }
                function serializeDashboard() {
                    var gridster = getGridster();
                    if (gridster) {
                        var data = gridster.serialize();
                        var widgets = $scope.dashboard.widgets || [];
                        angular.forEach(widgets, function (widget, idx) {
                            var value = data[idx];
                            if (value && widget) {
                                angular.forEach(value, function (attr, key) {
                                    return widget[key] = attr;
                                });
                            }
                        });
                        return true;
                    }
                    return false;
                }
                function makeResizable() {
                    var blocks = $('.grid-block');
                    blocks.resizable('destroy');
                    blocks.resizable({
                        grid: [
                            gridSize + (gridMargin * 2), 
                            gridSize + (gridMargin * 2)
                        ],
                        animate: false,
                        minWidth: gridSize,
                        minHeight: gridSize,
                        autoHide: false,
                        start: function (event, ui) {
                            gridHeight = getGridster().$el.height();
                        },
                        resize: function (event, ui) {
                            var g = getGridster();
                            var delta = gridSize + gridMargin * 2;
                            if (event.offsetY > g.$el.height()) {
                                var extra = Math.floor((event.offsetY - gridHeight) / delta + 1);
                                var newHeight = gridHeight + extra * delta;
                                g.$el.css('height', newHeight);
                            }
                        },
                        stop: function (event, ui) {
                            var resized = $(this);
                            setTimeout(function () {
                                resizeBlock(resized);
                            }, 300);
                        }
                    });
                    $('.ui-resizable-handle').hover(function () {
                        getGridster().disable();
                    }, function () {
                        getGridster().enable();
                    });
                }
                function resizeBlock(elmObj) {
                    var elmObj = $(elmObj);
                    var area = elmObj.find('.widget-area');
                    var w = elmObj.width() - gridSize;
                    var h = elmObj.height() - gridSize;
                    for(var grid_w = 1; w > 0; w -= (gridSize + (gridMargin * 2))) {
                        grid_w++;
                    }
                    for(var grid_h = 1; h > 0; h -= (gridSize + (gridMargin * 2))) {
                        grid_h++;
                    }
                    var widget = {
                        id: area.attr('data-widgetId')
                    };
                    changeWidgetSize(widget, function (widget) {
                        widget.size_x = grid_w;
                        widget.size_y = grid_h;
                    }, function (widget) {
                        if (serializeDashboard()) {
                            updateDashboardRepository("Changed size of widget: " + widget.id);
                        }
                    });
                }
                function updateDashboardRepository(message) {
                    if ($scope.dashboard) {
                        var commitMessage = message;
                        if ($scope.dashboard && $scope.dashboard.title) {
                            commitMessage += " on dashboard " + $scope.dashboard.title;
                        }
                        dashboardRepository.putDashboards([
                            $scope.dashboard
                        ], commitMessage, Dashboard.onOperationComplete);
                    }
                }
                function getGridster() {
                    return $element.gridster().data('gridster');
                }
            };
        }
        return GridsterDirective;
    })();
    Dashboard.GridsterDirective = GridsterDirective;    
})(Dashboard || (Dashboard = {}));
var Dashboard;
(function (Dashboard) {
    function ImportController($scope, $location, $routeParams, workspace, dashboardRepository) {
        $scope.placeholder = "Paste the JSON here for the dashboard configuration to import...";
        $scope.source = $scope.placeholder;
        var options = {
            mode: {
                name: "javascript"
            }
        };
        $scope.codeMirrorOptions = CodeEditor.createEditorSettings(options);
        $scope.isValid = function () {
            return $scope.source && $scope.source !== $scope.placeholder;
        };
        $scope.importJSON = function () {
            var json = [];
            try  {
                json = JSON.parse($scope.source);
            } catch (e) {
                notification("error", "Could not parse the JSON\n" + e);
                json = [];
            }
            var array = [];
            if (angular.isArray(json)) {
                array = json;
            } else if (angular.isObject(json)) {
                array.push(json);
            }
            if (array.length) {
                angular.forEach(array, function (dash, index) {
                    angular.copy(dash, dashboardRepository.createDashboard(dash));
                });
                dashboardRepository.putDashboards(array, "Imported dashboard JSON", Dashboard.onOperationComplete);
                $location.path("/dashboard/edit");
            }
        };
    }
    Dashboard.ImportController = ImportController;
})(Dashboard || (Dashboard = {}));
var Dashboard;
(function (Dashboard) {
    function NavBarController($scope, $routeParams, $rootScope, workspace, dashboardRepository) {
        $scope.hash = workspace.hash();
        $scope._dashboards = [];
        $scope.activeDashboard = $routeParams['dashboardId'];
        $rootScope.$on('loadDashboards', loadDashboards);
        $rootScope.$on('dashboardsUpdated', dashboardLoaded);
        $scope.dashboards = function () {
            return $scope._dashboards;
        };
        $scope.isActive = function (dash) {
            return workspace.isLinkActive("#/dashboard/id/" + dash.id);
        };
        $scope.isEditing = function () {
            return workspace.isLinkActive("#/dashboard/edit");
        };
        $scope.onTabRenamed = function (dash) {
            dashboardRepository.putDashboards([
                dash
            ], "Renamed dashboard", function (dashboards) {
                dashboardLoaded(null, dashboards);
            });
        };
        function dashboardLoaded(event, dashboards) {
            Dashboard.log.debug("navbar dashboardLoaded: ", dashboards);
            $scope._dashboards = dashboards;
            if (event === null) {
                $rootScope.$broadcast('dashboardsUpdated', dashboards);
                Core.$apply($scope);
            }
        }
        function loadDashboards(event) {
            dashboardRepository.getDashboards(function (dashboards) {
                dashboardLoaded(event, dashboards);
                Core.$apply($scope);
            });
        }
    }
    Dashboard.NavBarController = NavBarController;
})(Dashboard || (Dashboard = {}));
var Dashboard;
(function (Dashboard) {
    var RectangleLocation = (function () {
        function RectangleLocation(delegate, path, search, hash) {
            this.delegate = delegate;
            this._path = path;
            this._search = search;
            this._hash = hash;
        }
        RectangleLocation.prototype.absUrl = function () {
            return this.protocol() + this.host() + ":" + this.port() + this.path() + this.search();
        };
        RectangleLocation.prototype.hash = function (newHash) {
            if (typeof newHash === "undefined") { newHash = null; }
            if (newHash) {
                return this.delegate.hash(newHash).search('tab', null);
                ;
            }
            return this._hash;
        };
        RectangleLocation.prototype.host = function () {
            return this.delegate.host();
        };
        RectangleLocation.prototype.path = function (newPath) {
            if (typeof newPath === "undefined") { newPath = null; }
            if (newPath) {
                return this.delegate.path(newPath).search('tab', null);
            }
            return this._path;
        };
        RectangleLocation.prototype.port = function () {
            return this.delegate.port();
        };
        RectangleLocation.prototype.protocol = function () {
            return this.delegate.port();
        };
        RectangleLocation.prototype.replace = function () {
            return this;
        };
        RectangleLocation.prototype.search = function (parametersMap) {
            if (typeof parametersMap === "undefined") { parametersMap = null; }
            if (parametersMap) {
                return this.delegate.search(parametersMap);
            }
            return this._search;
        };
        RectangleLocation.prototype.url = function (newValue) {
            if (typeof newValue === "undefined") { newValue = null; }
            if (newValue) {
                return this.delegate.url(newValue).search('tab', null);
            }
            return this.absUrl();
        };
        return RectangleLocation;
    })();
    Dashboard.RectangleLocation = RectangleLocation;    
})(Dashboard || (Dashboard = {}));
var Dashboard;
(function (Dashboard) {
    function ShareController($scope, $location, $routeParams, workspace, dashboardRepository) {
        var id = $routeParams["dashboardId"];
        dashboardRepository.getDashboard(id, onDashboardLoad);
        var options = {
            mode: {
                name: "javascript"
            }
        };
        $scope.codeMirrorOptions = CodeEditor.createEditorSettings(options);
        function onDashboardLoad(dashboard) {
            $scope.dashboard = Dashboard.cleanDashboardData(dashboard);
            $scope.json = {
                "description": "hawtio dashboards",
                "public": true,
                "files": {
                    "dashboards.json": {
                        "content": JSON.stringify($scope.dashboard, null, "  ")
                    }
                }
            };
            $scope.source = JSON.stringify($scope.dashboard, null, "  ");
            Core.$applyNowOrLater($scope);
        }
    }
    Dashboard.ShareController = ShareController;
})(Dashboard || (Dashboard = {}));
var DataTable;
(function (DataTable) {
    var pluginName = 'datatable';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'hawtioCore'
    ]).directive('hawtioDatatable', function (workspace, $timeout, $filter, $compile) {
        return function (scope, element, attrs) {
            var gridOptions = null;
            var data = null;
            var widget = null;
            var timeoutId = null;
            var initialised = false;
            var childScopes = [];
            var rowDetailTemplate = null;
            var rowDetailTemplateId = null;
            var selectedItems = null;
            function updateGrid() {
                Core.$applyNowOrLater(scope);
            }
            function convertToDataTableColumn(columnDef) {
                var data = {
                    mData: columnDef.field,
                    sDefaultContent: ""
                };
                var name = columnDef.displayName;
                if (name) {
                    data["sTitle"] = name;
                }
                var width = columnDef.width;
                if (angular.isNumber(width)) {
                    data["sWidth"] = "" + width + "px";
                } else if (angular.isString(width) && !width.startsWith("*")) {
                    data["sWidth"] = width;
                }
                var template = columnDef.cellTemplate;
                if (template) {
                    data["fnCreatedCell"] = function (nTd, sData, oData, iRow, iCol) {
                        var childScope = childScopes[iRow];
                        if (!childScope) {
                            childScope = scope.$new(false);
                            childScopes[iRow] = childScope;
                        }
                        var entity = oData;
                        childScope["row"] = {
                            entity: entity,
                            getProperty: function (name) {
                                return entity[name];
                            }
                        };
                        var elem = $(nTd);
                        elem.html(template);
                        var contents = elem.contents();
                        contents.removeClass("ngCellText");
                        $compile(contents)(childScope);
                    };
                } else {
                    var cellFilter = columnDef.cellFilter;
                    var render = columnDef.render;
                    if (cellFilter && !render) {
                        var filter = $filter(cellFilter);
                        if (filter) {
                            render = function (data, type, full) {
                                return filter(data);
                            };
                        }
                    }
                    if (render) {
                        data["mRender"] = render;
                    }
                }
                return data;
            }
            function destroyChildScopes() {
                angular.forEach(childScopes, function (childScope) {
                    childScope.$destroy();
                });
                childScopes = [];
            }
            function selectHandler(selection) {
                if (selection && selectedItems) {
                    selectedItems.splice(0, selectedItems.length);
                    selectedItems.push(selection);
                    Core.$apply(scope);
                }
            }
            function onTableDataChange(value) {
                gridOptions = value;
                if (gridOptions) {
                    selectedItems = gridOptions.selectedItems;
                    rowDetailTemplate = gridOptions.rowDetailTemplate;
                    rowDetailTemplateId = gridOptions.rowDetailTemplateId;
                    if (widget === null) {
                        var widgetOptions = {
                            selectHandler: selectHandler,
                            disableAddColumns: true,
                            rowDetailTemplateId: rowDetailTemplateId,
                            ignoreColumns: gridOptions.ignoreColumns,
                            flattenColumns: gridOptions.flattenColumns
                        };
                        var rootElement = $(element);
                        var tableElement = rootElement.children("table");
                        if (!tableElement.length) {
                            $("<table class='table table-bordered table-condensed'></table>").appendTo(rootElement);
                            tableElement = rootElement.children("table");
                        }
                        tableElement.removeClass('table-striped');
                        tableElement.addClass('dataTable');
                        var trElement = Core.getOrCreateElements(tableElement, [
                            "thead", 
                            "tr"
                        ]);
                        destroyChildScopes();
                        var columns = [];
                        var columnCounter = 1;
                        var extraLeftColumn = rowDetailTemplate || rowDetailTemplateId;
                        if (extraLeftColumn) {
                            columns.push({
                                "mDataProp": null,
                                "sClass": "control center",
                                "sWidth": "30px",
                                "sDefaultContent": '<i class="icon-plus"></i>'
                            });
                            var th = trElement.children("th");
                            if (th.length < columnCounter++) {
                                $("<th></th>").appendTo(trElement);
                            }
                        }
                        var columnDefs = gridOptions.columnDefs;
                        if (angular.isString(columnDefs)) {
                            columnDefs = scope[columnDefs];
                        }
                        angular.forEach(columnDefs, function (columnDef) {
                            th = trElement.children("th");
                            if (th.length < columnCounter++) {
                                var name = columnDef.displayName || "";
                                $("<th>" + name + "</th>").appendTo(trElement);
                            }
                            columns.push(convertToDataTableColumn(columnDef));
                        });
                        widget = new TableWidget(scope, workspace, columns, widgetOptions);
                        widget.tableElement = tableElement;
                        var sortInfo = gridOptions.sortInfo;
                        if (sortInfo && columnDefs) {
                            var sortColumns = [];
                            var field = sortInfo.field;
                            if (field) {
                                var idx = columnDefs.findIndex({
                                    field: field
                                });
                                if (idx >= 0) {
                                    if (extraLeftColumn) {
                                        idx += 1;
                                    }
                                    var asc = sortInfo.direction || "asc";
                                    asc = asc.toLowerCase();
                                    sortColumns.push([
                                        idx, 
                                        asc
                                    ]);
                                }
                            }
                            if (sortColumns.length) {
                                widget.sortColumns = sortColumns;
                            }
                        }
                        if (columns.every(function (col) {
                            return col.sWidth;
                        })) {
                            widget.dataTableConfig.bAutoWidth = false;
                        }
                        var filterText = null;
                        var filterOptions = gridOptions.filterOptions;
                        if (filterOptions) {
                            filterText = filterOptions.filterText;
                        }
                        if (filterText || (angular.isDefined(gridOptions.showFilter) && !gridOptions.showFilter)) {
                            widget.dataTableConfig.sDom = 'Rlrtip';
                        }
                        if (filterText) {
                            scope.$watch(filterText, function (value) {
                                var dataTable = widget.dataTable;
                                if (dataTable) {
                                    dataTable.fnFilter(value);
                                }
                            });
                        }
                        if (angular.isDefined(gridOptions.displayFooter) && !gridOptions.displayFooter && widget.dataTableConfig.sDom) {
                            widget.dataTableConfig.sDom = widget.dataTableConfig.sDom.replace('i', '');
                        }
                    }
                    if (!data) {
                        data = gridOptions.data;
                        if (data) {
                            var listener = function (value) {
                                if (initialised || (value && (!angular.isArray(value) || value.length))) {
                                    initialised = true;
                                    destroyChildScopes();
                                    widget.populateTable(value);
                                    updateLater();
                                }
                            };
                            scope.$watch(data, listener);
                            scope.$on("hawtio.datatable." + data, function (args) {
                                var value = Core.pathGet(scope, data);
                                listener(value);
                            });
                        }
                    }
                }
                updateGrid();
            }
            scope.$watch(attrs.hawtioDatatable, onTableDataChange);
            function updateLater() {
                timeoutId = $timeout(function () {
                    updateGrid();
                }, 300);
            }
            element.bind('$destroy', function () {
                destroyChildScopes();
                $timeout.cancel(timeoutId);
            });
            updateLater();
        };
    }).run(function (helpRegistry) {
        helpRegistry.addDevDoc(pluginName, 'app/datatable/doc/developer.md');
    });
    hawtioPluginLoader.addModule(pluginName);
})(DataTable || (DataTable = {}));
var Dozer;
(function (Dozer) {
    Dozer.jmxDomain = 'net.sourceforge.dozer';
    Dozer.excludedPackages = [
        'java.lang', 
        'int', 
        'double', 
        'long'
    ];
    Dozer.elementNameMappings = {
        "Mapping": "mapping",
        "MappingClass": "class",
        "Field": "field"
    };
    Dozer.log = Logger.get("Dozer");
    function loadDozerModel(xml, pageId) {
        var doc = xml;
        if (angular.isString(xml)) {
            doc = $.parseXML(xml);
        }
        console.log("Has Dozer XML document: " + doc);
        var model = new Dozer.Mappings(doc);
        var mappingsElement = doc.documentElement;
        copyAttributes(model, mappingsElement);
        $(mappingsElement).children("mapping").each(function (idx, element) {
            var mapping = createMapping(element);
            model.mappings.push(mapping);
        });
        return model;
    }
    Dozer.loadDozerModel = loadDozerModel;
    function saveToXmlText(model) {
        var element = model.doc.documentElement.cloneNode(false);
        appendElement(model.mappings, element, null, 1);
        Dozer.addTextNode(element, "\n");
        var xmlText = Core.xmlNodeToString(element);
        return '<?xml version="1.0" encoding="UTF-8"?>\n' + xmlText;
    }
    Dozer.saveToXmlText = saveToXmlText;
    function findUnmappedFields(workspace, mapping, fn) {
        var className = mapping.class_a.value;
        findProperties(workspace, className, null, function (properties) {
            var answer = [];
            angular.forEach(properties, function (property) {
                console.log("got property " + JSON.stringify(property, null, "  "));
                var name = property.name;
                if (name) {
                    if (mapping.hasFromField(name)) {
                    } else {
                        answer.push(new Dozer.UnmappedField(name, property));
                    }
                }
            });
            fn(answer);
        });
    }
    Dozer.findUnmappedFields = findUnmappedFields;
    function findProperties(workspace, className, filter, fn) {
        if (typeof filter === "undefined") { filter = null; }
        if (typeof fn === "undefined") { fn = null; }
        var mbean = getIntrospectorMBean(workspace);
        if (mbean) {
            if (filter) {
                return workspace.jolokia.execute(mbean, "findProperties", className, filter, onSuccess(fn));
            } else {
                return workspace.jolokia.execute(mbean, "getProperties", className, onSuccess(fn));
            }
        } else {
            if (fn) {
                return fn([]);
            } else {
                return [];
            }
        }
    }
    Dozer.findProperties = findProperties;
    function findClassNames(workspace, searchText, limit, fn) {
        if (typeof limit === "undefined") { limit = 20; }
        if (typeof fn === "undefined") { fn = null; }
        var mbean = getIntrospectorMBean(workspace);
        if (mbean) {
            return workspace.jolokia.execute(mbean, "findClassNames", searchText, limit, onSuccess(fn));
        } else {
            if (fn) {
                return fn([]);
            } else {
                return [];
            }
        }
    }
    Dozer.findClassNames = findClassNames;
    function getIntrospectorMBean(workspace) {
        return Core.getMBeanTypeObjectName(workspace, "hawtio", "Introspector");
    }
    Dozer.getIntrospectorMBean = getIntrospectorMBean;
    function loadModelFromTree(rootTreeNode, oldModel) {
        oldModel.mappings = [];
        angular.forEach(rootTreeNode.childList, function (treeNode) {
            var mapping = Core.pathGet(treeNode, [
                "data", 
                "entity"
            ]);
            if (mapping) {
                oldModel.mappings.push(mapping);
            }
        });
        return oldModel;
    }
    Dozer.loadModelFromTree = loadModelFromTree;
    function createDozerTree(model) {
        var id = "mappings";
        var folder = new Folder(id);
        folder.addClass = "net-sourceforge-dozer-mappings";
        folder.domain = Dozer.jmxDomain;
        folder.typeName = "mappings";
        folder.entity = model;
        folder.key = Core.toSafeDomID(id);
        angular.forEach(model.mappings, function (mapping) {
            var mappingFolder = createMappingFolder(mapping, folder);
            folder.children.push(mappingFolder);
        });
        return folder;
    }
    Dozer.createDozerTree = createDozerTree;
    function createMappingFolder(mapping, parentFolder) {
        var mappingName = mapping.name();
        var mappingFolder = new Folder(mappingName);
        mappingFolder.addClass = "net-sourceforge-dozer-mapping";
        mappingFolder.typeName = "mapping";
        mappingFolder.domain = Dozer.jmxDomain;
        mappingFolder.key = (parentFolder ? parentFolder.key + "_" : "") + Core.toSafeDomID(mappingName);
        mappingFolder.parent = parentFolder;
        mappingFolder.entity = mapping;
        mappingFolder.icon = url("/app/dozer/img/class.gif");
        angular.forEach(mapping.fields, function (field) {
            addMappingFieldFolder(field, mappingFolder);
        });
        return mappingFolder;
    }
    Dozer.createMappingFolder = createMappingFolder;
    function addMappingFieldFolder(field, mappingFolder) {
        var name = field.name();
        var fieldFolder = new Folder(name);
        fieldFolder.addClass = "net-sourceforge-dozer-field";
        fieldFolder.typeName = "field";
        fieldFolder.domain = Dozer.jmxDomain;
        fieldFolder.key = mappingFolder.key + "_" + Core.toSafeDomID(name);
        fieldFolder.parent = mappingFolder;
        fieldFolder.entity = field;
        fieldFolder.icon = url("/app/dozer/img/attribute.gif");
        mappingFolder.children.push(fieldFolder);
        return fieldFolder;
    }
    Dozer.addMappingFieldFolder = addMappingFieldFolder;
    function createMapping(element) {
        var mapping = new Dozer.Mapping();
        var elementJQ = $(element);
        mapping.class_a = createMappingClass(elementJQ.children("class-a"));
        mapping.class_b = createMappingClass(elementJQ.children("class-b"));
        elementJQ.children("field").each(function (idx, fieldElement) {
            var field = createField(fieldElement);
            mapping.fields.push(field);
        });
        copyAttributes(mapping, element);
        return mapping;
    }
    function createField(element) {
        if (element) {
            var jqe = $(element);
            var a = jqe.children("a").text();
            var b = jqe.children("b").text();
            var field = new Dozer.Field(new Dozer.FieldDefinition(a), new Dozer.FieldDefinition(b));
            copyAttributes(field, element);
            return field;
        }
        return new Dozer.Field(new Dozer.FieldDefinition(""), new Dozer.FieldDefinition(""));
    }
    function createMappingClass(jqElement) {
        if (jqElement && jqElement[0]) {
            var element = jqElement[0];
            var text = element.textContent;
            if (text) {
                var mappingClass = new Dozer.MappingClass(text);
                copyAttributes(mappingClass, element);
                return mappingClass;
            }
        }
        return new Dozer.MappingClass("");
    }
    function copyAttributes(object, element) {
        var attributeMap = element.attributes;
        for(var i = 0; i < attributeMap.length; i++) {
            var attMap = attributeMap;
            var attr = attMap.item(i);
            if (attr) {
                var name = attr.localName;
                var value = attr.value;
                if (name && !name.startsWith("xmlns")) {
                    var safeName = Forms.safeIdentifier(name);
                    object[safeName] = value;
                }
            }
        }
    }
    function appendAttributes(object, element, ignorePropertyNames) {
        angular.forEach(object, function (value, key) {
            if (ignorePropertyNames.any(key)) {
            } else {
                if (value) {
                    var text = value.toString();
                    var name = key.replace(/_/g, '-');
                    element.setAttribute(name, text);
                }
            }
        });
    }
    Dozer.appendAttributes = appendAttributes;
    function appendElement(object, element, elementName, indentLevel) {
        if (typeof elementName === "undefined") { elementName = null; }
        if (typeof indentLevel === "undefined") { indentLevel = 0; }
        var answer = null;
        if (angular.isArray(object)) {
            angular.forEach(object, function (child) {
                answer = appendElement(child, element, elementName, indentLevel);
            });
        } else if (object) {
            if (!elementName) {
                var className = Core.pathGet(object, [
                    "constructor", 
                    "name"
                ]);
                if (!className) {
                    console.log("WARNING: no class name for value " + object);
                } else {
                    elementName = Dozer.elementNameMappings[className];
                    if (!elementName) {
                        console.log("WARNING: could not map class name " + className + " to an XML element name");
                    }
                }
            }
            if (elementName) {
                if (indentLevel) {
                    var text = indentText(indentLevel);
                    Dozer.addTextNode(element, text);
                }
                var doc = element.ownerDocument || document;
                var child = doc.createElement(elementName);
                var fn = object.saveToElement;
                if (fn) {
                    fn.apply(object, [
                        child
                    ]);
                } else {
                    angular.forEach(object, function (value, key) {
                        console.log("has key " + key + " value " + value);
                    });
                }
                if ($(child).children().length) {
                    var text = indentText(indentLevel);
                    Dozer.addTextNode(child, text);
                }
                element.appendChild(child);
                answer = child;
            }
        }
        return answer;
    }
    Dozer.appendElement = appendElement;
    function nameOf(object) {
        var text = angular.isObject(object) ? object["value"] : null;
        if (!text && angular.isString(object)) {
            text = object;
        }
        return text || "?";
    }
    Dozer.nameOf = nameOf;
    function addTextNode(element, text) {
        if (text) {
            var doc = element.ownerDocument || document;
            var child = doc.createTextNode(text);
            element.appendChild(child);
        }
    }
    Dozer.addTextNode = addTextNode;
    function indentText(indentLevel) {
        var text = "\n";
        for(var i = 0; i < indentLevel; i++) {
            text += "  ";
        }
        return text;
    }
})(Dozer || (Dozer = {}));
var Dozer;
(function (Dozer) {
    var Mappings = (function () {
        function Mappings(doc, mappings) {
            if (typeof mappings === "undefined") { mappings = []; }
            this.doc = doc;
            this.mappings = mappings;
        }
        return Mappings;
    })();
    Dozer.Mappings = Mappings;    
    var Mapping = (function () {
        function Mapping() {
            this.fields = [];
            this.map_id = Core.getUUID();
            this.class_a = new MappingClass('');
            this.class_b = new MappingClass('');
        }
        Mapping.prototype.name = function () {
            return Dozer.nameOf(this.class_a) + " -> " + Dozer.nameOf(this.class_b);
        };
        Mapping.prototype.hasFromField = function (name) {
            return this.fields.find(function (f) {
                return name === f.a.value;
            });
        };
        Mapping.prototype.hasToField = function (name) {
            return this.fields.find(function (f) {
                return name === f.b.value;
            });
        };
        Mapping.prototype.saveToElement = function (element) {
            Dozer.appendElement(this.class_a, element, "class-a", 2);
            Dozer.appendElement(this.class_b, element, "class-b", 2);
            Dozer.appendElement(this.fields, element, "field", 2);
            Dozer.appendAttributes(this, element, [
                "class_a", 
                "class_b", 
                "fields"
            ]);
        };
        return Mapping;
    })();
    Dozer.Mapping = Mapping;    
    var MappingClass = (function () {
        function MappingClass(value) {
            this.value = value;
        }
        MappingClass.prototype.saveToElement = function (element) {
            Dozer.addTextNode(element, this.value);
            Dozer.appendAttributes(this, element, [
                "value", 
                "properties", 
                "error"
            ]);
        };
        return MappingClass;
    })();
    Dozer.MappingClass = MappingClass;    
    var Field = (function () {
        function Field(a, b) {
            this.a = a;
            this.b = b;
        }
        Field.prototype.name = function () {
            return Dozer.nameOf(this.a) + " -> " + Dozer.nameOf(this.b);
        };
        Field.prototype.saveToElement = function (element) {
            Dozer.appendElement(this.a, element, "a", 3);
            Dozer.appendElement(this.b, element, "b", 3);
            Dozer.appendAttributes(this, element, [
                "a", 
                "b"
            ]);
        };
        return Field;
    })();
    Dozer.Field = Field;    
    var FieldDefinition = (function () {
        function FieldDefinition(value) {
            this.value = value;
        }
        FieldDefinition.prototype.saveToElement = function (element) {
            Dozer.addTextNode(element, this.value);
            Dozer.appendAttributes(this, element, [
                "value", 
                "properties", 
                "error"
            ]);
        };
        return FieldDefinition;
    })();
    Dozer.FieldDefinition = FieldDefinition;    
    var UnmappedField = (function () {
        function UnmappedField(fromField, property, toField) {
            if (typeof toField === "undefined") { toField = null; }
            this.fromField = fromField;
            this.property = property;
            this.toField = toField;
        }
        return UnmappedField;
    })();
    Dozer.UnmappedField = UnmappedField;    
})(Dozer || (Dozer = {}));
var Dozer;
(function (Dozer) {
    function schemaConfigure() {
        io_hawt_dozer_schema_Field["tabs"] = {
            'Fields': [
                'a.value', 
                'b.value'
            ],
            'From Field': [
                'a\\..*'
            ],
            'To Field': [
                'b\\..*'
            ],
            'Field Configuration': [
                '*'
            ]
        };
        io_hawt_dozer_schema_Mapping["tabs"] = {
            'Classes': [
                'class-a.value', 
                'class-b.value'
            ],
            'From Class': [
                'class-a\\..*'
            ],
            'To Class': [
                'class-b\\..*'
            ],
            'Class Configuration': [
                '*'
            ]
        };
        io_hawt_dozer_schema_Mapping.properties.fieldOrFieldExclude.hidden = true;
        Core.pathSet(io_hawt_dozer_schema_Field, [
            "properties", 
            "a", 
            "properties", 
            "value", 
            "label"
        ], "From Field");
        Core.pathSet(io_hawt_dozer_schema_Field, [
            "properties", 
            "b", 
            "properties", 
            "value", 
            "label"
        ], "To Field");
        Core.pathSet(io_hawt_dozer_schema_Mapping, [
            "properties", 
            "class-a", 
            "properties", 
            "value", 
            "label"
        ], "From Class");
        Core.pathSet(io_hawt_dozer_schema_Mapping, [
            "properties", 
            "class-b", 
            "properties", 
            "value", 
            "label"
        ], "To Class");
        Core.pathSet(io_hawt_dozer_schema_Field, [
            "properties", 
            "a", 
            "ignorePrefixInLabel"
        ], true);
        Core.pathSet(io_hawt_dozer_schema_Field, [
            "properties", 
            "b", 
            "ignorePrefixInLabel"
        ], true);
        Core.pathSet(io_hawt_dozer_schema_Mapping, [
            "properties", 
            "class-a", 
            "ignorePrefixInLabel"
        ], true);
        Core.pathSet(io_hawt_dozer_schema_Mapping, [
            "properties", 
            "class-b", 
            "ignorePrefixInLabel"
        ], true);
        Core.pathSet(io_hawt_dozer_schema_Mapping, [
            "properties", 
            "class-a", 
            "properties", 
            "value", 
            "formTemplate"
        ], classNameWidget("class_a"));
        Core.pathSet(io_hawt_dozer_schema_Mapping, [
            "properties", 
            "class-b", 
            "properties", 
            "value", 
            "formTemplate"
        ], classNameWidget("class_b"));
        Core.pathSet(io_hawt_dozer_schema_Field, [
            "properties", 
            "a", 
            "properties", 
            "value", 
            "formTemplate"
        ], '<input type="text" ng-model="dozerEntity.a.value" ' + 'typeahead="title for title in fromFieldNames($viewValue) | filter:$viewValue" ' + 'typeahead-editable="true"  title="The Java class name"/>');
        Core.pathSet(io_hawt_dozer_schema_Field, [
            "properties", 
            "b", 
            "properties", 
            "value", 
            "formTemplate"
        ], '<input type="text" ng-model="dozerEntity.b.value" ' + 'typeahead="title for title in toFieldNames($viewValue) | filter:$viewValue" ' + 'typeahead-editable="true"  title="The Java class name"/>');
        function classNameWidget(propertyName) {
            return '<input type="text" ng-model="dozerEntity.' + propertyName + '.value" ' + 'typeahead="title for title in classNames($viewValue) | filter:$viewValue" ' + 'typeahead-editable="true"  title="The Java class name"/>';
        }
    }
    Dozer.schemaConfigure = schemaConfigure;
})(Dozer || (Dozer = {}));
var ES;
(function (ES) {
    ES.config = {
        elasticsearch: "http://" + window.location.hostname + ":9200",
        indice: "twitter",
        doctype: "tweet",
        query: "*"
    };
})(ES || (ES = {}));
var ES;
(function (ES) {
    function isEmptyObject(value) {
        return $.isEmptyObject(value);
    }
    ES.isEmptyObject = isEmptyObject;
    function SearchCtrl($scope, $location, $log, ejsResource) {
        var esServer = $scope.esServer = ES.config["elasticsearch"];
        var query = $scope.queryTerm = ES.config["query"];
        var facetField = $scope.facetField = "tags";
        var facetType = $scope.facetType = "terms";
        var index = $scope.indice = ES.config["indice"];
        var type = $scope.docType = ES.config["doctype"];
        var ejs;
        var request;
        $scope.log = $log;
        $scope.search = function () {
            if (isEmptyObject(ejs)) {
                console.log("Init EJS server");
                ejs = initElasticsearchServer(esServer);
            }
            setupEsRequest();
            request = request.query(ejs.QueryStringQuery(query));
            var results = request.doSearch();
            console.log("Do Elastic Search");
            results.then(function (results) {
                $scope.queryTerm = "";
                if (typeof results.error != 'undefined') {
                    console.error("ES error : " + results.error);
                    return;
                }
                console.log(results.hits.total + " : results retrieved");
                $scope.results = results;
            });
        };
        $scope.facetTermsSearch = function () {
            if (isEmptyObject(ejs)) {
                console.log("Init EJS server");
                ejs = initElasticsearchServer(esServer);
            }
            setupEsRequest();
            if (!isEmptyObject($scope.facetField)) {
                facetField = $scope.facetField;
            }
            if (!isEmptyObject($scope.facetType)) {
                facetType = $scope.facetType;
            }
            request = request.query(ejs.QueryStringQuery(query)).facet(ejs.TermsFacet("termFacet").field(facetField).size(50));
            var results = request.doSearch();
            console.log("Do Elastic Search");
            results.then(function (results) {
                $scope.queryTerm = "";
                if (typeof results.error != 'undefined') {
                    console.error("ES error : " + results.error);
                    return;
                }
                console.log(results.hits.total + " : results retrieved");
                $scope.results = results;
            });
        };
        $scope.facetDateHistogramSearch = function () {
            if (isEmptyObject(ejs)) {
                console.log("Init EJS server");
                ejs = initElasticsearchServer(esServer);
            }
            setupEsRequest();
            if (!isEmptyObject($scope.facetField)) {
                facetField = $scope.facetField;
            }
            if (!isEmptyObject($scope.facetType)) {
                facetType = $scope.facetType;
            }
            request = request.query(ejs.QueryStringQuery(query)).facet(ejs.DateHistogramFacet("dateHistoFacet").field(facetField).interval("minute"));
            var results = request.doSearch();
            console.log("Do Elastic Search");
            results.then(function (results) {
                $scope.queryTerm = "";
                if (typeof results.error != 'undefined') {
                    console.error("ES error : " + results.error);
                    return;
                }
                console.log(results.hits.total + " : results retrieved");
                $scope.results = results;
            });
        };
        $scope.indexSampleDocs = function () {
            var host = "http://" + location.host;
            if (isEmptyObject(ejs)) {
                console.log("EJS object is not defined - create it - setupEsRequest");
                ejs = initElasticsearchServer(esServer);
            }
            var docs = [];
            $.getJSON(host + "/hawtio/app/elasticsearch/js/data.json", function (result) {
                $.each(result, function (i, field) {
                    console.log("Field : " + field);
                    docs[i] = ejs.Document(index, type, i).source(field);
                    docs[i].refresh(true).doIndex();
                });
            });
        };
        function setupEsRequest() {
            console.log("ES Server = " + $scope.esServer);
            console.log("Indice = " + $scope.indice);
            console.log("Type = " + $scope.docType);
            console.log("Query = " + $scope.queryTerm);
            if (!isEmptyObject($scope.indice)) {
                index = $scope.indice;
            }
            if (!isEmptyObject($scope.esServer)) {
                esServer = $scope.esServer;
            }
            if (!isEmptyObject($scope.docType)) {
                type = $scope.docType;
            }
            if (!isEmptyObject($scope.queryTerm)) {
                query = $scope.queryTerm;
            }
            var ejs = ejsResource($scope.esServer);
            request = ejs.Request().indices(index).types(type);
            console.log("Request to call ElasticSearch defined");
        }
        function initElasticsearchServer(esServer) {
            return ejsResource(esServer);
        }
        $scope.parse_error = function (data) {
            var _error = data.match("nested: (.*?);");
            return _error == null ? data : _error[1];
        };
    }
    ES.SearchCtrl = SearchCtrl;
})(ES || (ES = {}));
var ES;
(function (ES) {
    var pluginEsName = 'elasticjs';
    var base_url = 'app/elasticsearch/html';
    angular.module(pluginEsName, [
        'bootstrap', 
        'ngResource', 
        'elasticjs.service', 
        'dangle'
    ]).config([
        '$routeProvider', 
        function ($routeProvider) {
            $routeProvider.when('/search', {
                templateUrl: base_url + '/search.html'
            }).when('/results', {
                templateUrl: base_url + '/results.html'
            }).when('/elasticjs', {
                templateUrl: base_url + '/es.html'
            });
        }    ]).run(function ($location, workspace, viewRegistry, helpRegistry) {
        viewRegistry['elasticjs'] = 'app/elasticsearch/html/es.html';
        helpRegistry.addUserDoc('elasticjs', 'app/elasticsearch/doc/help.md', function () {
            return false;
        });
    });
    hawtioPluginLoader.addModule(pluginEsName);
})(ES || (ES = {}));
var Fabric;
(function (Fabric) {
    function ActiveProfileController($scope, jolokia) {
        $scope.addToDashboardLink = function () {
            var href = "#/fabric/activeProfiles";
            var title = "Active Profiles";
            var size = angular.toJson({
                size_y: 1,
                size_x: 5
            });
            return "#/dashboard/add?tab=dashboard" + "&href=" + encodeURIComponent(href) + "&size=" + encodeURIComponent(size) + "&title=" + encodeURIComponent(title);
        };
    }
    Fabric.ActiveProfileController = ActiveProfileController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function FabricApisController($scope, localStorage, $routeParams, $location, jolokia, workspace, $compile, $templateCache) {
        $scope.path = "apis";
        Fabric.initScope($scope, $location, jolokia, workspace);
        $scope.apis = [];
        $scope.selectedApis = [];
        $scope.versionId = Fabric.getDefaultVersionId(jolokia);
        $scope.apiOptions = {
            data: 'apis',
            showFilter: false,
            showColumnMenu: false,
            filterOptions: {
                filterText: "",
                useExternalFilter: false
            },
            selectedItems: $scope.selectedApis,
            rowHeight: 32,
            selectWithCheckboxOnly: true,
            columnDefs: [
                {
                    field: 'service',
                    displayName: 'Service',
                    cellTemplate: '<div class="ngCellText">{{row.entity.service}}</div>',
                    width: "***"
                }, 
                {
                    field: 'wadlHref',
                    displayName: 'APIs',
                    cellTemplate: '<div class="ngCellText">' + '<a ng-show="row.entity.apidocsHref" ng-href="{{row.entity.apidocsHref}}"><i class="icon-puzzle-piece"></i> Swagger</a> ' + '<a ng-show="row.entity.wadlHref" ng-href="{{row.entity.wadlHref}}"><i class="icon-puzzle-piece"></i> WADL</a> ' + '<a ng-show="row.entity.wsdlHref" ng-href="{{row.entity.wsdlHref}}"><i class="icon-puzzle-piece"></i> WSDL</a>' + '</div>',
                    width: "*"
                }, 
                {
                    field: 'container',
                    displayName: 'Container',
                    cellTemplate: '<div class="ngCellText"><span fabric-container-link="{{row.entity.container}}"/></div>',
                    width: "*"
                }, 
                {
                    field: 'endpoint',
                    displayName: 'Location',
                    cellTemplate: '<div class="ngCellText">{{row.entity.endpoint}}</div>',
                    width: "***"
                }
            ]
        };
        function matchesFilter(text) {
            var filter = $scope.searchFilter;
            return !filter || (text && text.has(filter));
        }
        if (Fabric.fabricCreated(workspace)) {
            Core.register(jolokia, $scope, {
                type: 'exec',
                mbean: Fabric.managerMBean,
                operation: "clusterJson",
                arguments: [
                    $scope.path
                ]
            }, onSuccess(onClusterData));
        }
        function addObjectNameProperties(object) {
            var objectName = object["objectName"];
            if (objectName) {
                var properties = Core.objectNameProperties(objectName);
                if (properties) {
                    angular.forEach(properties, function (value, key) {
                        if (!object[key]) {
                            object[key] = value;
                        }
                    });
                }
            }
            return null;
        }
        function createFlatList(array, json, path) {
            if (typeof path === "undefined") { path = ""; }
            angular.forEach(json, function (value, key) {
                var childPath = path + "/" + key;
                function addParameters(href) {
                    angular.forEach([
                        "container", 
                        "objectName"
                    ], function (name) {
                        var param = value[name];
                        if (param) {
                            href += "&" + name + "=" + encodeURIComponent(param);
                        }
                    });
                    return href;
                }
                var services = value["services"];
                if (services && angular.isArray(services) && value["id"]) {
                    value["path"] = childPath;
                    if (services.length) {
                        var url = services[0];
                        value["endpoint"] = url;
                        addObjectNameProperties(value);
                        url = Core.useProxyIfExternal(url);
                        var apidocs = value["apidocs"];
                        var wadl = value["wadl"];
                        var wsdl = value["wsdl"];
                        if (apidocs) {
                            value["apidocsHref"] = addParameters("/hawtio-swagger/index.html?baseUri=" + url + apidocs);
                        }
                        if (wadl) {
                            value["wadlHref"] = addParameters("#/fabric/api/wadl?wadl=" + encodeURIComponent(url + wadl));
                        }
                        if (wsdl) {
                            value["wsdlHref"] = addParameters("#/fabric/api/wsdl?wsdl=" + encodeURIComponent(url + wsdl));
                        }
                    }
                    array.push(value);
                } else {
                    createFlatList(array, value, childPath);
                }
            });
        }
        function onClusterData(response) {
            if (response && response.value) {
                var responseJson = response.value;
                if ($scope.responseJson === responseJson) {
                    return;
                }
                $scope.responseJson = responseJson;
                try  {
                    var json = JSON.parse(responseJson);
                    $scope.apis = [];
                    createFlatList($scope.apis, json);
                    Core.$apply($scope);
                } catch (e) {
                    console.log("Failed to parse JSON " + e);
                    console.log("JSON: " + responseJson);
                }
            }
        }
    }
    Fabric.FabricApisController = FabricApisController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function AssignProfileController($scope, jolokia, $location, $routeParams, workspace) {
        $scope.profileId = $routeParams['pid'];
        $scope.versionId = $routeParams['vid'];
        Fabric.initScope($scope, $location, jolokia, workspace);
        $scope.containerIdFilter = '';
        var valid = true;
        if (Core.isBlank($scope.profileId)) {
            Fabric.log.warn("No profile ID specified, redirecting to Fabric management view");
            valid = false;
        }
        if (Core.isBlank($scope.versionId)) {
            Fabric.log.warn("No version ID specified, redirecting to Fabric management view");
            valid = false;
        }
        if (!valid) {
            $location.path("/fabric/view");
        }
        $scope.gotoCreate = function () {
            $location.path('/fabric/containers/createContainer').search({
                versionId: $scope.versionId,
                profileIds: $scope.profileId
            });
        };
        $scope.$on('$routeChangeSuccess', function () {
            Fabric.log.debug("RouteParams: ", $routeParams);
            Fabric.log.debug("Scope: ", $scope);
        });
        $scope.$watch('containers', function (newValue, oldValue) {
            if (newValue !== oldValue && newValue) {
                $scope.selected = newValue.filter(function (c) {
                    return c['selected'];
                });
            }
        }, true);
        $scope.assignProfiles = function () {
            var requests = [];
            $scope.selected.forEach(function (c) {
                requests.push({
                    type: 'exec',
                    mbean: Fabric.managerMBean,
                    operation: 'addProfilesToContainer',
                    arguments: [
                        c.id, 
                        [
                            $scope.profileId
                        ]
                    ]
                });
            });
            notification('info', "Applying " + $scope.profileId + " to the selected containers");
            var outstanding = requests.length;
            jolokia.request(requests, onSuccess(function () {
                outstanding = outstanding - 1;
                if (outstanding === 0) {
                    notification('success', "Applied " + $scope.profileId);
                    Core.$apply($scope);
                }
            }));
            setTimeout(function () {
                $location.path("/fabric/activeProfiles");
                Core.$apply($scope);
            }, 30);
        };
    }
    Fabric.AssignProfileController = AssignProfileController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function FabricBrokerDiagramController($scope, localStorage, $routeParams, $location, jolokia, workspace, $compile, $templateCache) {
        Fabric.initScope($scope, $location, jolokia, workspace);
        $scope.selectedNode = null;
        var defaultFlags = {
            panel: true,
            popup: false,
            label: true,
            group: false,
            profile: false,
            slave: false,
            broker: true,
            network: true,
            container: false,
            queue: true,
            topic: true,
            consumer: true,
            producer: true
        };
        $scope.viewSettings = {};
        $scope.shapeSize = {
            broker: 20,
            queue: 14,
            topic: 14
        };
        var graphBuilder = new ForceGraph.GraphBuilder();
        Core.bindModelToSearchParam($scope, $location, "searchFilter", "q", "");
        angular.forEach(defaultFlags, function (defaultValue, key) {
            var modelName = "viewSettings." + key;
            function currentValue() {
                var answer = $location.search()[paramName] || defaultValue;
                return answer === "false" ? false : answer;
            }
            var paramName = key;
            var value = currentValue();
            Core.pathSet($scope, modelName, value);
            $scope.$watch(modelName, function () {
                var current = Core.pathGet($scope, modelName);
                var old = currentValue();
                if (current !== old) {
                    var defaultValue = defaultFlags[key];
                    if (current !== defaultValue) {
                        if (!current) {
                            current = "false";
                        }
                        $location.search(paramName, current);
                    } else {
                        $location.search(paramName, null);
                    }
                }
                redrawGraph();
            });
        });
        $scope.$watch("selectedNode", function (newValue, oldValue) {
        });
        $scope.$watch("searchFilter", function (newValue, oldValue) {
            redrawGraph();
        });
        if (Fabric.hasMQManager) {
            Core.register(jolokia, $scope, {
                type: 'exec',
                mbean: Fabric.mqManagerMBean,
                operation: "loadBrokerStatus()"
            }, onSuccess(onBrokerData));
        }
        function onBrokerData(response) {
            if (response) {
                var responseJson = angular.toJson(response.value);
                if ($scope.responseJson === responseJson) {
                    return;
                }
                $scope.responseJson = responseJson;
                $scope.brokers = response.value;
                redrawGraph();
            }
        }
        function redrawGraph() {
            graphBuilder = new ForceGraph.GraphBuilder();
            var containersToDelete = $scope.activeContainers || {};
            $scope.activeContainers = {};
            angular.forEach($scope.brokers, function (brokerStatus) {
                brokerStatus.validContainer = brokerStatus.alive && brokerStatus.master && brokerStatus.provisionStatus === "success";
                renameTypeProperty(brokerStatus);
                var groupId = brokerStatus.group;
                var profileId = brokerStatus.profile;
                var brokerId = brokerStatus.brokerName;
                var containerId = brokerStatus.container;
                var versionId = brokerStatus.version || "1.0";
                var group = getOrAddNode("group", groupId, brokerStatus, function () {
                    return {
                        popup: {
                            title: "Broker Group: " + groupId,
                            content: "<p>" + groupId + "</p>"
                        }
                    };
                });
                var profile = getOrAddNode("profile", profileId, brokerStatus, function () {
                    return {
                        popup: {
                            title: "Profile: " + profileId,
                            content: "<p>" + profileId + "</p>"
                        }
                    };
                });
                var master = brokerStatus.master;
                var broker = null;
                var brokerFlag = master ? $scope.viewSettings.broker : $scope.viewSettings.slave;
                if (brokerFlag) {
                    broker = getOrAddNode("broker", brokerId, brokerStatus, function () {
                        return {
                            type: master ? "brokerMaster" : "broker",
                            popup: {
                                title: (master ? "Master" : "Slave") + " Broker: " + brokerId,
                                content: "<p>Container: " + containerId + "</p> <p>Group: " + groupId + "</p>"
                            }
                        };
                    });
                }
                var container = null;
                if (containerId) {
                    container = getOrAddNode("container", containerId, brokerStatus, function () {
                        return {
                            containerId: containerId,
                            popup: {
                                title: "Container: " + containerId,
                                content: "<p>" + containerId + " version: " + versionId + "</p>"
                            }
                        };
                    });
                }
                if (container && container.validContainer) {
                    var key = container.containerId;
                    $scope.activeContainers[key] = container;
                    delete containersToDelete[key];
                }
                if ($scope.viewSettings.group) {
                    if ($scope.viewSettings.profile) {
                        addLink(group, profile, "group");
                        addLink(profile, broker, "broker");
                    } else {
                        addLink(group, broker, "group");
                    }
                } else {
                    if ($scope.viewSettings.profile) {
                        addLink(profile, broker, "broker");
                    }
                }
                if (container) {
                    if ((master || $scope.viewSettings.slave) && $scope.viewSettings.container) {
                        addLink(broker, container, "container");
                        container.destinationLinkNode = container;
                    } else {
                        container.destinationLinkNode = broker;
                    }
                }
            });
            angular.forEach($scope.activeContainers, function (container, id) {
                var containerJolokia = container.jolokia;
                if (containerJolokia) {
                    onContainerJolokia(containerJolokia, container, id);
                } else {
                    Fabric.containerJolokia(jolokia, id, function (containerJolokia) {
                        return onContainerJolokia(containerJolokia, container, id);
                    });
                }
            });
            $scope.graph = graphBuilder.buildGraph();
            Core.$apply($scope);
        }
        function brokerNameMarkup(brokerName) {
            return brokerName ? "<p></p>broker: " + brokerName + "</p>" : "";
        }
        function onContainerJolokia(containerJolokia, container, id) {
            if (containerJolokia) {
                container.jolokia = containerJolokia;
                function getOrAddDestination(properties) {
                    var typeName = properties.destType;
                    var destinationName = properties.destinationName;
                    if (!destinationName || ($scope.searchFilter && destinationName.indexOf($scope.searchFilter) < 0)) {
                        return null;
                    }
                    var hideFlag = "topic" === typeName ? $scope.viewSettings.topic : $scope.viewSettings.queue;
                    if (!hideFlag) {
                        return null;
                    }
                    return getOrAddNode(typeName, destinationName, properties, function () {
                        return {
                            popup: {
                                title: (properties.destinationType || "Queue") + ": " + destinationName,
                                content: brokerNameMarkup(properties.brokerName)
                            }
                        };
                    });
                }
                var brokerId = container.brokerName;
                if (brokerId && $scope.viewSettings.network && $scope.viewSettings.broker) {
                    containerJolokia.request({
                        type: "read",
                        mbean: "org.apache.activemq:connector=networkConnectors,*"
                    }, onSuccess(function (response) {
                        angular.forEach(response.value, function (properties, objectName) {
                            var details = Core.parseMBean(objectName);
                            var attributes = details['attributes'];
                            if (properties) {
                                configureDestinationProperties(properties);
                                var remoteBrokerId = properties.RemoteBrokerName;
                                if (remoteBrokerId) {
                                    var brokerIdPrefix = "broker:";
                                    addLinkIds(brokerIdPrefix + brokerId, brokerIdPrefix + remoteBrokerId, "network");
                                }
                            }
                        });
                        graphModelUpdated();
                    }));
                }
                if ($scope.viewSettings.consumer) {
                    containerJolokia.search("org.apache.activemq:endpoint=Consumer,*", onSuccess(function (response) {
                        angular.forEach(response, function (objectName) {
                            var details = Core.parseMBean(objectName);
                            if (details) {
                                var properties = details['attributes'];
                                if (properties) {
                                    configureDestinationProperties(properties);
                                    var consumerId = properties.consumerId;
                                    if (consumerId) {
                                        var destination = getOrAddDestination(properties);
                                        if (destination) {
                                            addLink(container.destinationLinkNode, destination, "destination");
                                            var consumer = getOrAddNode("consumer", consumerId, properties, function () {
                                                return {
                                                    popup: {
                                                        title: "Consumer: " + consumerId,
                                                        content: "<p>client: " + (properties.clientId || "") + "</p> " + brokerNameMarkup(properties.brokerName)
                                                    }
                                                };
                                            });
                                            addLink(destination, consumer, "consumer");
                                        }
                                    }
                                }
                            }
                        });
                        graphModelUpdated();
                    }));
                }
                if ($scope.viewSettings.producer) {
                    containerJolokia.search("org.apache.activemq:endpoint=Producer,*", onSuccess(function (response) {
                        angular.forEach(response, function (objectName) {
                            var details = Core.parseMBean(objectName);
                            if (details) {
                                var properties = details['attributes'];
                                if (properties) {
                                    configureDestinationProperties(properties);
                                    var producerId = properties.producerId;
                                    if (producerId) {
                                        var destination = getOrAddDestination(properties);
                                        if (destination) {
                                            addLink(container.destinationLinkNode, destination, "destination");
                                            var producer = getOrAddNode("producer", producerId, properties, function () {
                                                return {
                                                    popup: {
                                                        title: "Producer: " + producerId,
                                                        content: "<p>client: " + (properties.clientId || "") + "</p> " + brokerNameMarkup(properties.brokerName)
                                                    }
                                                };
                                            });
                                            addLink(producer, destination, "producer");
                                        }
                                        graphModelUpdated();
                                    }
                                }
                            }
                        });
                        graphModelUpdated();
                    }));
                }
                if ($scope.viewSettings.producer) {
                    containerJolokia.request({
                        type: "read",
                        mbean: "org.apache.activemq:endpoint=dynamicProducer,*"
                    }, onSuccess(function (response) {
                        angular.forEach(response.value, function (mbeanValues, objectName) {
                            var details = Core.parseMBean(objectName);
                            var attributes = details['attributes'];
                            var properties = {};
                            angular.forEach(attributes, function (value, key) {
                                properties[key] = value;
                            });
                            angular.forEach(mbeanValues, function (value, key) {
                                properties[key] = value;
                            });
                            configureDestinationProperties(properties);
                            properties['destinationName'] = properties['DestinationName'];
                            var producerId = properties["producerId"] || properties["ProducerId"];
                            if (properties["DestinationTemporary"] || properties["DestinationTopc"]) {
                                properties["destType"] = "topic";
                            }
                            var destination = getOrAddDestination(properties);
                            if (producerId && destination) {
                                addLink(container.destinationLinkNode, destination, "destination");
                                var producer = getOrAddNode("producer", producerId, properties, function () {
                                    return {
                                        popup: {
                                            title: "Producer (Dynamic): " + producerId,
                                            content: "<p>client: " + (properties['ClientId'] || "") + "</p> " + brokerNameMarkup(properties['brokerName'])
                                        }
                                    };
                                });
                                addLink(producer, destination, "producer");
                            }
                        });
                        graphModelUpdated();
                    }));
                }
            }
        }
        function graphModelUpdated() {
            $scope.graph = graphBuilder.buildGraph();
            Core.$apply($scope);
        }
        function getOrAddNode(typeName, id, properties, createFn) {
            var node = null;
            if (id) {
                var nodeId = typeName + ":" + id;
                node = graphBuilder.getNode(nodeId);
                if (!node) {
                    var nodeValues = createFn();
                    node = angular.copy(properties);
                    angular.forEach(nodeValues, function (value, key) {
                        return node[key] = value;
                    });
                    node['id'] = nodeId;
                    if (!node['type']) {
                        node['type'] = typeName;
                    }
                    if (!node['name']) {
                        node['name'] = id;
                    }
                    if (node) {
                        var size = $scope.shapeSize[typeName];
                        if (size && !node['size']) {
                            node['size'] = size;
                        }
                        if (!node['summary']) {
                            node['summary'] = node['popup'] || "";
                        }
                        if (!$scope.viewSettings.popup) {
                            delete node['popup'];
                        }
                        if (!$scope.viewSettings.label) {
                            delete node['name'];
                        }
                        var enabled = $scope.viewSettings[typeName];
                        if (enabled || !angular.isDefined(enabled)) {
                            graphBuilder.addNode(node);
                        } else {
                        }
                    }
                }
            }
            return node;
        }
        function addLink(object1, object2, linkType) {
            if (object1 && object2) {
                addLinkIds(object1.id, object2.id, linkType);
            }
        }
        function addLinkIds(id1, id2, linkType) {
            if (id1 && id2) {
                graphBuilder.addLink(id1, id2, linkType);
            }
        }
        function renameTypeProperty(properties) {
            properties.mbeanType = properties['type'];
            delete properties['type'];
        }
        function configureDestinationProperties(properties) {
            renameTypeProperty(properties);
            var destinationType = properties.destinationType || "Queue";
            var typeName = destinationType.toLowerCase();
            properties.isQueue = !typeName.startsWith("t");
            properties['destType'] = typeName;
        }
    }
    Fabric.FabricBrokerDiagramController = FabricBrokerDiagramController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function FabricBrokersController($scope, localStorage, $routeParams, $location, jolokia, workspace, $compile, $templateCache) {
        Fabric.initScope($scope, $location, jolokia, workspace);
        $scope.maps = {
            group: {},
            profile: {},
            broker: {},
            container: {}
        };
        $scope.showBroker = function (broker) {
            var path = Fabric.profileLink(workspace, jolokia, localStorage, broker.version, broker.profile);
            path += "/org.fusesource.mq.fabric.server-" + broker.id + ".properties";
            $location.path(path);
        };
        $scope.connectToBroker = function (container, broker) {
            var view = "/jmx/attributes?tab=activemq";
            $scope.doConnect(container, view);
        };
        $scope.createBroker = function (group, profile) {
            var args = {};
            if (group) {
                var groupId = group["id"];
                if (groupId) {
                    args["group"] = groupId;
                }
            }
            if (profile) {
                var profileId = profile["id"];
                if (profileId) {
                    args["profile"] = profileId;
                }
            }
            $location.url("/fabric/mq/createBroker").search(args);
        };
        function matchesFilter(text) {
            var filter = $scope.searchFilter;
            return !filter || (text && text.has(filter));
        }
        $scope.groupMatchesFilter = function (group) {
            return matchesFilter(group.id) || group.profiles.find(function (item) {
                return $scope.profileMatchesFilter(item);
            });
        };
        $scope.profileMatchesFilter = function (profile) {
            return matchesFilter(profile.id) || matchesFilter(profile.group) || matchesFilter(profile.version) || profile.brokers.find(function (item) {
                return $scope.brokerMatchesFilter(item);
            });
        };
        $scope.brokerMatchesFilter = function (broker) {
            return matchesFilter(broker.id) || matchesFilter(broker.group) || matchesFilter(broker.version) || broker.containers.find(function (item) {
                return $scope.containerMatchesFilter(item);
            });
        };
        $scope.containerMatchesFilter = function (container) {
            return matchesFilter(container.id) || matchesFilter(container.group) || matchesFilter(container.profile) || matchesFilter(container.version) || matchesFilter(container.brokerName) || (container.master && $scope.searchFilter && $scope.searchFilter.has("master"));
        };
        if (Fabric.hasMQManager) {
            Core.register(jolokia, $scope, {
                type: 'exec',
                mbean: Fabric.mqManagerMBean,
                operation: "loadBrokerStatus()"
            }, onSuccess(onBrokerData));
        }
        function onBrokerData(response) {
            if (response) {
                var responseJson = angular.toJson(response.value);
                if ($scope.responseJson === responseJson) {
                    return;
                }
                $scope.responseJson = responseJson;
                var brokers = response.value;
                function findByIdOrCreate(collection, id, map, fn) {
                    var value = collection.find({
                        "id": id
                    });
                    if (!value) {
                        value = fn();
                        value["id"] = id;
                        collection.push(value);
                        var old = map[id];
                        value["expanded"] = old ? old["expanded"] : true;
                        map[id] = value;
                    }
                    return value;
                }
                $scope.groups = [];
                var maps = $scope.maps;
                angular.forEach(brokers, function (brokerStatus) {
                    var groupId = brokerStatus.group || "Unknown";
                    var profileId = brokerStatus.profile || "Unknown";
                    var brokerId = brokerStatus.brokerName || "Unknown";
                    var containerId = brokerStatus.container;
                    var versionId = brokerStatus.version || "1.0";
                    var group = findByIdOrCreate($scope.groups, groupId, maps.group, function () {
                        return {
                            profiles: []
                        };
                    });
                    var profile = findByIdOrCreate(group.profiles, profileId, maps.profile, function () {
                        return {
                            group: groupId,
                            version: versionId,
                            requirements: {
                                minimumInstances: brokerStatus.minimumInstances
                            },
                            brokers: [],
                            containers: {}
                        };
                    });
                    var connectTo = (brokerStatus.networks || []).join(",");
                    var broker = findByIdOrCreate(profile.brokers, brokerId, maps.broker, function () {
                        return {
                            group: groupId,
                            profile: profileId,
                            version: versionId,
                            containers: [],
                            connectTo: connectTo
                        };
                    });
                    if (containerId) {
                        var container = findByIdOrCreate(broker.containers, containerId, maps.container, function () {
                            return brokerStatus;
                        });
                        if (container.master) {
                            container.masterTooltip = " is the master for broker: " + brokerId;
                        }
                        profile.containers[containerId] = container;
                    }
                });
                angular.forEach($scope.groups, function (group) {
                    angular.forEach(group.profiles, function (profile) {
                        angular.forEach(profile.brokers, function (broker) {
                            broker.containers = broker.containers.sortBy(function (c) {
                                return c.id;
                            });
                        });
                        var count = Object.values(profile.containers).length;
                        var required = profile.requirements.minimumInstances || 0;
                        profile.requireStyle = Fabric.containerCountBadgeStyle(required, count);
                        profile.count = count;
                        profile.requiredToolTip = "this profile requires " + Core.maybePlural(required, "container") + " to be running but is currently running " + Core.maybePlural(count, "container");
                        if (required > count) {
                            profile.requiredToolTip += ". click here to create more containers";
                        }
                    });
                });
                Core.$apply($scope);
            }
        }
    }
    Fabric.FabricBrokersController = FabricBrokersController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function ClusterController($scope, $location, $routeParams, workspace, jolokia) {
        $scope.path = $routeParams["page"] || "/";
        if (!$scope.path.startsWith("/")) {
            $scope.path = "/" + $scope.path;
        }
        $scope.gridOptions = {
            data: 'children',
            displayFooter: false,
            sortInfo: {
                fields: [
                    'name'
                ],
                directions: [
                    'asc'
                ]
            },
            columnDefs: [
                {
                    field: 'name',
                    displayName: 'Name',
                    cellTemplate: '<div class="ngCellText"><a href="{{childLink(row.entity)}}"><i class="{{row | fileIconClass}}"></i> {{row.getProperty(col.field)}}</a></div>',
                    cellFilter: ""
                }
            ]
        };
        $scope.isTabActive = function (href) {
            var tidy = Core.trimLeading(href, "#");
            var loc = $location.path();
            return loc === tidy;
        };
        $scope.childLink = function (child) {
            var prefix = "#/fabric/clusters/" + Core.trimLeading($scope.path, "/") + "/";
            var postFix = "";
            var path = child.name;
            return Core.createHref($location, prefix + path + postFix);
        };
        $scope.$watch('workspace.tree', function () {
            setTimeout(updateView, 50);
        });
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateView, 50);
        });
        updateView();
        function updateView() {
            loadBreadcrumbs();
            var mbean = Fabric.getZooKeeperFacadeMBean(workspace);
            if (mbean) {
                jolokia.execute(mbean, "read", $scope.path, onSuccess(onContents));
            }
        }
        function onContents(contents) {
            $scope.children = [];
            $scope.stringData = null;
            $scope.html = null;
            if (contents) {
                angular.forEach(contents.children, function (childName) {
                    $scope.children.push({
                        name: childName
                    });
                });
                if (!$scope.children.length) {
                    var stringData = contents.stringData;
                    if (stringData) {
                        $scope.stringData = stringData;
                        var json = Core.tryParseJson(stringData);
                        if (json) {
                            $scope.html = Core.valueToHtml(json);
                        } else {
                            $scope.html = stringData;
                        }
                    }
                }
            }
            Core.$apply($scope);
        }
        function loadBreadcrumbs() {
            var href = "#/fabric/clusters";
            $scope.breadcrumbs = [
                {
                    href: href + "/",
                    name: "/"
                }
            ];
            var path = $scope.path;
            var array = path ? path.split("/") : [];
            angular.forEach(array, function (name) {
                if (name) {
                    if (!name.startsWith("/") && !href.endsWith("/")) {
                        href += "/";
                    }
                    href += name;
                    $scope.breadcrumbs.push({
                        href: href,
                        name: name
                    });
                }
            });
        }
    }
    Fabric.ClusterController = ClusterController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function ContainerController($scope, $routeParams, $location, localStorage, jolokia, workspace, userDetails) {
        Fabric.initScope($scope, $location, jolokia, workspace);
        if ($scope.inDashboard) {
            $scope.operation = 'getContainer(java.lang.String, java.util.List)';
        } else {
            $scope.operation = 'getContainer(java.lang.String)';
        }
        $scope.username = userDetails.username;
        $scope.password = userDetails.password;
        $scope.tab = $routeParams['tab'];
        if (!$scope.tab) {
            $scope.tab = 'Status';
        }
        $scope.$watch('tab', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $location.search({
                    tab: newValue
                }).replace();
            }
        });
        $scope.loading = true;
        $scope.containerId = $routeParams.containerId;
        $scope.addToDashboardLink = function () {
            var href = "#/fabric/container/:containerId";
            var routeParams = angular.toJson($routeParams);
            var title = $scope.containerId;
            return "#/dashboard/add?tab=dashboard&href=" + encodeURIComponent(href) + "&routeParams=" + encodeURIComponent(routeParams) + "&title=" + encodeURIComponent(title);
        };
        $scope.selectedProfiles = [];
        $scope.selectedProfilesDialog = [];
        $scope.selectedProfilesString = '';
        $scope.addProfileDialog = new Core.Dialog();
        $scope.deleteProfileDialog = new Core.Dialog();
        $scope.$watch('selectedProfiles', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $scope.selectedProfilesString = '';
                $scope.selectedProfiles.each(function (p) {
                    $scope.selectedProfilesString += '<li>' + p.id + '</li>\n';
                });
            }
        }, true);
        $scope.stop = function () {
            Fabric.doStopContainer($scope, jolokia, $scope.containerId);
        };
        $scope.delete = function () {
            Core.unregister(jolokia, $scope);
            Fabric.doDeleteContainer($scope, jolokia, $scope.containerId, function () {
                $location.path('/fabric/containers');
            });
        };
        $scope.start = function () {
            Fabric.doStartContainer($scope, jolokia, $scope.containerId);
        };
        $scope.statusIcon = function () {
            return Fabric.statusIcon($scope.row);
        };
        $scope.getGitURL = function (jolokiaUrl) {
            var answer = jolokiaUrl ? jolokiaUrl.replace("jolokia", "git/fabric") : null;
            if (answer !== null) {
                var command = "git clone -b 1.0 " + answer;
                if ($scope.username !== null && $scope.password !== null) {
                    command = command.replace("://", "://" + $scope.username + ":" + $scope.password + "@");
                }
                answer = command;
            }
            return answer;
        };
        $scope.getSshURL = function (sshUrl) {
            if (!sshUrl) {
                return '';
            }
            var answer = sshUrl;
            if ($scope.username !== null && $scope.password !== null) {
                var parts = sshUrl.split(":");
                if (parts.length === 2) {
                    answer = "ssh -p " + parts[1] + " " + $scope.username + "@" + parts[0];
                }
            }
            return answer;
        };
        $scope.getJmxURL = function (jmxUrl) {
            return jmxUrl;
        };
        $scope.getType = function () {
            if ($scope.row) {
                if ($scope.row.ensembleServer) {
                    return "Fabric Server";
                } else if ($scope.row.managed) {
                    return "Managed Container";
                } else {
                    return "Unmanaged Container";
                }
            }
            return "";
        };
        $scope.updateContainerProperty = function (propertyName, row) {
            Fabric.setContainerProperty(jolokia, row.id, propertyName, row[propertyName], function () {
                $;
                Core.$apply($scope);
            }, function (response) {
                notification('error', 'Failed to set container property due to : ' + response.error);
                Core.$apply($scope);
            });
        };
        $scope.getClass = function (item) {
            if (!$scope.provisionListFilter) {
                return 'no-filter';
            } else if (item.has($scope.provisionListFilter)) {
                return 'match-filter';
            } else {
                return 'no-match-filter';
            }
        };
        $scope.addProfiles = function () {
            $scope.addProfileDialog.close();
            var addedProfiles = $scope.selectedProfilesDialog.map(function (p) {
                return p.id;
            });
            var text = Core.maybePlural(addedProfiles.length, "profile");
            Fabric.addProfilesToContainer(jolokia, $scope.row.id, addedProfiles, function () {
                notification('success', "Successfully added " + text);
                $scope.selectedProfilesDialog = [];
                $scope.$broadcast('fabricProfileRefresh');
                Core.$apply($scope);
            }, function (response) {
                notification('error', "Failed to add " + text + " due to " + response.error);
                $scope.selectedProfilesDialog = [];
                Core.$apply($scope);
            });
        };
        $scope.showChangeVersionDialog = function () {
            $scope.changeVersionDialog.open([
                $scope.container
            ]);
        };
        $scope.getArguments = function () {
            if ($scope.inDashboard) {
                return [
                    $scope.containerId, 
                    [
                        'id', 
                        'versionId', 
                        'profileIds', 
                        'provisionResult', 
                        'jolokiaUrl', 
                        'alive', 
                        'jmxDomains', 
                        'ensembleServer'
                    ]
                ];
            }
            return [
                $scope.containerId
            ];
        };
        $scope.deleteProfiles = function () {
            $scope.deleteProfileDialog.close();
            var removedProfiles = $scope.selectedProfiles.map(function (p) {
                return p.id;
            });
            var text = Core.maybePlural(removedProfiles.length, "profile");
            Fabric.removeProfilesFromContainer(jolokia, $scope.row.id, removedProfiles, function () {
                notification('success', "Successfully removed " + text);
                $scope.selectedProfiles = [];
                $scope.$broadcast('fabricProfileRefresh');
                Core.$apply($scope);
            }, function (response) {
                notification('error', "Failed to remove " + text + " due to " + response.error);
                $scope.selectedProfiles = [];
                Core.$apply($scope);
            });
        };
        $scope.$on("fabricProfileRefresh", function () {
            setTimeout(function () {
                jolokia.request({
                    type: 'exec',
                    mbean: Fabric.managerMBean,
                    operation: $scope.operation,
                    arguments: $scope.getArguments()
                }, {
                    method: 'POST',
                    success: function (response) {
                        render(response);
                    }
                });
            }, 500);
        });
        if (angular.isDefined($scope.containerId)) {
            Core.register(jolokia, $scope, {
                type: 'exec',
                mbean: Fabric.managerMBean,
                operation: $scope.operation,
                arguments: $scope.getArguments()
            }, onSuccess(render));
        }
        $scope.formatStackTrace = function (exception) {
            return Log.formatStackTrace(exception);
        };
        function render(response) {
            if (!angular.isDefined($scope.responseJson)) {
                $scope.loading = false;
            }
            var responseJson = angular.toJson(response.value);
            if ($scope.responseJson !== responseJson) {
                $scope.responseJson = responseJson;
                $scope.row = response.value;
                $scope.container = $scope.row;
                if ($scope.row) {
                    if (angular.isDefined($scope.row.provisionException) && angular.isString($scope.row.provisionException)) {
                        $scope.row.provisionExceptionArray = $scope.row.provisionException.lines();
                    }
                    $scope.services = Fabric.getServiceList($scope.row);
                    if (angular.isDefined($scope.resolverWatch) && angular.isFunction($scope.resolverWatch)) {
                        $scope.resolverWatch();
                    }
                    $scope.resolverWatch = $scope.$watch('row.resolver', function (newValue, oldValue) {
                        if (newValue !== oldValue) {
                            $scope.updateContainerProperty('resolver', $scope.row);
                        }
                    });
                }
                Core.$apply($scope);
            }
        }
    }
    Fabric.ContainerController = ContainerController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    var ContainerList = (function () {
        function ContainerList() {
            this.restrict = 'A';
            this.replace = true;
            this.templateUrl = Fabric.templatePath + "containerList.html";
            this.scope = false;
            this.link = function ($scope, $element, $attrs) {
                $scope.showSelect = Core.parseBooleanValue(UI.getIfSet('showSelect', $attrs, 'true'));
                var atVersion = UI.getIfSet('atVersion', $attrs, null);
                var withoutProfile = UI.getIfSet('withoutProfile', $attrs, null);
                if (atVersion !== null) {
                    $scope.atVersion = $scope.$eval(atVersion);
                }
                if (withoutProfile !== null) {
                    $scope.withoutProfile = $scope.$eval(withoutProfile);
                }
                Fabric.log.debug("atVersion: ", $scope.atVersion);
                Fabric.log.debug("withoutProfile: ", $scope.withoutProfile);
                Fabric.log.debug("container list attributes: ", $attrs);
            };
        }
        ContainerList.prototype.controller = function ($scope, $element, $attrs, jolokia, $location, workspace, $templateCache) {
            $scope.containerArgs = [
                "id", 
                "alive", 
                "parentId", 
                "profileIds", 
                "versionId", 
                "provisionResult", 
                "jolokiaUrl", 
                "root", 
                'jmxDomains'
            ];
            $scope.profileFields = [
                "id", 
                "hidden"
            ];
            $scope.containersOp = 'containers(java.util.List, java.util.List)';
            $scope.ensembleContainerIdListOp = 'EnsembleContainers';
            $scope.containers = [];
            $scope.activeProfiles = [];
            $scope.selectedContainers = [];
            $scope.selectedContainerIds = [];
            $scope.showSelect = true;
            $scope.requirements = null;
            Fabric.initScope($scope, $location, jolokia, workspace);
            $scope.currentPage = $templateCache.get("addProfileRequirements");
            $scope.editRequirements = {
                dialog: new Core.Dialog(),
                excludeProfiles: [],
                selectedProfiles: [],
                excludeDependentProfiles: [],
                selectedDependentProfiles: [],
                addDependentProfileDialog: new Core.Dialog(),
                versionId: null,
                addProfileSelectShow: false,
                dialogOpen: function (profile) {
                    var editRequirementsEntity = {
                        profileRequirements: []
                    };
                    if ($scope.requirements) {
                        angular.copy($scope.requirements, editRequirementsEntity);
                    }
                    var profileRequirements = editRequirementsEntity.profileRequirements;
                    if (profileRequirements) {
                        angular.forEach($scope.activeProfiles, function (profile) {
                            var currentRequirements = profile.requirements;
                            if (!currentRequirements) {
                                currentRequirements = {
                                    profile: profile.id
                                };
                                profile.requirements = currentRequirements;
                                profileRequirements.push(currentRequirements);
                            }
                        });
                    }
                    if (!profile && $scope.activeProfiles.length) {
                        profile = $scope.activeProfiles[0];
                    }
                    if (profile) {
                        $scope.editRequirements.versionId = profile.versionId;
                    }
                    $scope.editRequirements.entity = editRequirementsEntity;
                    $scope.editRequirements.dialog.open();
                },
                addDependentProfileDialogOpen: function (requirement) {
                    $scope.editRequirements.addDependentProfileDialogProfile = requirement.profile;
                    $scope.editRequirements.selectedDependentProfiles.splice(0, $scope.editRequirements.selectedDependentProfiles.length);
                    $scope.editRequirements.excludeDependentProfiles = [
                        requirement.profile
                    ].concat(requirement.dependentProfiles || []);
                    $scope.editRequirements.addDependentProfilesToRequirement = requirement;
                    $scope.editRequirements.addDependentProfileDialogShow = true;
                },
                addDependentProfileDialogHide: function () {
                    $scope.editRequirements.addDependentProfileDialogShow = false;
                },
                addDependentProfileDialogApply: function () {
                    var requirement = $scope.editRequirements.addDependentProfilesToRequirement;
                    angular.forEach($scope.editRequirements.selectedDependentProfiles, function (profile) {
                        var id = profile.id;
                        if (id && requirement) {
                            if (!requirement.dependentProfiles) {
                                requirement.dependentProfiles = [];
                            }
                            if (!requirement.dependentProfiles.find(id)) {
                                requirement.dependentProfiles.push(id);
                            }
                        }
                    });
                    $scope.editRequirements.addDependentProfileDialogHide();
                },
                addProfileRequirementOpen: function () {
                    $scope.editRequirements.selectedProfiles.splice(0, $scope.editRequirements.selectedProfiles.length);
                    $scope.editRequirements.excludeProfiles = $scope.activeProfiles.map(function (p) {
                        return p.id;
                    });
                    $scope.editRequirements.addProfileRequirementShow = true;
                },
                addProfileRequirementHide: function () {
                    $scope.editRequirements.addProfileRequirementShow = false;
                },
                addProfileRequirementApply: function () {
                    var entity = $scope.editRequirements.entity;
                    var profileRequirements = entity.profileRequirements;
                    if (!profileRequirements) {
                        profileRequirements = [];
                        entity.profileRequirements = profileRequirements;
                    }
                    angular.forEach($scope.editRequirements.selectedProfiles, function (profile) {
                        var id = profile.id;
                        if (id) {
                            profileRequirements.push({
                                profile: id
                            });
                        }
                    });
                    $scope.editRequirements.addProfileRequirementHide();
                }
            };
            $scope.getFilteredName = function (item) {
                return item.versionId + " / " + item.id;
            };
            $scope.filterContainer = function (container) {
                var filterText = $scope.containerIdFilter;
                if (filterText && !$scope.getFilteredName(container).has(filterText)) {
                    var profileIds = container.profileIds;
                    if (profileIds) {
                        return profileIds.any(function (id) {
                            return id.indexOf(filterText) >= 0;
                        });
                    }
                    return false;
                }
                return true;
            };
            $scope.$watch('editRequirements.addDependentProfileDialogShow', function (newValue, oldValue) {
                if (newValue !== oldValue) {
                    if (newValue) {
                        $scope.currentPage = $templateCache.get("addDependentProfile");
                    } else {
                        $scope.currentPage = $templateCache.get("addProfileRequirements");
                    }
                }
            });
            $scope.$watch('editRequirements.addProfileRequirementShow', function (newValue, oldValue) {
                if (newValue !== oldValue) {
                    if (newValue) {
                        $scope.currentPage = $templateCache.get("addProfileRequirement");
                    } else {
                        $scope.currentPage = $templateCache.get("addProfileRequirements");
                    }
                }
            });
            $scope.updateActiveContainers = function () {
                var activeProfiles = $scope.activeProfiles;
                $scope.activeProfiles = $scope.currentActiveProfiles();
                $scope.activeProfiles.each(function (activeProfile) {
                    var ap = activeProfiles.find(function (ap) {
                        return ap.id === activeProfile.id && ap.versionId === activeProfile.versionId;
                    });
                    if (ap) {
                        activeProfile['selected'] = ap.selected;
                        activeProfile['expanded'] = ap.expanded;
                    } else {
                        activeProfile['selected'] = false;
                        activeProfile['expanded'] = false;
                    }
                });
            };
            $scope.updateContainers = function (newContainers) {
                var response = angular.toJson(newContainers);
                if ($scope.containersResponse !== response) {
                    $scope.containersResponse = response;
                    var rootContainers = newContainers.exclude(function (c) {
                        return !c.root;
                    });
                    var childContainers = newContainers.exclude(function (c) {
                        return c.root;
                    });
                    if (childContainers.length > 0) {
                        var tmp = [];
                        rootContainers = rootContainers.sortBy('id');
                        rootContainers.each(function (c) {
                            tmp.add(c);
                            var children = childContainers.exclude(function (child) {
                                return child.parentId !== c.id;
                            });
                            tmp.add(children.sortBy('id'));
                        });
                        newContainers = tmp;
                    }
                    if (angular.isDefined($scope.atVersion)) {
                        newContainers = newContainers.filter(function (c) {
                            return c.versionId === $scope.atVersion;
                        });
                    }
                    if (angular.isDefined($scope.withoutProfile)) {
                        newContainers = newContainers.filter(function (c) {
                            return !c.profileIds.any(function (p) {
                                return p === $scope.withoutProfile;
                            });
                        });
                    }
                    newContainers.each(function (container) {
                        container.services = Fabric.getServiceList(container);
                        var c = $scope.containers.find(function (c) {
                            return c.id === container.id;
                        });
                        if (c) {
                            container['selected'] = c.selected;
                        } else {
                            container['selected'] = false;
                        }
                        if ($scope.selectedContainerIds.any(container.id)) {
                            container.selected = true;
                        }
                    });
                    $scope.containers = newContainers;
                    $scope.updateActiveContainers();
                    Core.$apply($scope);
                }
            };
            $scope.currentActiveProfiles = function () {
                var answer = [];
                $scope.containers.each(function (container) {
                    container.profileIds.each(function (profile) {
                        var p = container.profiles.find(function (p) {
                            return p.id === profile;
                        });
                        if (p && p.hidden) {
                            return;
                        }
                        var activeProfile = answer.find(function (o) {
                            return o.versionId === container.versionId && o.id === profile;
                        });
                        if (activeProfile) {
                            activeProfile.containers = activeProfile.containers.include(container.id).unique();
                            activeProfile.count = activeProfile.containers.length;
                        } else {
                            answer.push({
                                id: profile,
                                count: 1,
                                versionId: container.versionId,
                                containers: [
                                    container.id
                                ],
                                selected: false,
                                requirements: null,
                                requireStyle: null
                            });
                        }
                    });
                });
                if ($scope.requirements) {
                    angular.forEach($scope.requirements.profileRequirements, function (profileRequirement) {
                        var id = profileRequirement.profile;
                        var min = profileRequirement.minimumInstances;
                        if (id) {
                            var profile = answer.find({
                                id: id
                            });
                            function requireStyle() {
                                var count = 0;
                                if (profile) {
                                    count = profile['count'];
                                }
                                return Fabric.containerCountBadgeStyle(min, count);
                            }
                            if (profile) {
                                profile["requirements"] = profileRequirement;
                                profile["requireStyle"] = requireStyle();
                            } else {
                                answer.push({
                                    id: id,
                                    count: 0,
                                    versionId: $scope.requirements.version || "1.0",
                                    containers: [],
                                    selected: false,
                                    requirements: profileRequirement,
                                    requireStyle: requireStyle()
                                });
                            }
                        }
                    });
                }
                return answer;
            };
            $scope.updateEnsembleContainerIdList = function (ids) {
                var response = angular.toJson(ids);
                if ($scope.ensembleContainerIdsResponse !== response) {
                    $scope.ensembleContainerIdsResponse = response;
                    $scope.ensembleContainerIds = ids;
                    Core.$apply($scope);
                }
            };
            $scope.dispatch = function (response) {
                switch(response.request.operation) {
                    case ($scope.containersOp):
                        $scope.updateContainers(response.value);
                        return;
                }
                switch(response.request.attribute) {
                    case ($scope.ensembleContainerIdListOp):
                        $scope.updateEnsembleContainerIdList(response.value);
                        return;
                }
            };
            $scope.clearSelection = function (group) {
                group.each(function (item) {
                    item.selected = false;
                });
            };
            $scope.setActiveProfile = function (profile) {
                $scope.clearSelection($scope.activeProfiles);
                if (!profile || profile === null) {
                    return;
                }
                profile.selected = true;
            };
            $scope.selectAllContainers = function () {
                $scope.containers.each(function (container) {
                    if ($scope.filterContainer(container)) {
                        container.selected = true;
                    }
                });
            };
            $scope.setActiveContainer = function (container) {
                $scope.clearSelection($scope.containers);
                if (!container || container === null) {
                    return;
                }
                container.selected = true;
            };
            $scope.deleteSelectedContainers = function () {
                $scope.selectedContainers.each(function (c) {
                    $scope.deleteContainer(c.id);
                });
            };
            $scope.startSelectedContainers = function () {
                $scope.selectedContainers.each(function (c) {
                    $scope.startContainer(c.id);
                });
            };
            $scope.stopSelectedContainers = function () {
                $scope.selectedContainers.each(function (c) {
                    $scope.stopContainer(c.id);
                });
            };
            $scope.deleteContainer = function (name) {
                Fabric.doDeleteContainer($scope, jolokia, name);
            };
            $scope.startContainer = function (name) {
                Fabric.doStartContainer($scope, jolokia, name);
            };
            $scope.stopContainer = function (name) {
                Fabric.doStopContainer($scope, jolokia, name);
            };
            $scope.anySelectionAlive = function (state) {
                var selected = $scope.selectedContainers;
                return selected.length > 0 && selected.any(function (s) {
                    return s.alive === state;
                });
            };
            $scope.everySelectionAlive = function (state) {
                var selected = $scope.selectedContainers;
                return selected.length > 0 && selected.every(function (s) {
                    return s.alive === state;
                });
            };
            Core.register(jolokia, $scope, [
                {
                    type: 'exec',
                    mbean: Fabric.managerMBean,
                    operation: $scope.containersOp,
                    arguments: [
                        $scope.containerArgs, 
                        $scope.profileFields
                    ]
                }, 
                {
                    type: 'read',
                    mbean: Fabric.clusterManagerMBean,
                    attribute: $scope.ensembleContainerIdListOp
                }
            ], onSuccess($scope.dispatch));
        };
        return ContainerList;
    })();
    Fabric.ContainerList = ContainerList;    
    var ActiveProfileList = (function (_super) {
        __extends(ActiveProfileList, _super);
        function ActiveProfileList() {
            _super.apply(this, arguments);

            this.templateUrl = Fabric.templatePath + "activeProfileList.html";
        }
        ActiveProfileList.prototype.controller = function ($scope, $element, $attrs, jolokia, $location, workspace, $templateCache) {
            _super.prototype.controller.call(this, $scope, $element, $attrs, jolokia, $location, workspace, $templateCache);
            $scope.searchFilter = '';
            $scope.isOpen = function (profile) {
                if ($scope.searchFilter !== '') {
                    return "opened";
                }
                return "closed";
            };
            $scope.containersForProfile = function (id) {
                return $scope.containers.filter(function (container) {
                    return container.profileIds.some(id);
                });
            };
            $scope.profileMatchesFilter = function (profile) {
                return profile.id.has($scope.searchFilter) || !profile.containers.filter(function (id) {
                    return id.has($scope.searchFilter);
                }).isEmpty();
            };
            $scope.containerMatchesFilter = function (container) {
                return container.id.has($scope.searchFilter) || !container.profileIds.filter(function (id) {
                    return id.has($scope.searchFilter);
                }).isEmpty();
            };
            $scope.updateRequirements = function (requirements) {
                function onRequirementsSaved(response) {
                    $scope.requirements = requirements;
                    notification("success", "Updated the requirements");
                    $scope.updateActiveContainers();
                    Core.$apply($scope);
                }
                ;
                if (requirements) {
                    $scope.editRequirements.dialog.close();
                    var json = JSON.stringify(requirements);
                    jolokia.execute(Fabric.managerMBean, "requirementsJson", json, onSuccess(onRequirementsSaved));
                }
            };
            function onRequirements(response) {
                var responseJson = angular.toJson(response.value);
                if (responseJson !== $scope.requirementsResponse) {
                    $scope.requirementsResponse = responseJson;
                    $scope.requirements = response.value;
                    $scope.updateActiveContainers();
                    Core.$apply($scope);
                }
            }
            Core.register(jolokia, $scope, {
                type: 'exec',
                mbean: Fabric.managerMBean,
                operation: "requirements()"
            }, onSuccess(onRequirements));
        };
        return ActiveProfileList;
    })(Fabric.ContainerList);
    Fabric.ActiveProfileList = ActiveProfileList;    
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function ContainersController($scope, $location, $route, jolokia, workspace) {
        Fabric.initScope($scope, $location, jolokia, workspace);
        Core.bindModelToSearchParam($scope, $location, "containerIdFilter", "q", "");
        Core.reloadWhenParametersChange($route, $scope, $location);
        $scope.addToDashboardLink = function () {
            var href = "#/fabric/containers";
            var title = "Containers";
            var size = angular.toJson({
                size_y: 1,
                size_x: 4
            });
            return "#/dashboard/add?tab=dashboard" + "&href=" + encodeURIComponent(href) + "&size=" + encodeURIComponent(size) + "&title=" + encodeURIComponent(title);
        };
        $scope.$watch('containers', function (oldValue, newValue) {
            if (oldValue !== newValue) {
                $scope.selectedContainers = $scope.containers.filter(function (c) {
                    return c.selected;
                });
                if ($scope.selectedContainers.length > 0) {
                    $scope.activeContainerId = '';
                }
            }
        }, true);
        $scope.showChangeVersionDialog = function () {
            $scope.changeVersionDialog.open($scope.selectedContainers);
        };
    }
    Fabric.ContainersController = ContainersController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function CreateBrokerController($scope, localStorage, $routeParams, $location, jolokia, workspace, $compile, $templateCache) {
        Fabric.initScope($scope, $location, jolokia, workspace);
        $scope.defaultGroup = "default";
        $scope.defaultBrokerName = "brokerName";
        $scope.groups = [];
        $scope.possibleNetworks = [];
        $scope.profiles = [];
        $scope.parentProfiles = [];
        $scope.entity = {
            group: $scope.defaultGroup
        };
        $scope.otherEntity = {
            networkConnectAll: false
        };
        $scope.forms = {};
        $scope.onSubmit = function (json, form) {
            $scope.message = ($scope.entity.brokerName || "unknown") + " in group " + ($scope.entity.group || "unknown");
            notification("info", "Creating broker " + $scope.message);
            var json = JSON.stringify($scope.entity, null, '  ');
            jolokia.execute(Fabric.mqManagerMBean, "saveBrokerConfigurationJSON", json, onSuccess(onSave));
        };
        $scope.brokerNameExists = function () {
            var name = $scope.entity.brokerName;
            return name && $scope.brokerNames.indexOf(name) >= 0;
        };
        function updatePossibleNetworks() {
            var group = $scope.entity.group;
            $scope.possibleNetworks = [].concat($scope.groups);
            if (group) {
                $scope.possibleNetworks = $scope.possibleNetworks.remove(group);
            }
        }
        $scope.$watch("entity.group", updatePossibleNetworks);
        $scope.$watch("otherEntity.networkConnectAll", function () {
            if ($scope.otherEntity.networkConnectAll) {
                $scope.entity.networks = $scope.possibleNetworks;
            }
        });
        angular.forEach([
            "group", 
            "profile"
        ], function (param) {
            var value = $routeParams[param];
            if (value) {
                $scope.entity[param] = value;
            }
        });
        if (!$scope.entity.kind) {
            $scope.entity.kind = "MasterSlave";
        }
        Fabric.getDtoSchema("brokerConfig", "org.fusesource.fabric.api.jmx.MQBrokerConfigDTO", jolokia, function (schema) {
            $scope.schema = schema;
            configureSchema(schema);
            jolokia.execute(Fabric.mqManagerMBean, "loadBrokerStatus()", onSuccess(onBrokerData));
            Core.$apply($scope);
        });
        function configureSchema(schema) {
            delete schema.properties['username'];
            delete schema.properties['password'];
            delete schema.properties['properties'];
            var isReplicated = "entity.kind == 'Replicated'";
            var isStandalone = "entity.kind == 'StandAlone'";
            Core.pathSet(schema.properties, [
                'group', 
                'required'
            ], true);
            Core.pathSet(schema.properties, [
                'group', 
                'tooltip'
            ], 'The peer group name of message brokers. The group is name is used by messaging clients to connect to a broker; so it represents a peer group of brokers used for load balancing.');
            Core.pathSet(schema.properties, [
                'group', 
                'input-attributes', 
                'typeahead'
            ], 'title for title in groups | filter:$viewValue');
            Core.pathSet(schema.properties, [
                'group', 
                'input-attributes', 
                'typeahead-editable'
            ], 'true');
            Core.pathSet(schema.properties, [
                'brokerName', 
                'required'
            ], true);
            Core.pathSet(schema.properties, [
                'brokerName', 
                'tooltip'
            ], 'The name of the broker.');
            Core.pathSet(schema.properties, [
                'brokerName', 
                'input-attributes', 
                'autofocus'
            ], 'true');
            Core.pathSet(schema.properties, [
                'parentProfile', 
                'tooltip'
            ], 'The parent profile used by the profile.');
            Core.pathSet(schema.properties, [
                'parentProfile', 
                'input-attributes', 
                'typeahead'
            ], 'p.id for p in parentProfiles | filter:$viewValue');
            Core.pathSet(schema.properties, [
                'parentProfile', 
                'input-attributes', 
                'typeahead-editable'
            ], 'false');
            Core.pathSet(schema.properties, [
                'parentProfile', 
                'input-attributes', 
                "placeholder"
            ], "{{" + isReplicated + " ? 'mq-replicated' : 'mq-base'}}");
            Core.pathSet(schema.properties, [
                'profile', 
                'tooltip'
            ], 'The profile to create instances of this broker.');
            Core.pathSet(schema.properties, [
                'profile', 
                'input-attributes', 
                'typeahead'
            ], 'title for title in profiles | filter:$viewValue');
            Core.pathSet(schema.properties, [
                'profile', 
                'input-attributes', 
                'typeahead-editable'
            ], 'true');
            Core.pathSet(schema.properties, [
                'profile', 
                'input-attributes', 
                "placeholder"
            ], "mq-broker-{{entity.group || 'default'}}.{{entity.brokerName || 'brokerName'}}");
            Core.pathSet(schema.properties, [
                'clientProfile', 
                'tooltip'
            ], 'The profile used by messaging clients to connect to this group of brokers.');
            Core.pathSet(schema.properties, [
                'clientProfile', 
                'input-attributes', 
                'typeahead'
            ], 'title for title in profiles | filter:$viewValue');
            Core.pathSet(schema.properties, [
                'clientProfile', 
                'input-attributes', 
                'typeahead-editable'
            ], 'true');
            Core.pathSet(schema.properties, [
                'clientProfile', 
                'input-attributes', 
                "placeholder"
            ], "mq-client-{{entity.group || 'default'}}");
            Core.pathSet(schema.properties, [
                'clientParentProfile', 
                'tooltip'
            ], 'The parent profile used by the client profile.');
            Core.pathSet(schema.properties, [
                'clientParentProfile', 
                'input-attributes', 
                'typeahead'
            ], 'p.id for p in parentProfiles | filter:$viewValue');
            Core.pathSet(schema.properties, [
                'clientParentProfile', 
                'input-attributes', 
                'typeahead-editable'
            ], 'false');
            Core.pathSet(schema.properties, [
                'parentProfile', 
                'input-attributes', 
                "placeholder"
            ], "default");
            Core.pathSet(schema.properties, [
                'data', 
                'input-attributes', 
                "placeholder"
            ], "${karaf.base}/data/{{entity.brokerName || 'brokerName'}}");
            Core.pathSet(schema.properties, [
                'configUrl', 
                'input-attributes', 
                "placeholder"
            ], "profile:broker.xml");
            Core.pathSet(schema.properties, [
                'replicas', 
                'control-group-attributes', 
                "ng-show"
            ], isReplicated);
            Core.pathSet(schema.properties, [
                'replicas', 
                'input-attributes', 
                "placeholder"
            ], "3");
            Core.pathSet(schema.properties, [
                'minimumInstances', 
                'control-group-attributes', 
                "ng-hide"
            ], isReplicated);
            Core.pathSet(schema.properties, [
                'minimumInstances', 
                'input-attributes', 
                "placeholder"
            ], "{{" + isStandalone + " ? 1 : 2}}");
            Core.pathSet(schema.properties, [
                'networksPassword', 
                'type'
            ], 'password');
            Core.pathSet(schema.properties, [
                'networks', 
                'items', 
                'input-attributes', 
                'typeahead-editable'
            ], 'true');
            Core.pathSet(schema.properties, [
                'networks', 
                'input-attributes', 
                "ng-hide"
            ], "otherEntity.networkConnectAll");
            Core.pathSet(schema.properties, [
                'networks', 
                'tooltip'
            ], 'The broker groups to create a store and forward network to');
            Core.pathSet(schema.properties, [
                'networkConnectAll', 
                'type'
            ], 'boolean');
            Core.pathSet(schema.properties, [
                'networkConnectAll', 
                'input-attributes', 
                'ng-model'
            ], "otherEntity.networkConnectAll");
            Core.pathSet(schema.properties, [
                'networkConnectAll', 
                'label'
            ], 'Network to all groups');
            Core.pathSet(schema.properties, [
                'networkConnectAll', 
                'tooltip'
            ], 'Should this broker create a store and forward network to all the known groups of brokers');
            schema['tabs'] = {
                'Default': [
                    'group', 
                    'brokerName', 
                    'kind', 
                    'profile', 
                    'clientProfile', 
                    'data', 
                    'configUrl', 
                    'replicas', 
                    'minimumInstances', 
                    'networkConnectAll', 
                    'networks'
                ],
                'Advanced': [
                    'parentProfile', 
                    'clientParentProfile', 
                    'networksUserName', 
                    'networksPassword', 
                    '*'
                ]
            };
        }
        function onBrokerData(brokerStatuses) {
            var networkNames = brokerStatuses.map(function (s) {
                return s.networks;
            }).flatten().unique();
            var groups = brokerStatuses.map(function (s) {
                return s.group;
            }).unique();
            $scope.groups = networkNames.concat(groups).unique().sort();
            $scope.profiles = brokerStatuses.map(function (s) {
                return s.profile;
            }).unique().sort();
            $scope.brokerNames = brokerStatuses.map(function (s) {
                return s.brokerName;
            }).unique().sort();
            updatePossibleNetworks();
            var version = brokerStatuses.map(function (s) {
                return s.version;
            }).find(function (s) {
                return s;
            }) || "1.0";
            if (version) {
                jolokia.execute(Fabric.managerMBean, "getProfiles(java.lang.String,java.util.List)", version, [
                    "id", 
                    "abstract"
                ], onSuccess(onProfileData));
            }
            Core.$apply($scope);
        }
        function onProfileData(profileData) {
            if (profileData) {
                $scope.parentProfiles = profileData.filter(function (p) {
                    return !p.abstract;
                }).sortBy("id");
            }
        }
        function onSave(response) {
            notification("success", "Created broker " + $scope.message);
            $location.path("/fabric/mq/brokers");
            Core.$apply($scope);
        }
    }
    Fabric.CreateBrokerController = CreateBrokerController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function CreateContainerController($scope, $element, $compile, $location, workspace, jolokia, localStorage) {
        var log = Logger.get("Fabric");
        $scope.versionsOp = 'versions()';
        $scope.entity = {
            number: 1
        };
        var localStorageProperties = {
            child: {
                jmxUser: 'fabric.userName',
                jmxPassword: 'fabric.password'
            },
            openshift: {
                serverUrl: 'openshift.serverUrl',
                login: 'openshift.login',
                password: 'openshift.password',
                domain: 'openshift.domain',
                gearProfile: 'openshift.gearProfile'
            },
            jclouds: {
                owner: 'jclouds.owner',
                credential: 'jclouds.credential',
                providerName: 'jclouds.providerName',
                imageId: 'jclouds.imageId',
                hardwareId: 'jclouds.hardwareId',
                locationId: 'jclouds.locationId',
                group: 'jclouds.group',
                instanceType: 'jclouds.instanceType'
            }
        };
        $scope.providers = Fabric.registeredProviders(jolokia);
        $scope.selectedProvider = $scope.providers[Object.extended($scope.providers).keys().first()];
        $scope.schema = {};
        $scope.response = {};
        $scope.versions = [];
        $scope.profiles = [];
        $scope.selectedVersion = {};
        $scope.selectedProfiles = [];
        $scope.selectedProfileIds = '';
        $scope.selectedVersionId = '';
        $scope.profileIdFilter = '';
        $scope.child = {
            rootContainers: []
        };
        $scope.openShift = {
            loginDataKey: "openshift.loginData",
            params: null,
            domains: [],
            gearProfiles: [],
            tryLogin: "",
            login: function () {
                var entity = $scope.entity;
                var serverUrl = Core.pathGet(entity, [
                    "serverUrl"
                ]) || "openshift.redhat.com";
                var login = Core.pathGet(entity, [
                    "login"
                ]);
                var password = Core.pathGet(entity, [
                    "password"
                ]);
                log.info("Invoking login to server " + serverUrl + " user " + login);
                $scope.openShift.loginFailed = false;
                if (serverUrl && login && password) {
                    $scope.openShift.domains = [];
                    Fabric.getOpenShiftDomains(workspace, jolokia, serverUrl, login, password, function (results) {
                        $scope.openShift.domains = results;
                        log.info("found openshift domains: " + results);
                        if (results.length === 1) {
                            $scope.entity.domain = results[0];
                        }
                        Core.$apply($scope);
                        Fabric.getOpenShiftGearProfiles(workspace, jolokia, serverUrl, login, password, function (results) {
                            $scope.openShift.gearProfiles = results;
                            log.info("found openshift gears: " + $scope.openShift.gearProfiles);
                            savePropertiesInLocalStorage();
                            var loginData = {
                                domains: $scope.openShift.domains,
                                gearProfiles: $scope.openShift.gearProfiles
                            };
                            localStorage[$scope.openShift.loginDataKey] = angular.toJson(loginData);
                            Core.$apply($scope);
                        });
                    }, function (error) {
                        $scope.openShift.loginFailed = true;
                        Core.$apply($scope);
                    });
                }
            }
        };
        $scope.jclouds = {};
        $scope.forms = {};
        $scope.showAddProfileDialog = false;
        $scope.$watch('selectedProvider', function (newValue, oldValue) {
            if ($scope.selectedProvider) {
                Fabric.getSchema($scope.selectedProvider.id, $scope.selectedProvider.className, jolokia, function (schema) {
                    $scope.schema = schema;
                    Core.$apply($scope);
                });
            }
        }, true);
        $scope.$watch('schema', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $scope.entity['providerType'] = $scope.selectedProvider.id;
                $location.search('tab', $scope.selectedProvider.id);
                var providerId = $scope.entity['providerType'];
                var properties = localStorageProperties[providerId];
                angular.forEach(properties, function (value, key) {
                    var localValue = localStorage[value];
                    if (localValue) {
                        $scope.entity[key] = localValue;
                        log.info("Defaulted entity " + key + " to " + localValue + " from localStorage");
                    }
                });
                if (providerId === "openshift") {
                    var loginDataText = localStorage[$scope.openShift.loginDataKey];
                    if (loginDataText) {
                        log.info("Loaded openshift login details: " + loginDataText);
                        var loginData = Wiki.parseJson(loginDataText);
                        if (loginData) {
                            angular.forEach([
                                "domains", 
                                "gearProfiles"
                            ], function (key) {
                                var value = loginData[key];
                                if (value && angular.isArray(value) && value.length) {
                                    $scope.openShift[key] = value;
                                }
                            });
                        }
                    }
                }
                Forms.defaultValues($scope.entity, $scope.schema);
                if ($scope.selectedProvider.id === 'child') {
                    var rootContainers = Fabric.getRootContainers(jolokia);
                    $scope.child.rootContainers = rootContainers;
                    if (rootContainers && rootContainers.length === 1 && !$scope.entity["parent"]) {
                        $scope.entity["parent"] = rootContainers[0];
                    }
                }
                window.setTimeout(function () {
                    $('input[ng-model]').trigger('input');
                }, 100);
            }
        }, true);
        $scope.$watch('versions', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                if (!$scope.selectedVersion) {
                    if ($scope.selectedVersionId !== '') {
                        $scope.selectedVersion = $scope.versions.find(function (v) {
                            return v.id === $scope.selectedVersionId;
                        });
                    } else {
                        $scope.selectedVersion = $scope.versions.find(function (v) {
                            return v.defaultVersion;
                        });
                    }
                }
            }
        });
        $scope.$watch('selectedVersion', function (newValue, oldValue) {
            if (oldValue !== newValue) {
                if (newValue && 'id' in newValue) {
                    $scope.selectedVersionId = newValue['id'];
                    $location.search('versionId', $scope.selectedVersionId);
                }
            }
        }, true);
        $scope.deselect = function (profile) {
            profile.selected = false;
            $scope.selectedProfiles.remove(function (p) {
                return p.id === profile.id;
            });
        };
        $scope.$watch('selectedProfiles', function (newValue, oldValue) {
            if (oldValue !== newValue) {
                log.debug("selectedProfiles: ", $scope.selectedProfiles);
                $scope.selectedProfileIds = $scope.selectedProfiles.map(function (p) {
                    return p.id;
                }).join(',');
            }
        }, true);
        $scope.$watch('selectedProfileIds', function (newValue, oldValue) {
            var profileIds = $scope.selectedProfileIds.split(',');
            var selected = [];
            profileIds.each(function (id) {
                selected.push({
                    id: id,
                    selected: true
                });
            });
            $scope.selectedProfiles = selected;
            $location.search('profileIds', $scope.selectedProfileIds);
        });
        $scope.rootContainers = function () {
            return Fabric.getRootContainers(jolokia);
        };
        $scope.init = function () {
            var tab = $location.search()['tab'];
            if (tab) {
                $scope.selectedProvider = $scope.providers[tab];
            }
            var parentId = $location.search()['parentId'];
            if (parentId) {
                $scope.entity['parent'] = parentId;
            }
            var versionId = $location.search()['versionId'];
            if (versionId) {
                $scope.selectedVersion = {
                    id: versionId
                };
            }
            var profileIds = $location.search()['profileIds'];
            if (profileIds) {
                $scope.selectedProfileIds = profileIds;
            }
            var count = $location.search()['number'];
            if (count) {
                $scope.entity.number = count;
            }
        };
        $scope.init();
        $scope.$on('$routeUpdate', $scope.init);
        function savePropertiesInLocalStorage() {
            var providerId = $scope.entity['providerType'];
            var properties = localStorageProperties[providerId];
            angular.forEach(properties, function (value, key) {
                var entityValue = $scope.entity[key];
                if (entityValue) {
                    localStorage[value] = entityValue;
                }
            });
        }
        $scope.onSubmit = function (json, form) {
            var providerId = $scope.entity['providerType'];
            if (json.saveJmxCredentials || 'child' !== providerId) {
                savePropertiesInLocalStorage();
            }
            json = Fabric.sanitizeJson(json);
            delete json.saveJmxCredentials;
            if (json.number === 1) {
                delete json.number;
            }
            json['version'] = $scope.selectedVersion.id;
            if ($scope.selectedProfiles.length > 0) {
                json['profiles'] = $scope.selectedProfiles.map(function (p) {
                    return p.id;
                });
            }
            setTimeout(function () {
                jolokia.execute(Fabric.managerMBean, 'createContainers(java.util.Map)', angular.toJson(json), {
                    method: "post",
                    success: function (response) {
                        var error = false;
                        angular.forEach(response.value, function (value, key) {
                            error = true;
                            notification('error', "Creating container " + key + " failed: " + value);
                        });
                        if (!error) {
                            notification('success', "Successfully created containers");
                        }
                        Core.$apply($scope);
                    },
                    error: function (response) {
                        notification('error', "Error creating containers: " + response.error);
                        Core.$apply($scope);
                    }
                });
                Core.$apply($scope);
            }, 10);
            notification('info', "Requesting that new container(s) be created");
            $location.url('/fabric/containers');
        };
    }
    Fabric.CreateContainerController = CreateContainerController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function CreateFabricController($scope, jolokia, $location, workspace, branding) {
        $scope.$on('$routeChangeSuccess', function () {
            if (workspace.treeContainsDomainAndProperties(Fabric.jmxDomain, {
                type: "Fabric"
            })) {
                $location.url("/fabric/view");
            }
        });
        Fabric.getSchema('createEnsemble', 'org.fusesource.fabric.api.CreateEnsembleOptions', jolokia, function (schema) {
            $scope.schema = schema;
            Core.$apply($scope);
        });
        $scope.creating = false;
        $scope.entity = {
            zooKeeperServerPort: 2181,
            globalResolver: 'localhostname',
            resolver: 'localhostname',
            agentEnabled: true,
            autoImportEnabled: true,
            minimumPort: 0,
            maximumPort: 65535,
            profiles: [
                'fabric', 
                'hawtio'
            ]
        };
        if (branding.profile) {
            $scope.entity.profiles.push(branding.profile);
        }
        $scope.forms = {};
        $scope.onSubmit = function (json, form) {
            json = Fabric.sanitizeJson(json);
            setTimeout(function () {
                jolokia.execute(Fabric.clusterBootstrapManagerMBean, 'createCluster(java.util.Map)', angular.toJson(json), {
                    method: 'post',
                    success: function (response) {
                        notification('success', "Created fabric!");
                        $location.url("/fabric/containers");
                        Core.$apply($scope);
                    },
                    error: function (response) {
                        notification('error', "Error creating fabric: " + response.error);
                        Core.$apply($scope);
                    }
                });
                notification('info', "Creating fabric, please wait...");
                $location.url("/logs");
                Core.$apply($scope);
            }, 30);
        };
    }
    Fabric.CreateFabricController = CreateFabricController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function FeatureEditController($scope, $routeParams, $location, jolokia, xml2json) {
        $scope.getProfileFeaturesOp = "getProfileFeatures(java.lang.String, java.lang.String)";
        $scope.versionId = $routeParams.versionId;
        $scope.profileId = $routeParams.profileId;
        $scope.response = {};
        $scope.features = [];
        $scope.repositories = [];
        $scope.repoIds = [];
        $scope.selectedRepoId = '';
        $scope.selectedRepo = {};
        $scope.selectedRepoXML = '';
        $scope.selectedRepoJson = {};
        $scope.selectedRepoError = '';
        $scope.selectedRepoRepos = [];
        $scope.selectedRepoFeatures = [];
        $scope.deletingFeatures = [];
        $scope.addingFeatures = [];
        $scope.selectedRepoSelectedFeatures = [];
        $scope.featureGridOptions = {
            data: 'selectedRepoFeatures',
            selectedItems: $scope.selectedRepoSelectedFeatures,
            displayFooter: false,
            showFilter: false,
            keepLastSelected: true,
            showSelectionCheckbox: true,
            filterOptions: {
                filterText: ''
            },
            columnDefs: [
                {
                    field: 'name',
                    displayName: 'Name'
                }, 
                {
                    field: 'version',
                    displayName: 'Version'
                }
            ]
        };
        $scope.$watch('features', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $scope.parentFeatures = $scope.features.filter(function (f) {
                    return f.isParentFeature;
                });
                $scope.profileFeatures = $scope.features.filter(function (f) {
                    return !f.isParentFeature;
                });
                $scope.addingFeatures = $scope.features.filter(function (f) {
                    return f.adding;
                });
                $scope.deletingFeatures = $scope.features.filter(function (f) {
                    return f.deleting;
                });
            }
        }, true);
        $scope.$watch('addingFeatures', function (newValue, oldValue) {
            if (newValue !== oldValue) {
            }
        }, true);
        $scope.$watch('selectedRepoXML', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $scope.selectedRepoJson = xml2json($scope.selectedRepoXML);
            }
        });
        $scope.$watch('selectedRepoId', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                if ($scope.selectedRepoId !== '') {
                    $scope.selectedRepo = $scope.repositories.find(function (repo) {
                        return $scope.selectedRepoId === repo.id;
                    });
                } else {
                    $scope.selectedRepo = {};
                }
            }
        });
        $scope.$watch('selectedRepoJson', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $scope.selectedRepoName = $scope.selectedRepoJson.name;
                $scope.selectedRepoRepos = $scope.selectedRepoJson.repository;
                if (!angular.isArray($scope.selectedRepoRepos)) {
                    $scope.selectedRepoRepos = [
                        $scope.selectedRepoRepos
                    ];
                }
                Logger.info("selectedRepoRepos: ", $scope.selectedRepoRepos);
                $scope.selectedRepoFeatures = $scope.selectedRepoJson.feature;
                if (!angular.isArray($scope.selectedRepoFeatures)) {
                    $scope.selectedRepoFeatures = [
                        $scope.selectedRepoFeatures
                    ];
                }
            }
        });
        $scope.$watch('selectedRepo', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                if (angular.isDefined($scope.selectedRepo.data)) {
                    $scope.selectedRepoXML = $scope.selectedRepo.data;
                } else {
                    $scope.selectedRepoXML = '';
                }
                if (angular.isDefined($scope.selectedRepo.errorMessage)) {
                    $scope.selectedRepoError = $scope.selectedRepo.errorMessage;
                } else {
                    $scope.selectedRepoError = '';
                }
            }
        }, true);
        $scope.$watch('repoIds', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                if ($scope.repoIds.length > 0) {
                    if ($scope.selectedRepoId === '') {
                        $scope.selectedRepoId = $scope.repoIds[0];
                    }
                } else {
                    $scope.selectedRepoId = '';
                }
            }
        }, true);
        $scope.$watch('repositories', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $scope.repoIds = $scope.repositories.map(function (repo) {
                    return repo.id;
                });
            }
        }, true);
        $scope.dispatch = function (response) {
            var responseJson = angular.toJson(response.value);
            if (responseJson !== $scope.responseJson) {
                if (angular.isDefined($scope.responseJson)) {
                    notification('info', "Profile feature definitions updated");
                }
                $scope.responseJson = responseJson;
                $scope.features = Object.clone(response.value.featureDefinitions, true);
                $scope.repositories = Object.clone(response.value.repositoryDefinitions, true);
                Core.$apply($scope);
            }
        };
        $scope.getClass = function (feature) {
            if (feature.adding) {
                return "adding";
            }
            if (feature.deleting) {
                return "deleting";
            }
            return "";
        };
        $scope.removeFeature = function (feature) {
            if (feature.adding) {
                $scope.features.remove(function (f) {
                    return f.id === feature.id;
                });
            } else {
                feature.deleting = !feature.deleting;
            }
        };
        $scope.addSelectedFeatures = function (withVersion) {
            $scope.selectedRepoSelectedFeatures.each(function (feature) {
                var id = feature.name;
                if (withVersion) {
                    id = id + "/" + feature.version;
                }
                $scope.features.push({
                    id: id,
                    adding: true
                });
            });
        };
        $scope.save = function () {
            jolokia.request({
                type: 'exec',
                mbean: Fabric.managerMBean,
                operation: 'getConfigurationFile(java.lang.String, java.lang.String, java.lang.String)',
                arguments: [
                    $scope.versionId, 
                    $scope.profileId, 
                    'org.fusesource.fabric.agent.properties'
                ]
            }, onSuccess($scope.doSave));
        };
        $scope.doSave = function (response) {
            var configFile = response.value.decodeBase64();
            var lines = configFile.lines();
            if ($scope.deletingFeatures.length > 0) {
                $scope.deletingFeatures.each(function (feature) {
                    lines.remove(function (line) {
                        return line.startsWith("feature." + feature.id);
                    });
                });
            }
            if ($scope.addingFeatures.length > 0) {
                $scope.addingFeatures.each(function (feature) {
                    lines.add("feature." + feature.id + " = " + feature.id);
                });
            }
            configFile = lines.join('\n');
            Fabric.saveConfigFile(jolokia, $scope.versionId, $scope.profileId, 'org.fusesource.fabric.agent.properties', configFile.encodeBase64(), function () {
                notification('success', "Updated feature definitions...");
                Core.$apply($scope);
            }, function (response) {
                notification('error', "Failed to save feature definitions due to " + response.error);
                Core.$apply($scope);
            });
        };
        Core.register(jolokia, $scope, [
            {
                type: 'exec',
                mbean: Fabric.managerMBean,
                operation: $scope.getProfileFeaturesOp,
                arguments: [
                    $scope.versionId, 
                    $scope.profileId
                ]
            }
        ], onSuccess($scope.dispatch));
    }
    Fabric.FeatureEditController = FeatureEditController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    Fabric.log = Logger.get("Fabric");
    Fabric.jmxDomain = "org.fusesource.fabric";
    Fabric.managerMBean = Fabric.jmxDomain + ":type=Fabric";
    Fabric.clusterManagerMBean = Fabric.jmxDomain + ":type=ClusterServiceManager";
    Fabric.clusterBootstrapManagerMBean = Fabric.jmxDomain + ":type=ClusterBootstrapManager";
    Fabric.openShiftFabricMBean = Fabric.jmxDomain + ":type=OpenShift";
    Fabric.mqManagerMBean = Fabric.jmxDomain + ":type=MQManager";
    var schemaLookupDomain = "hawtio";
    var schemaLookupType = "SchemaLookup";
    Fabric.schemaLookupMBean = schemaLookupDomain + ":type=" + schemaLookupType;
    Fabric.useDirectoriesInGit = true;
    var fabricTopLevel = "fabric/profiles/";
    Fabric.profileSuffix = ".profile";
    Fabric.jolokiaWebAppGroupId = "org.fusesource.fabric.fabric-jolokia";
    function fabricCreated(workspace) {
        return workspace.treeContainsDomainAndProperties(Fabric.jmxDomain, {
            type: "Fabric"
        });
    }
    Fabric.fabricCreated = fabricCreated;
    function canBootstrapFabric(workspace) {
        return workspace.treeContainsDomainAndProperties(Fabric.jmxDomain, {
            type: "ClusterBootstrapManager"
        });
    }
    Fabric.canBootstrapFabric = canBootstrapFabric;
    function hasOpenShiftFabric(workspace) {
        return workspace.treeContainsDomainAndProperties(Fabric.jmxDomain, {
            type: "OpenShift"
        });
    }
    Fabric.hasOpenShiftFabric = hasOpenShiftFabric;
    function hasMQManager(workspace) {
        return workspace.treeContainsDomainAndProperties(Fabric.jmxDomain, {
            type: "MQManager"
        });
    }
    Fabric.hasMQManager = hasMQManager;
    function hasSchemaMBean(workspace) {
        return workspace.treeContainsDomainAndProperties(schemaLookupDomain, {
            type: schemaLookupType
        });
    }
    Fabric.hasSchemaMBean = hasSchemaMBean;
    function hasGitMBean(workspace) {
        return workspace.treeContainsDomainAndProperties(Git.jmxDomain, {
            type: Git.mbeanType
        });
    }
    Fabric.hasGitMBean = hasGitMBean;
    function isFMCContainer(workspace) {
        return Fabric.hasFabric(workspace) && Fabric.hasSchemaMBean(workspace) && Fabric.hasGitMBean(workspace);
    }
    Fabric.isFMCContainer = isFMCContainer;
    function hasFabric(workspace) {
        return fabricCreated(workspace) && canBootstrapFabric(workspace);
    }
    Fabric.hasFabric = hasFabric;
    function initScope($scope, $location, jolokia, workspace) {
        $scope.isCurrentContainer = function (container) {
            if (!container) {
                return false;
            }
            if (Core.isBlank(Fabric.currentContainerId)) {
                return false;
            }
            if (angular.isObject(container)) {
                return container['id'] === Fabric.currentContainerId;
            }
            if (angular.isString(container)) {
                return container === Fabric.currentContainerId;
            }
            return false;
        };
        $scope.canConnect = function (container) {
            if (!container) {
                return false;
            }
            if (Core.isBlank(container['jolokiaUrl'])) {
                return false;
            }
            if (!Core.parseBooleanValue(container['alive'])) {
                return false;
            }
            return !$scope.isCurrentContainer(container);
        };
        $scope.refreshProfile = function (versionId, profileId) {
            Fabric.log.debug('Refreshing profile: ' + profileId + '/' + versionId);
            if (!versionId || !profileId) {
                return;
            }
            jolokia.request({
                type: 'exec',
                mbean: Fabric.managerMBean,
                operation: 'refreshProfile',
                arguments: [
                    versionId, 
                    profileId
                ]
            }, {
                method: 'POST',
                success: function () {
                    notification('success', 'Triggered refresh of profile ' + profileId + '/' + versionId);
                    Core.$apply($scope);
                },
                error: function (response) {
                    Fabric.log.warn('Failed to trigger refresh for profile ' + profileId + '/' + versionId + ' due to: ', response.error);
                    Fabric.log.info("Stack trace: ", response.stacktrace);
                    Core.$apply($scope);
                }
            });
        };
        $scope.hasFabricWiki = function () {
            return Git.isGitMBeanFabric(workspace);
        };
        $scope.showContainer = function (container) {
            $location.path('/fabric/container/' + container.id);
        };
        $scope.createRequiredContainers = function (profile) {
            var profileId = profile.id;
            var args = {};
            if (profileId) {
                args["profileIds"] = profileId;
            }
            var versionId = profile.versionId || profile.version;
            if (versionId) {
                args["versionId"] = versionId;
            }
            var requirements = profile.requirements;
            if (requirements) {
                var min = requirements.minimumInstances;
                if (min) {
                    var delta = min - (profile.count || 0);
                    if (delta > 1) {
                        args["number"] = delta;
                    }
                }
            }
            $location.url('/fabric/containers/createContainer').search(args);
        };
        $scope.createContainer = function () {
            var kind = null;
            var providers = registeredProviders(jolokia);
            angular.forEach([
                "openshift", 
                "jclouds"
            ], function (value) {
                if (!kind && providers[value]) {
                    kind = value;
                }
            });
            if (!kind) {
                kind = 'child';
            }
            $location.url('/fabric/containers/createContainer').search('tab', kind);
        };
        $scope.createChildContainer = function (container) {
            $location.url('/fabric/containers/createContainer').search({
                'tab': 'child',
                'parentId': container.id
            });
        };
        $scope.createChildContainer = function (container) {
            $location.url('/fabric/containers/createContainer').search({
                'tab': 'child',
                'parentId': container.id
            });
        };
        $scope.showProfile = function (profile) {
            var version = profile.versionId || profile.version || $scope.activeVersionId;
            Fabric.gotoProfile(workspace, jolokia, localStorage, $location, version, profile);
        };
        $scope.getSelectedClass = function (obj) {
            var answer = [];
            if (obj.selected) {
                answer.push('selected');
            }
            if (angular.isDefined(obj['root']) && obj['root'] === false) {
                answer.push('child-container');
            }
            return answer.join(' ');
        };
        $scope.statusIcon = function (row) {
            return Fabric.statusIcon(row);
        };
        $scope.isEnsembleContainer = function (containerId) {
            if ($scope.ensembleContainerIds) {
                return $scope.ensembleContainerIds.any(containerId);
            }
            return false;
        };
        $scope.connect = {
            dialog: new Core.Dialog(),
            saveCredentials: false,
            userName: null,
            password: null,
            container: null,
            view: null,
            onOK: function () {
                var userName = $scope.connect.userName;
                var password = $scope.connect.password;
                var container = $scope.connect.container;
                Fabric.log.info("Logging into container " + container + " with user " + userName);
                if ($scope.connect.saveCredentials) {
                    $scope.connect.saveCredentials = false;
                    if (userName) {
                        localStorage['fabric.userName'] = userName;
                    }
                    if (password) {
                        localStorage['fabric.password'] = password;
                    }
                }
                console.log("Connecting as user " + userName);
                var options = new Core.ConnectToServerOptions();
                options.view = $scope.connect.view;
                Fabric.connect(localStorage, container, userName, password, true, options);
                $scope.connect.container = {};
                setTimeout(function () {
                    $scope.connect.dialog.close();
                    Core.$apply($scope);
                }, 100);
            }
        };
        $scope.doConnect = function (container, view) {
            $scope.connect.userName = Core.username || localStorage['fabric.userName'];
            $scope.connect.password = Core.password || localStorage['fabric.password'];
            $scope.connect.container = container;
            $scope.connect.view = view || "/logs";
            var alwaysPrompt = localStorage['fabricAlwaysPrompt'];
            if ((alwaysPrompt && alwaysPrompt !== "false") || !$scope.connect.userName || !$scope.connect.userName) {
                $scope.connect.dialog.open();
            } else {
                $scope.connect.onOK();
            }
        };
        $scope.createVersionDialog = {
            dialog: new Core.Dialog(),
            newVersionName: "",
            open: function () {
                $scope.createVersionDialog.newVersionName = "";
                $scope.createVersionDialog.dialog.open();
            },
            onOk: function () {
                var success = function (response) {
                    notification('success', "Created version " + response.value.id);
                    $scope.createVersionDialog.newVersionName = "";
                    var $rootScope = $scope.$root || $scope.$rootScope || $scope;
                    if ($rootScope) {
                        $rootScope.$broadcast('wikiBranchesUpdated');
                    }
                };
                var error = function (response) {
                    Fabric.log.error("Failed to create version due to :", response.error, " stack trace: ", response.stacktrace);
                };
                var newVersionName = $scope.createVersionDialog.newVersionName;
                if (newVersionName !== '') {
                    Fabric.createVersionWithId(jolokia, newVersionName, success, error);
                } else {
                    Fabric.createVersion(jolokia, success, error);
                }
                $scope.createVersionDialog.dialog.close();
            }
        };
        $scope.changeVersionDialog = {
            dialog: new Core.Dialog(),
            containerIds: [],
            versions: [],
            gridOptions: {
                data: 'changeVersionDialogVersions',
                selectedItems: [],
                showFilter: false,
                showColumnMenu: false,
                multiSelect: false,
                filterOptions: {
                    filterText: "",
                    useExternalFilter: false
                },
                sortInfo: {
                    fields: [
                        "sortProperty"
                    ],
                    directions: [
                        "desc"
                    ]
                },
                columnDefs: [
                    {
                        field: 'sortProperty',
                        displayName: 'Select New Version',
                        cellTemplate: '<div class="ngCellText">{{row.entity.id}}</div>'
                    }
                ]
            },
            openNewVersionDialog: function () {
                $scope.changeVersionDialog.dialog.close();
                setTimeout(function () {
                    $scope.createVersionDialog.open();
                    Core.$apply($scope);
                }, 500);
            },
            open: function (containers) {
                $scope.changeVersionDialog.containers = containers || [];
                $scope.changeVersionDialog.gridOptions.selectedItems = [];
                function render(response) {
                    if (response) {
                        var currentIds = $scope.changeVersionDialog.containers.map(function (c) {
                            return c.versionId;
                        }).unique();
                        if (currentIds && currentIds.length === 1) {
                            var currentId = currentIds[0];
                            response = response.filter(function (v) {
                                return v.id !== currentId;
                            });
                        }
                    }
                    angular.forEach(response, function (version) {
                        version.sortProperty = Core.versionToSortableString(version.id);
                    });
                    $scope.changeVersionDialogVersions = response;
                    if (response.length > 0) {
                        $scope.changeVersionDialog.gridOptions.selectedItems = [
                            response[response.length - 1]
                        ];
                    }
                    $scope.changeVersionDialog.dialog.open();
                    Core.$apply($scope);
                }
                jolokia.execute(Fabric.managerMBean, 'versions(java.util.List)', [
                    'id', 
                    'defaultVersion'
                ], onSuccess(render));
            },
            onOk: function () {
                $scope.changeVersionDialog.dialog.close();
                var selectedItems = $scope.changeVersionDialog.gridOptions.selectedItems;
                if (selectedItems && selectedItems.length) {
                    var newVersionId = selectedItems[0].id;
                    if (newVersionId) {
                        var containerIds = $scope.changeVersionDialog.containers.map(function (c) {
                            return c.id;
                        });
                        Fabric.log.info("Setting version to " + newVersionId + " on containers: " + containerIds);
                        Fabric.migrateContainers(jolokia, newVersionId, containerIds, function () {
                            notification('success', "Successfully migrated containers");
                        }, function (response) {
                            notification('error', "Failed to migrate containers due to " + response.error);
                        });
                        setTimeout(function () {
                            $scope.changeVersionDialog.dialog.close();
                            Core.$apply($scope);
                        }, 100);
                    }
                }
            }
        };
    }
    Fabric.initScope = initScope;
    function pagePathToProfileId(pageId) {
        var answer = null;
        if (angular.isDefined(pageId) && pageId.has(fabricTopLevel) && pageId !== fabricTopLevel) {
            var profileId = pageId.remove(fabricTopLevel);
            if ((Fabric.useDirectoriesInGit || !profileId.has("/"))) {
                var profileSeparator = profileId.indexOf(Fabric.profileSuffix + "/");
                var endsWithSuffix = profileId.endsWith(Fabric.profileSuffix);
                if (!Fabric.useDirectoriesInGit || endsWithSuffix || profileSeparator > 0) {
                    if (Fabric.useDirectoriesInGit) {
                        if (endsWithSuffix) {
                            profileId = Core.trimTrailing(profileId, Fabric.profileSuffix);
                        } else if (profileSeparator > 0) {
                            profileId = profileId.substring(0, profileSeparator);
                        }
                        profileId = profileId.replace(/\//g, "-");
                    }
                    answer = profileId;
                }
            }
        }
        return answer;
    }
    Fabric.pagePathToProfileId = pagePathToProfileId;
    function profilePath(profileId) {
        return profileId.replace(/-/g, "/") + Fabric.profileSuffix;
    }
    Fabric.profilePath = profilePath;
    function profileLink(workspace, jolokia, localStorage, versionId, profileId) {
        var path;
        if (Wiki.isWikiEnabled(workspace, jolokia, localStorage)) {
            path = "/wiki/branch/" + versionId + "/view/fabric/profiles/" + Fabric.profilePath(profileId);
        } else {
            path = "/fabric/profile/" + versionId + "/" + profileId;
        }
        return path;
    }
    Fabric.profileLink = profileLink;
    function containerCountBadgeStyle(min, count) {
        if (min) {
            if (!count) {
                return "badge-important";
            } else {
                return min <= count ? "badge-success" : "badge-warning";
            }
        }
        return "";
    }
    Fabric.containerCountBadgeStyle = containerCountBadgeStyle;
    function gotoProfile(workspace, jolokia, localStorage, $location, versionId, profile) {
        var path = profileLink(workspace, jolokia, localStorage, versionId, profile.id);
        $location.url(path);
    }
    Fabric.gotoProfile = gotoProfile;
    function setSelect(selection, group) {
        if (!angular.isDefined(selection)) {
            return group[0];
        }
        var answer = group.findIndex(function (item) {
            return item.id === selection.id;
        });
        if (answer !== -1) {
            return group[answer];
        } else {
            return group[0];
        }
    }
    Fabric.setSelect = setSelect;
    function doDeleteContainer($scope, jolokia, name, onDelete) {
        if (typeof onDelete === "undefined") { onDelete = null; }
        notification('info', "Deleting " + name);
        destroyContainer(jolokia, name, function () {
            notification('success', "Deleted " + name);
            if (onDelete) {
                onDelete();
            }
            Core.$apply($scope);
        }, function (response) {
            notification('error', "Failed to delete " + name + " due to " + response.error);
            Core.$apply($scope);
        });
    }
    Fabric.doDeleteContainer = doDeleteContainer;
    function doStartContainer($scope, jolokia, name) {
        notification('info', "Starting " + name);
        startContainer(jolokia, name, function () {
            notification('success', "Started " + name);
            Core.$apply($scope);
        }, function (response) {
            notification('error', "Failed to start " + name + " due to " + response.error);
            Core.$apply($scope);
        });
    }
    Fabric.doStartContainer = doStartContainer;
    function doStopContainer($scope, jolokia, name) {
        notification('info', "Stopping " + name);
        stopContainer(jolokia, name, function () {
            notification('success', "Stopped " + name);
            Core.$apply($scope);
        }, function (response) {
            notification('error', "Failed to stop " + name + " due to " + response.error);
            Core.$apply($scope);
        });
    }
    Fabric.doStopContainer = doStopContainer;
    Fabric.urlResolvers = [
        'http:', 
        'ftp:', 
        'mvn:'
    ];
    function completeUri($q, $scope, workspace, jolokia, something) {
    }
    Fabric.completeUri = completeUri;
    function applyPatches(jolokia, files, targetVersion, newVersionName, proxyUser, proxyPass, success, error) {
        doAction('applyPatches(java.util.List,java.lang.String,java.lang.String,java.lang.String,java.lang.String)', jolokia, [
            files, 
            targetVersion, 
            newVersionName, 
            proxyUser, 
            proxyPass
        ], success, error);
    }
    Fabric.applyPatches = applyPatches;
    function setContainerProperty(jolokia, containerId, property, value, success, error) {
        doAction('setContainerProperty(java.lang.String, java.lang.String, java.lang.Object)', jolokia, [
            containerId, 
            property, 
            value
        ], success, error);
    }
    Fabric.setContainerProperty = setContainerProperty;
    function deleteConfigFile(jolokia, version, profile, pid, success, error) {
        doAction('deleteConfigurationFile(java.lang.String, java.lang.String, java.lang.String)', jolokia, [
            version, 
            profile, 
            pid
        ], success, error);
    }
    Fabric.deleteConfigFile = deleteConfigFile;
    function newConfigFile(jolokia, version, profile, pid, success, error) {
        doAction('setConfigurationFile(java.lang.String, java.lang.String, java.lang.String, java.lang.String)', jolokia, [
            version, 
            profile, 
            pid, 
            ''
        ], success, error);
    }
    Fabric.newConfigFile = newConfigFile;
    function saveConfigFile(jolokia, version, profile, pid, data, success, error) {
        doAction('setConfigurationFile(java.lang.String, java.lang.String, java.lang.String, java.lang.String)', jolokia, [
            version, 
            profile, 
            pid, 
            data
        ], success, error);
    }
    Fabric.saveConfigFile = saveConfigFile;
    function addProfilesToContainer(jolokia, container, profiles, success, error) {
        doAction('addProfilesToContainer(java.lang.String, java.util.List)', jolokia, [
            container, 
            profiles
        ], success, error);
    }
    Fabric.addProfilesToContainer = addProfilesToContainer;
    function removeProfilesFromContainer(jolokia, container, profiles, success, error) {
        doAction('removeProfilesFromContainer(java.lang.String, java.util.List)', jolokia, [
            container, 
            profiles
        ], success, error);
    }
    Fabric.removeProfilesFromContainer = removeProfilesFromContainer;
    function applyProfiles(jolokia, version, profiles, containers, success, error) {
        doAction('applyProfilesToContainers(java.lang.String, java.util.List, java.util.List)', jolokia, [
            version, 
            profiles, 
            containers
        ], success, error);
    }
    Fabric.applyProfiles = applyProfiles;
    function migrateContainers(jolokia, version, containers, success, error) {
        doAction('applyVersionToContainers(java.lang.String, java.util.List)', jolokia, [
            version, 
            containers
        ], success, error);
    }
    Fabric.migrateContainers = migrateContainers;
    function changeProfileParents(jolokia, version, id, parents, success, error) {
        doAction('changeProfileParents(java.lang.String, java.lang.String, java.util.List)', jolokia, [
            version, 
            id, 
            parents
        ], success, error);
    }
    Fabric.changeProfileParents = changeProfileParents;
    function createProfile(jolokia, version, id, parents, success, error) {
        doAction('createProfile(java.lang.String, java.lang.String, java.util.List)', jolokia, [
            version, 
            id, 
            parents
        ], success, error);
    }
    Fabric.createProfile = createProfile;
    function copyProfile(jolokia, version, sourceName, targetName, force, success, error) {
        doAction('copyProfile(java.lang.String, java.lang.String, java.lang.String, boolean)', jolokia, [
            version, 
            sourceName, 
            targetName, 
            force
        ], success, error);
    }
    Fabric.copyProfile = copyProfile;
    function createVersionWithParentAndId(jolokia, base, id, success, error) {
        doAction('createVersion(java.lang.String, java.lang.String)', jolokia, [
            base, 
            id
        ], success, error);
    }
    Fabric.createVersionWithParentAndId = createVersionWithParentAndId;
    function createVersionWithId(jolokia, id, success, error) {
        doAction('createVersion(java.lang.String)', jolokia, [
            id
        ], success, error);
    }
    Fabric.createVersionWithId = createVersionWithId;
    function createVersion(jolokia, success, error) {
        doAction('createVersion()', jolokia, [], success, error);
    }
    Fabric.createVersion = createVersion;
    function deleteVersion(jolokia, id, success, error) {
        doAction('deleteVersion(java.lang.String)', jolokia, [
            id
        ], success, error);
    }
    Fabric.deleteVersion = deleteVersion;
    function activeVersion($location) {
        return $location.search()['cv'] || "1.0";
    }
    Fabric.activeVersion = activeVersion;
    function getContainerIdsForProfile(jolokia, version, profileId) {
        return jolokia.execute(Fabric.managerMBean, "containerIdsForProfile", version, profileId, {
            method: 'POST'
        });
    }
    Fabric.getContainerIdsForProfile = getContainerIdsForProfile;
    function deleteProfile(jolokia, version, id, success, error) {
        doAction('deleteProfile(java.lang.String, java.lang.String)', jolokia, [
            version, 
            id
        ], success, error);
    }
    Fabric.deleteProfile = deleteProfile;
    function profileWebAppURL(jolokia, webAppId, profileId, versionId, success, error) {
        doAction('profileWebAppURL', jolokia, [
            webAppId, 
            profileId, 
            versionId
        ], success, error);
    }
    Fabric.profileWebAppURL = profileWebAppURL;
    function onJolokiaUrlCreateJolokia(response, fn) {
        var jolokia = null;
        if (response) {
            var url = response.value;
            if (url) {
                url = Core.useProxyIfExternal(url);
                jolokia = Fabric.createJolokia(url);
            } else {
                if (response.error) {
                    Fabric.log.warn(response.error, response.stacktrace);
                }
            }
            if (fn) {
                fn(jolokia);
            }
        }
        return jolokia;
    }
    function profileJolokia(jolokia, profileId, versionId, onJolokia) {
        function onJolokiaUrl(response) {
            return onJolokiaUrlCreateJolokia(response, onJolokia);
        }
        return Fabric.profileWebAppURL(jolokia, Fabric.jolokiaWebAppGroupId, profileId, versionId, onJolokiaUrl, onJolokiaUrl);
    }
    Fabric.profileJolokia = profileJolokia;
    function containerJolokia(jolokia, containerId, onJolokia) {
        function onJolokiaUrl(response) {
            return onJolokiaUrlCreateJolokia(response, onJolokia);
        }
        return Fabric.containerWebAppURL(jolokia, Fabric.jolokiaWebAppGroupId, containerId, onJolokiaUrl, onJolokiaUrl);
    }
    Fabric.containerJolokia = containerJolokia;
    function containerWebAppURL(jolokia, webAppId, containerId, success, error) {
        doAction('containerWebAppURL', jolokia, [
            webAppId, 
            containerId
        ], success, error);
    }
    Fabric.containerWebAppURL = containerWebAppURL;
    function doAction(action, jolokia, arguments, success, error) {
        jolokia.request({
            type: 'exec',
            mbean: Fabric.managerMBean,
            operation: action,
            arguments: arguments
        }, {
            method: 'POST',
            success: success,
            error: error
        });
    }
    Fabric.doAction = doAction;
    function stopContainer(jolokia, id, success, error) {
        doAction('stopContainer(java.lang.String)', jolokia, [
            id
        ], success, error);
    }
    Fabric.stopContainer = stopContainer;
    function destroyContainer(jolokia, id, success, error) {
        doAction('destroyContainer(java.lang.String)', jolokia, [
            id
        ], success, error);
    }
    Fabric.destroyContainer = destroyContainer;
    function startContainer(jolokia, id, success, error) {
        doAction('startContainer(java.lang.String)', jolokia, [
            id
        ], success, error);
    }
    Fabric.startContainer = startContainer;
    function getServiceList(container) {
        var answer = [];
        if (angular.isDefined(container) && angular.isDefined(container.jmxDomains) && angular.isArray(container.jmxDomains) && container.alive) {
            container.jmxDomains.forEach(function (domain) {
                if (domain === "org.fusesource.insight") {
                    answer.push({
                        title: "Fuse Insight",
                        type: "icon",
                        src: "icon-eye-open"
                    });
                }
                if (domain === "org.apache.activemq") {
                    answer.push({
                        title: "Apache ActiveMQ",
                        type: "img",
                        src: "app/fabric/img/message_broker.png"
                    });
                }
                if (domain === "org.apache.camel") {
                    answer.push({
                        title: "Apache Camel",
                        type: "img",
                        src: "app/fabric/img/camel.png"
                    });
                }
                if (domain === "org.fusesource.fabric") {
                    answer.push({
                        title: "Fuse Fabric",
                        type: "img",
                        src: "app/fabric/img/fabric.png"
                    });
                }
                if (domain === "hawtio") {
                    answer.push({
                        title: "hawtio",
                        type: "img",
                        src: "app/fabric/img/hawtio.png"
                    });
                }
                if (domain === "org.apache.karaf") {
                    answer.push({
                        title: "Apache Karaf",
                        type: "icon",
                        src: "icon-beaker"
                    });
                }
                if (domain === "org.apache.zookeeper") {
                    answer.push({
                        title: "Apache Zookeeper",
                        type: "icon",
                        src: "icon-group"
                    });
                }
            });
        }
        return answer;
    }
    Fabric.getServiceList = getServiceList;
    function getDefaultVersionId(jolokia) {
        return (getDefaultVersion(jolokia) || {})["id"] || "1.0";
    }
    Fabric.getDefaultVersionId = getDefaultVersionId;
    function getDefaultVersion(jolokia) {
        return jolokia.execute(Fabric.managerMBean, "defaultVersion()");
    }
    Fabric.getDefaultVersion = getDefaultVersion;
    function defaultContainerValues(workspace, $scope, values) {
        var map = {};
        angular.forEach(values, function (row) {
            var profileIds = row["profileIds"];
            if (profileIds) {
                angular.forEach(profileIds, function (profileId) {
                    var containers = map[profileId];
                    if (!containers) {
                        containers = [];
                        map[profileId] = containers;
                    }
                    containers.push(row);
                });
            }
            $scope.profileMap = map;
            row["link"] = containerLinks(workspace, row["id"]);
            row["profileLinks"] = profileLinks(workspace, row["versionId"], profileIds);
            var versionId = row["versionId"];
            var versionHref = url("#/fabric/profiles?v=" + versionId);
            var versionLink = "<a href='" + versionHref + "'>" + versionId + "</a>";
            row["versionHref"] = versionHref;
            row["versionLink"] = versionLink;
            var id = row['id'] || "";
            var title = "container " + id + " ";
            var img = "red-dot.png";
            if (row['managed'] === false) {
                img = "spacer.gif";
            } else if (!row['alive']) {
                img = "gray-dot.png";
            } else if (row['provisionPending']) {
                img = "pending.gif";
            } else if (row['provisionStatus'] === 'success') {
                img = "green-dot.png";
            }
            img = "img/dots/" + img;
            row["statusImageHref"] = img;
            row["link"] = "<img src='" + img + "' title='" + title + "'/> " + (row["link"] || id);
        });
        return values;
    }
    Fabric.defaultContainerValues = defaultContainerValues;
    function toCollection(values) {
        var collection = values;
        if (!angular.isArray(values)) {
            collection = [
                values
            ];
        }
        return collection;
    }
    Fabric.toCollection = toCollection;
    function containerLinks(workspace, values) {
        var answer = "";
        angular.forEach(toCollection(values), function (value, key) {
            var prefix = "";
            if (answer.length > 0) {
                prefix = " ";
            }
            answer += prefix + "<a href='" + url("#/fabric/container/" + value + workspace.hash()) + "'>" + value + "</a>";
        });
        return answer;
    }
    Fabric.containerLinks = containerLinks;
    function profileLinks(workspace, versionId, values) {
        var answer = "";
        angular.forEach(toCollection(values), function (value, key) {
            var prefix = "";
            if (answer.length > 0) {
                prefix = " ";
            }
            answer += prefix + "<a href='" + url("#/fabric/profile/" + versionId + "/" + value + workspace.hash()) + "'>" + value + "</a>";
        });
        return answer;
    }
    Fabric.profileLinks = profileLinks;
    function defaultProfileValues(workspace, versionId, values) {
        angular.forEach(values, function (row) {
            var id = row["id"];
            row["link"] = profileLinks(workspace, versionId, id);
            row["parentLinks"] = profileLinks(workspace, versionId, row["parentIds"]);
            var containersHref = url("#/fabric/containers?p=" + id);
            var containerCount = row["containerCount"];
            var containersLink = "";
            if (containerCount) {
                containersLink = "<a href='" + containersHref + "'>" + containerCount + "</a>";
            }
            row["containersCountLink"] = containersLink;
            row["containersHref"] = containersHref;
        });
        return values;
    }
    Fabric.defaultProfileValues = defaultProfileValues;
    function getZooKeeperFacadeMBean(workspace) {
        var folder = workspace.findMBeanWithProperties(Fabric.jmxDomain, {
            type: "ZooKeeper"
        });
        return Core.pathGet(folder, "objectName");
    }
    Fabric.getZooKeeperFacadeMBean = getZooKeeperFacadeMBean;
    function statusTitle(container) {
        var answer = 'Alive';
        if (!container.alive) {
            answer = 'Not Running';
        } else {
            answer += ' - ' + humanizeValue(container.provisionResult);
        }
        return answer;
    }
    Fabric.statusTitle = statusTitle;
    function statusIcon(row) {
        if (row) {
            if (row.alive) {
                switch(row.provisionResult) {
                    case 'success':
                        return "green icon-play-circle";
                    case 'downloading':
                        return "icon-download-alt";
                    case 'installing':
                        return "icon-hdd";
                    case 'analyzing':
                    case 'finalizing':
                        return "icon-refresh icon-spin";
                    case 'resolving':
                        return "icon-sitemap";
                    case 'error':
                        return "red icon-warning-sign";
                }
            } else {
                return "orange icon-off";
            }
        }
        return "icon-refresh icon-spin";
    }
    Fabric.statusIcon = statusIcon;
    function connect(localStorage, row, userName, password, useProxy, options) {
        if (typeof userName === "undefined") { userName = ""; }
        if (typeof password === "undefined") { password = ""; }
        if (typeof useProxy === "undefined") { useProxy = true; }
        if (typeof options === "undefined") { options = new Core.ConnectToServerOptions(); }
        options.jolokiaUrl = row.jolokiaUrl;
        options.userName = userName;
        options.password = password;
        options.useProxy = useProxy;
        Core.connectToServer(localStorage, options);
    }
    Fabric.connect = connect;
    function createJolokia(url) {
        var username = Core.username;
        var password = Core.password;
        if (!username) {
            var jsonText = localStorage[url];
            if (jsonText) {
                var obj = Wiki.parseJson(jsonText);
                if (obj) {
                    username = obj["username"];
                    password = obj["password"];
                }
            }
        }
        Fabric.log.info("Logging into remote jolokia " + url + " using username: " + username);
        return Core.createJolokia(url, username, password);
    }
    Fabric.createJolokia = createJolokia;
    function registeredProviders(jolokia) {
        var providers = jolokia.execute(Fabric.managerMBean, 'registeredProviders()');
        var answer = {};
        angular.forEach(providers, function (value, key) {
            answer[key] = {
                id: key,
                className: value
            };
        });
        return answer;
    }
    Fabric.registeredProviders = registeredProviders;
    function getSchema(id, className, jolokia, cb) {
        jolokia.execute(Fabric.schemaLookupMBean, 'getSchemaForClass(java.lang.String)', className, {
            method: 'POST',
            success: function (value) {
                cb(Fabric.customizeSchema(id, angular.fromJson(value)));
            }
        });
    }
    Fabric.getSchema = getSchema;
    function getDtoSchema(id, className, jolokia, cb) {
        jolokia.execute(Fabric.schemaLookupMBean, 'getSchemaForClass(java.lang.String)', className, {
            method: 'POST',
            success: function (value) {
                cb(angular.fromJson(value));
            }
        });
    }
    Fabric.getDtoSchema = getDtoSchema;
    function getCurrentContainer(jolokia, fields) {
        var name = jolokia.getAttribute(Fabric.managerMBean, 'CurrentContainerName', {
            method: 'POST'
        });
        return jolokia.execute(Fabric.managerMBean, "getContainer(java.lang.String, java.util.List)", name, fields, {
            method: 'POST'
        });
    }
    Fabric.getCurrentContainer = getCurrentContainer;
    function getContainerFields(jolokia, name, fields) {
        return jolokia.execute(Fabric.managerMBean, "getContainer(java.lang.String, java.util.List)", name, fields, {
            method: 'POST'
        });
    }
    Fabric.getContainerFields = getContainerFields;
    function getRootContainers(jolokia) {
        var fields = [
            "id", 
            "root"
        ];
        var answer = jolokia.execute(Fabric.managerMBean, "containers(java.util.List)", fields, {
            method: 'POST'
        });
        return answer.filter({
            root: true
        }).map(function (v) {
            return v["id"];
        });
    }
    Fabric.getRootContainers = getRootContainers;
    function getOpenShiftDomains(workspace, jolokia, serverUrl, login, password, fn, onError) {
        if (typeof fn === "undefined") { fn = null; }
        if (typeof onError === "undefined") { onError = null; }
        if (hasOpenShiftFabric(workspace) && serverUrl && login && password) {
            var options = onSuccess(fn, {
                error: onError
            });
            return jolokia.execute(Fabric.openShiftFabricMBean, "getDomains", serverUrl, login, password, options);
        } else {
            if (fn) {
                fn([]);
            }
            return [];
        }
    }
    Fabric.getOpenShiftDomains = getOpenShiftDomains;
    function getOpenShiftGearProfiles(workspace, jolokia, serverUrl, login, password, fn) {
        if (typeof fn === "undefined") { fn = null; }
        if (hasOpenShiftFabric(workspace) && serverUrl && login && password) {
            return jolokia.execute(Fabric.openShiftFabricMBean, "getGearProfiles", serverUrl, login, password, onSuccess(fn));
        } else {
            if (fn) {
                fn([]);
            }
            return [];
        }
    }
    Fabric.getOpenShiftGearProfiles = getOpenShiftGearProfiles;
    function filterProfiles(jolokia, versionId, profileIds) {
        var profiles = [];
        if (versionId) {
            profiles = jolokia.execute(Fabric.managerMBean, "getProfiles(java.lang.String, java.util.List)", versionId, [
                'id', 
                'hidden', 
                'abstract'
            ], {
                method: 'POST'
            });
        }
        profiles = profiles.filter(function (profile) {
            return profileIds.some(function (id) {
                return profile.id === id;
            });
        });
        profiles = profiles.filter((function (profile) {
            return !profile.abstract && !profile.hidden;
        }));
        return profiles.map(function (p) {
            return p.id;
        });
    }
    Fabric.filterProfiles = filterProfiles;
    function getProfileData(jolokia, versionId, profileId, fields) {
        return jolokia.execute(Fabric.managerMBean, "getProfile(java.lang.String, java.lang.String, java.util.List)", versionId, profileId, fields, {
            method: 'POST'
        });
    }
    Fabric.getProfileData = getProfileData;
    function getConfigFile(jolokia, versionId, profileId, fileName, fn) {
        if (typeof fn === "undefined") { fn = null; }
        function onResults(answer) {
            return answer ? answer.decodeBase64() : null;
        }
        var callback = !fn ? null : function (result) {
            fn(onResults(result));
        };
        var answer = jolokia.execute(Fabric.managerMBean, "getConfigurationFile(java.lang.String, java.lang.String, java.lang.String)", versionId, profileId, fileName, onSuccess(callback));
        return fn ? answer : onResults(answer);
    }
    Fabric.getConfigFile = getConfigFile;
    function sanitizeJson(json) {
        angular.forEach(json, function (value, key) {
            if (value === "") {
                delete json[key];
            }
        });
        return json;
    }
    Fabric.sanitizeJson = sanitizeJson;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    Fabric.jmxDomain = 'org.fusesource.fabric';
    Fabric.templatePath = 'app/fabric/html/';
    Fabric.currentContainerId = '';
    angular.module('fabric', [
        'bootstrap', 
        'ui.bootstrap', 
        'ui.bootstrap.dialog', 
        'ngResource', 
        'ngGrid', 
        'hawtio-forms', 
        'hawtioCore', 
        'ngDragDrop', 
        'wiki'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/createFabric', {
            templateUrl: Fabric.templatePath + 'createFabric.html'
        }).when('/fabric/containers/createContainer', {
            templateUrl: Fabric.templatePath + 'createContainer.html',
            reloadOnSearch: false
        }).when('/fabric/map', {
            templateUrl: Fabric.templatePath + 'map.html'
        }).when('/fabric/clusters/*page', {
            templateUrl: Fabric.templatePath + 'clusters.html'
        }).when('/fabric/containers', {
            templateUrl: Fabric.templatePath + 'containers.html',
            reloadOnSearch: false
        }).when('/fabric/container/:containerId', {
            templateUrl: Fabric.templatePath + 'container.html'
        }).when('/fabric/assignProfile', {
            templateUrl: Fabric.templatePath + 'assignProfile.html'
        }).when('/fabric/activeProfiles', {
            templateUrl: Fabric.templatePath + 'activeProfiles.html'
        }).when('/wiki/profile/:versionId/:profileId/editFeatures', {
            templateUrl: Fabric.templatePath + 'editFeatures.html'
        }).when('/fabric/profile/:versionId/:profileId/:fname', {
            templateUrl: Fabric.templatePath + 'pid.html'
        }).when('/fabric/view', {
            templateUrl: Fabric.templatePath + 'fabricView.html',
            reloadOnSearch: false
        }).when('/fabric/migrate', {
            templateUrl: Fabric.templatePath + 'migrateVersions.html'
        }).when('/fabric/patching', {
            templateUrl: Fabric.templatePath + 'patching.html'
        }).when('/fabric/mq/brokers', {
            templateUrl: Fabric.templatePath + 'brokers.html'
        }).when('/fabric/mq/brokerDiagram', {
            templateUrl: Fabric.templatePath + 'brokerDiagram.html',
            reloadOnSearch: false
        }).when('/fabric/mq/brokerNetwork', {
            templateUrl: Fabric.templatePath + 'brokerNetwork.html'
        }).when('/fabric/mq/createBroker', {
            templateUrl: Fabric.templatePath + 'createBroker.html'
        }).when('/fabric/api', {
            templateUrl: Fabric.templatePath + 'apis.html'
        }).when('/fabric/api/wsdl', {
            templateUrl: 'app/api/html/wsdl.html'
        }).when('/fabric/api/wadl', {
            templateUrl: 'app/api/html/wadl.html'
        }).when('/fabric/test', {
            templateUrl: Fabric.templatePath + 'test.html'
        });
    }).directive('fabricVersionSelector', function () {
        return new Fabric.VersionSelector();
    }).directive('fabricProfileSelector', function () {
        return new Fabric.ProfileSelector();
    }).directive('fabricContainerList', function () {
        return new Fabric.ContainerList();
    }).directive('fabricProfileDetails', function () {
        return new Fabric.ProfileDetails();
    }).directive('fabricActiveProfileList', function () {
        return new Fabric.ActiveProfileList();
    }).directive('fabricProfileLink', function (workspace, jolokia, localStorage) {
        return {
            restrict: 'A',
            link: function ($scope, $element, $attrs) {
                var profileId = $attrs['fabricProfileLink'];
                if (profileId && !profileId.isBlank() && Fabric.fabricCreated(workspace)) {
                    var container = Fabric.getCurrentContainer(jolokia, [
                        'versionId'
                    ]);
                    var versionId = container['versionId'];
                    if (versionId && !versionId.isBlank()) {
                        var url = '#' + Fabric.profileLink(workspace, jolokia, localStorage, versionId, profileId);
                        if (angular.isDefined($attrs['file'])) {
                            url = url + "/" + $attrs['file'];
                        }
                        $element.attr('href', url);
                    }
                }
            }
        };
    }).directive('fabricContainers', function ($location, jolokia, workspace, $compile) {
        return {
            restrict: 'A',
            link: function ($scope, $element, $attrs) {
                var model = $attrs['fabricContainers'];
                var profileId = $attrs['profile'];
                var version = $scope.versionId || $scope.version || "1.0";
                if (model && !model.isBlank() && profileId && !profileId.isBlank()) {
                    Fabric.initScope($scope, $location, jolokia, workspace);
                    var containerIds = Fabric.getContainerIdsForProfile(jolokia, version, profileId);
                    Fabric.log.info("Searching for containers for profile: " + profileId + " version " + version + ". Found: " + containerIds);
                    $scope[model] = containerIds;
                    $scope["onCancel"] = function () {
                        console.log("In our new cancel thingy!");
                    };
                    var dialog = $("<div ng-include=\"'app/fabric/html/connectToContainerDialog.html'\"></div>");
                    var answer = $compile(dialog)($scope);
                    $element.append(answer);
                }
            }
        };
    }).directive('fabricContainerLink', function ($location, jolokia, workspace) {
        return {
            restrict: 'A',
            link: function ($scope, $element, $attrs) {
                var containerId = $attrs['fabricContainerLink'];
                if (containerId && !containerId.isBlank()) {
                    var fields = [
                        "alive", 
                        "provisionResult", 
                        "versionId", 
                        "jmxDomains"
                    ];
                    var container = Fabric.getContainerFields(jolokia, containerId, fields);
                    var link = "#/fabric/container/" + containerId;
                    var title = Fabric.statusTitle(container) || "container " + containerId;
                    var icon = Fabric.statusIcon(container) || "";
                    var html = "<a href='" + link + "' title='" + title + "'><i class='" + icon + "'></i> " + containerId + "</a>";
                    $element.html(html);
                    Core.$apply($scope);
                }
            }
        };
    }).directive('fabricContainerConnect', function ($location, jolokia) {
        return {
            restrict: 'A',
            link: function ($scope, $element, $attrs) {
                var containerId = $attrs['fabricContainerConnect'];
                var view = $attrs['view'];
                if (containerId && !containerId.isBlank()) {
                    var fields = [
                        "jolokiaUrl"
                    ];
                    var connectFn = function () {
                        var container = Fabric.getContainerFields(jolokia, containerId, fields);
                        Fabric.log.info("Connecting to container id " + containerId + " view + " + view);
                        container["id"] = containerId;
                        $scope.doConnect(container, view);
                        Core.$apply($scope);
                    };
                    $element.on("click", connectFn);
                }
            }
        };
    }).directive('fabricVersionLink', function (workspace, jolokia, localStorage) {
        return {
            restrict: 'A',
            link: function ($scope, $element, $attrs) {
                var versionLink = $attrs['fabricVersionLink'];
                if (versionLink && !versionLink.isBlank() && Fabric.fabricCreated(workspace)) {
                    var container = Fabric.getCurrentContainer(jolokia, [
                        'versionId'
                    ]);
                    var versionId = container['versionId'] || "1.0";
                    if (versionId && !versionId.isBlank()) {
                        var url = "#/wiki/branch/" + versionId + "/" + Core.trimLeading(versionLink, "/");
                        $element.attr('href', url);
                    }
                }
            }
        };
    }).run(function ($location, workspace, jolokia, viewRegistry, pageTitle, helpRegistry, layoutFull) {
        viewRegistry['fabric'] = Fabric.templatePath + 'layoutFabric.html';
        viewRegistry['createFabric'] = layoutFull;
        pageTitle.addTitleElement(function () {
            if (Fabric.currentContainerId === '' && Fabric.fabricCreated(workspace)) {
                try  {
                    Fabric.currentContainerId = jolokia.getAttribute(Fabric.managerMBean, 'CurrentContainerName', {
                        timeout: 1
                    });
                } catch (e) {
                }
            }
            return Fabric.currentContainerId;
        });
        workspace.topLevelTabs.push({
            content: "Create Fabric",
            title: "Create a fabric starting with this container",
            isValid: function (workspace) {
                return Fabric.canBootstrapFabric(workspace) && !Fabric.fabricCreated(workspace);
            },
            href: function () {
                return "#/createFabric";
            },
            isActive: function (workspace) {
                return workspace.isLinkActive("createFabric");
            }
        });
        workspace.topLevelTabs.push({
            content: "Runtime",
            title: "Manage your containers in this fabric",
            isValid: function (workspace) {
                return Fabric.isFMCContainer(workspace);
            },
            href: function () {
                return "#/fabric/containers";
            },
            isActive: function (workspace) {
                return workspace.isLinkActive("fabric");
            }
        });
        workspace.topLevelTabs.push({
            content: "Configuration",
            title: "Manage the configuration of your profiles in Fabric",
            isValid: function (workspace) {
                return Fabric.isFMCContainer(workspace);
            },
            href: function () {
                return "#/wiki/branch/" + Fabric.activeVersion($location) + "/view/fabric/profiles";
            },
            isActive: function (workspace) {
                return workspace.isLinkActive("/wiki") && (workspace.linkContains("fabric", "profiles") || workspace.linkContains("editFeatures"));
            }
        });
        workspace.topLevelTabs.push({
            id: "fabric.insight",
            content: "Insight",
            title: "View insight into your fabric looking at logs, metrics and messages across the fabric",
            isValid: function (workspace) {
                return Fabric.isFMCContainer(workspace) && Insight.hasInsight(workspace);
            },
            href: function () {
                return "#/insight/all?p=insight";
            },
            isActive: function (workspace) {
                return workspace.isLinkActive("/insight");
            }
        });
        helpRegistry.addUserDoc('fabric', 'app/fabric/doc/help.md', function () {
            return Fabric.isFMCContainer(workspace);
        });
        helpRegistry.addDevDoc("fabric", 'app/fabric/doc/developer.md');
    });
    hawtioPluginLoader.addModule('fabric');
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function FabricViewController($scope, $location, jolokia, localStorage, workspace) {
        Fabric.initScope($scope, $location, jolokia, workspace);
        $scope.containerArgs = [
            "id", 
            "alive", 
            "parentId", 
            "profileIds", 
            "versionId", 
            "provisionResult", 
            "jolokiaUrl", 
            "root"
        ];
        $scope.containersOp = 'containers(java.util.List)';
        $scope.ensembleContainerIdListOp = 'EnsembleContainers';
        $scope.init = function () {
            var activeVersionId = $location.search()['cv'];
            if (activeVersionId) {
                $scope.activeVersionId = activeVersionId;
                $scope.activeVersion = {
                    id: $scope.activeVersionId
                };
            }
            var profiles = $location.search()['sp'];
            $scope.selectedProfileIds = [];
            if (profiles) {
                $scope.selectedProfileIds = profiles.split(',');
            }
            var containers = $location.search()['sc'];
            $scope.selectedContainerIds = [];
            if (containers) {
                $scope.selectedContainerIds = containers.split(',');
            }
        };
        $scope.versions = [];
        $scope.profiles = [];
        $scope.containers = [];
        $scope.activeProfiles = [];
        $scope.activeVersion = {};
        $scope.activeVersionId = '';
        $scope.selectedContainers = [];
        $scope.selectedProfiles = [];
        $scope.selectedActiveProfiles = [];
        $scope.dialogProfiles = [];
        $scope.profileIdFilter = '';
        $scope.activeProfileIdFilter = '';
        $scope.containerIdFilter = '';
        $scope.filterActiveVersion = false;
        $scope.filterActiveProfile = false;
        $scope.deleteVersionDialog = new Core.Dialog();
        $scope.deleteProfileDialog = new Core.Dialog();
        $scope.createProfileDialog = new Core.Dialog();
        $scope.ensembleContainerIds = [];
        $scope.profileSelectedAll = false;
        $scope.targetContainer = {};
        $scope.triggerResize = function () {
            setTimeout(function () {
                $('.dialogGrid').trigger('resize');
            }, 10);
        };
        $scope.$watch('createProfileDialog', function () {
            if ($scope.createProfileDialog) {
                $scope.triggerResize();
            }
        });
        $scope.$watch('createVersionDialog', function () {
            if ($scope.createVersionDialog) {
                $scope.triggerResize();
            }
        });
        $scope.newProfileName = '';
        $scope.selectedParents = [];
        $scope.selectedParentVersion = [];
        $scope.$on('$routeUpdate', $scope.init);
        $scope.$watch('activeVersionId', function (oldValue, newValue) {
            $location.search('cv', $scope.activeVersionId);
        });
        $scope.$watch('activeVersion', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $scope.activeVersionId = $scope.activeVersion.id;
            }
        });
        $scope.$watch('containers', function (oldValue, newValue) {
            if (oldValue !== newValue) {
                $scope.selectedContainers = $scope.containers.filter(function (c) {
                    return c.selected;
                });
                if ($scope.selectedContainers.length > 0) {
                    $scope.activeContainerId = '';
                }
            }
        }, true);
        $scope.$watch('activeProfiles', function (oldValue, newValue) {
            if (oldValue !== newValue) {
                $scope.selectedActiveProfiles = $scope.activeProfiles.filter(function (ap) {
                    return ap.selected;
                });
            }
        }, true);
        $scope.$watch('selectedProfiles', function (oldValue, newValue) {
            if (oldValue !== newValue) {
                var ids = $scope.getSelectedProfileIds().join(',');
                $location.search('sp', ids);
            }
        }, true);
        $scope.$watch('selectedContainers', function (oldValue, newValue) {
            if (oldValue !== newValue) {
                var ids = $scope.getSelectedContainerIds().join(',');
                $location.search('sc', ids);
            }
        }, true);
        $scope.init();
        $scope.doCreateProfile = function (newProfileName, selectedParents) {
            $scope.newProfileName = newProfileName;
            $scope.createProfileDialog.close();
            var parents = selectedParents.map(function (profile) {
                return profile.id;
            });
            Fabric.createProfile(jolokia, $scope.activeVersionId, $scope.newProfileName, parents, function () {
                notification('success', "Created profile " + $scope.newProfileName);
                $scope.profileIdFilter = $scope.newProfileName;
                $scope.newProfileName = "";
                Core.$apply($scope);
            }, function (response) {
                notification('error', "Failed to create profile " + $scope.newProfileName + " due to " + response.error);
                Core.$apply($scope);
            });
        };
        $scope.deleteVersion = function () {
            var id = $scope.activeVersionId;
            Fabric.deleteVersion(jolokia, id, function () {
                notification('success', "Deleted version " + id);
                $scope.activeVersionId = '';
                Core.$apply($scope);
            }, function (response) {
                notification('error', "Failed to delete version " + id + " due to " + response.error);
                Core.$apply($scope);
            });
        };
        $scope.deleteSelectedProfiles = function () {
            $scope.selectedProfiles.each(function (profile) {
                var profileId = profile.id;
                Fabric.deleteProfile(jolokia, $scope.activeVersionId, profileId, function () {
                    notification('success', "Deleted profile " + profileId);
                }, function (response) {
                    notification('error', "Failed to delete profile " + profileId + ' due to ' + response.error);
                });
            });
        };
        $scope.patchVersion = function (versionId) {
            $location.url('/fabric/patching').search({
                versionId: versionId
            });
        };
        $scope.migrateVersion = function (targetName, sourceName) {
            notification('info', "Moving " + targetName + " to " + sourceName);
            Fabric.migrateContainers(jolokia, sourceName, [
                targetName
            ], function () {
                notification('success', "Moved " + targetName + " to version " + sourceName);
            }, function (response) {
                notification('error', "Failed to move " + targetName + " to version " + sourceName + " due to " + response.error);
            });
        };
        $scope.addProfiles = function (targetName, profiles) {
            notification('info', "Adding " + profiles.join(', ') + " to " + targetName);
            Fabric.addProfilesToContainer(jolokia, targetName, profiles, function () {
                notification('success', "Added " + profiles.join(', ') + " to " + targetName);
            }, function (response) {
                notification('error', "Failed to add " + profiles.join(', ') + " to " + targetName + " due to " + response.error);
            });
        };
        $scope.removeActiveProfiles = function () {
            $scope.selectedActiveProfiles.each(function (profile) {
                $scope.removeActiveProfile(profile);
            });
        };
        $scope.removeActiveProfile = function (profile) {
            if ($scope.selectedContainers.length > 0) {
                $scope.selectedContainers.each(function (container) {
                    if (container.profileIds.some(profile.id) && container.versionId === profile.versionId) {
                        $scope.removeProfile(container.id, profile.id);
                    }
                });
            } else {
                $scope.removeProfile($scope.activeContainerId, profile.id);
            }
        };
        $scope.removeProfile = function (containerId, profileId) {
            notification('info', "Removing " + profileId + " from " + containerId);
            Fabric.removeProfilesFromContainer(jolokia, containerId, [
                profileId
            ], function () {
                notification('success', "Removed " + profileId + " from " + containerId);
            }, function (response) {
                notification('error', "Failed to remove " + profileId + " from " + containerId + " due to " + response.error);
            });
        };
        $scope.getFilteredName = function (item) {
            return item.versionId + " / " + item.id;
        };
        $scope.filterContainer = function (container) {
            if (!$scope.getFilteredName(container).has($scope.containerIdFilter)) {
                return false;
            }
            if ($scope.selectedActiveProfiles.length > 0) {
                if ($scope.selectedActiveProfiles.none(function (ap) {
                    return ap.versionId === container.versionId && container.profileIds.some(ap.id);
                })) {
                    return false;
                }
            }
            return true;
        };
        $scope.filterActiveProfile = function (profile) {
            if (!$scope.getFilteredName(profile).has($scope.activeProfileIdFilter)) {
                return false;
            }
            if ($scope.filterActiveVersion && $scope.activeVersionId && $scope.activeVersionId !== '' && profile.versionId !== $scope.activeVersionId) {
                return false;
            }
            if ($scope.selectedContainers.length > 0) {
                if ($scope.selectedContainers.none(function (c) {
                    return c.versionId === profile.versionId && c.profileIds.some(profile.id);
                })) {
                    return false;
                }
            }
            if ($scope.activeContainerId && $scope.activeContainerId !== '') {
                if ($scope.activeContainerVersion && $scope.activeContainerVersion !== '' && $scope.activeContainerVersion !== profile.versionId) {
                    return false;
                }
                if (!profile.containers.some($scope.activeContainerId)) {
                    return false;
                }
            }
            return true;
        };
        $scope.showMigrateButton = function () {
            return $scope.selectedContainers.length > 0 && $scope.activeVersionId && $scope.activeVersionId !== '';
        };
        $scope.applyVersionToContainers = function () {
            $scope.selectedContainers.each(function (c) {
                $scope.migrateVersion(c.id, $scope.activeVersionId);
            });
        };
        $scope.showProfileAddButton = function () {
            return $scope.selectedProfiles.length > 0 && $scope.selectedContainers.length > 0 && $scope.selectedContainers.every(function (c) {
                return c.versionId === $scope.activeVersionId;
            });
        };
        $scope.addProfilesToContainers = function () {
            var profileIds = $scope.selectedProfiles.map(function (p) {
                return p.id;
            });
            $scope.selectedContainers.each(function (c) {
                $scope.addProfiles(c.id, profileIds);
            });
        };
        $scope.versionCanBeDeleted = function () {
            return $scope.containers.none(function (c) {
                return c.versionId === $scope.activeVersionId;
            });
        };
        $scope.profilesCanBeDeleted = function () {
            var possibleMatches = $scope.containers.filter(function (c) {
                return c.versionId === $scope.activeVersionId;
            });
            if (possibleMatches.length === 0) {
                return true;
            }
            possibleMatches = possibleMatches.filter(function (c) {
                return $scope.selectedProfiles.some(function (p) {
                    return c.profileIds.some(p.id);
                });
            });
            if (possibleMatches.length === 0) {
                return true;
            }
            return false;
        };
        $scope.getSelectedProfileIds = function () {
            return $scope.getIds($scope.selectedProfiles);
        };
        $scope.getSelectedContainerIds = function () {
            return $scope.getIds($scope.selectedContainers);
        };
        $scope.getIds = function (arr) {
            return arr.map(function (o) {
                return o.id;
            });
        };
        $scope.getStatusTitle = function (container) {
            return Fabric.statusTitle(container);
        };
        $scope.containersForVersion = function (id) {
            var count = $scope.containers.findAll(function (container) {
                return container.versionId === id;
            }).length;
            if (count === 0) {
                return '';
            }
            return "(" + count + ")";
        };
        $scope.containersForProfile = function (id) {
            var profile = $scope.currentActiveProfiles().find(function (profile) {
                return profile.versionId === $scope.activeVersionId && profile.id === id;
            });
            if (profile) {
                return "(" + profile.count + ")";
            } else {
                return "";
            }
        };
        $scope.isSelectedVersion = function (id) {
            if ($scope.activeVersionId === id) {
                return 'selected';
            }
            return '';
        };
        $scope.getSelectedClass = function (obj) {
            var answer = [];
            if (obj.selected) {
                answer.push('selected');
            }
            if (angular.isDefined(obj['root']) && obj['root'] === false) {
                answer.push('child-container');
            }
            return answer.join(' ');
        };
        $scope.setActiveVersionId = function (id) {
            $scope.activeVersionId = id;
        };
        $scope.showProfile = function (profile) {
            if (angular.isDefined(profile.versionId)) {
                Fabric.gotoProfile(workspace, jolokia, localStorage, $location, profile.versionId, profile);
            } else {
                Fabric.gotoProfile(workspace, jolokia, localStorage, $location, $scope.activeVersionId, profile);
            }
        };
    }
    Fabric.FabricViewController = FabricViewController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    Fabric.startMaps = function () {
    };
    function MapController($scope, $templateCache, jolokia) {
        $scope.myMarkers = [];
        $scope.containers = {};
        $scope.template = "";
        $scope.start = function () {
            $scope.mapOptions = {
                center: new google.maps.LatLng(35.784, -78.670),
                zoom: 15,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            Core.register(jolokia, $scope, {
                type: 'exec',
                mbean: Fabric.managerMBean,
                operation: 'containers()',
                arguments: []
            }, onSuccess(render));
            $scope.template = $templateCache.get("pageTemplate");
        };
        Fabric.startMaps = $scope.start;
        $('body').append('<script type="text/javascript" src="//maps.google.com/maps/api/js?sensor=false&async=2&callback=Fabric.startMaps"></script>');
        $scope.addMarker = function ($event) {
            $scope.myMarkers.push(new google.maps.Marker({
                map: $scope.myMap,
                position: $event.latLng
            }));
        };
        $scope.setZoomMessage = function (zoom) {
            console.log(zoom, 'zoomed');
        };
        $scope.openMarkerInfo = function (marker) {
            $scope.currentMarker = marker;
            $scope.currentMarkerLat = marker.getPosition().lat();
            $scope.currentMarkerLng = marker.getPosition().lng();
            $scope.myInfoWindow.open($scope.myMap, marker);
        };
        $scope.setMarkerPosition = function (marker, lat, lng) {
            marker.setPosition(new google.maps.LatLng(lat, lng));
        };
        function render(response) {
            if (response && response.value) {
                response.value.forEach(function (container) {
                    var addMarker = false;
                    var id = container.id;
                    var containerData = $scope.containers[id];
                    if (!containerData) {
                        containerData = {
                            name: id
                        };
                        $scope.containers[id] = containerData;
                        addMarker = true;
                    }
                    containerData.alive = container.alive;
                    containerData.version = container.versionId;
                    containerData.profileIds = container.profileIds;
                    var geoLocation = container["geoLocation"];
                    if (geoLocation) {
                        var values = geoLocation.split(",");
                        if (values.length >= 2) {
                            var lattitude = Core.parseFloatValue(values[0], "lattitude");
                            var longitude = Core.parseFloatValue(values[1], "longitude");
                            if (lattitude && longitude) {
                                var marker = containerData.marker;
                                if (addMarker || !marker) {
                                    marker = new google.maps.Marker({
                                        map: $scope.myMap,
                                        position: new google.maps.LatLng(lattitude, longitude),
                                        title: container.id
                                    });
                                    containerData.marker = marker;
                                    $scope.myMarkers.push(marker);
                                    if ($scope.myMarkers.length === 1) {
                                        if ($scope.myMap) {
                                            $scope.myMap.panTo(marker.getPosition());
                                        }
                                    }
                                } else {
                                    if (containerData.marker) {
                                        containerData.marker.position = new google.maps.LatLng(lattitude, longitude);
                                    }
                                }
                                containerData.lattitude = lattitude;
                                containerData.longitude = longitude;
                            }
                        }
                    }
                });
                Core.$apply($scope);
            }
        }
    }
    Fabric.MapController = MapController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function MigrateContainersController($scope, jolokia, $location) {
        $scope.versions = [];
        $scope.containers = [];
        $scope.containersResponse = [];
        $scope.selectedVersion = [];
        $scope.selectedContainers = [];
        $scope.showApply = false;
        $scope.versionGridOptions = {
            data: 'versions',
            selectedItems: $scope.selectedVersion,
            showSelectionCheckbox: true,
            multiSelect: false,
            keepLastSelected: true,
            columnDefs: [
                {
                    field: 'id',
                    displayName: 'Version Name',
                    width: '94%'
                }
            ],
            filterOptions: {
                filterText: ''
            }
        };
        $scope.containerGridOptions = {
            data: 'containers',
            selectedItems: $scope.selectedContainers,
            showSelectionCheckbox: true,
            multiSelect: true,
            keepLastSelected: false,
            columnDefs: [
                {
                    field: 'id',
                    displayName: 'Container Name',
                    width: '94%'
                }
            ],
            filterOptions: {
                filterText: ''
            }
        };
        $scope.canApply = function () {
            return !($scope.selectedVersion.length > 0 && $scope.selectedContainers.length > 0);
        };
        $scope.render = function (response) {
            if (response.request.operation === 'versions()') {
                if (!Object.equal($scope.versions, response.value)) {
                    $scope.versions = response.value;
                    Core.$apply($scope);
                }
            }
            if (response.request.operation === 'containerIds()') {
                if (!Object.equal($scope.containersResponse, response.value)) {
                    $scope.containersResponse = response.value;
                    $scope.containers = [];
                    $scope.containersResponse.each(function (container) {
                        $scope.containers.push({
                            id: container
                        });
                    });
                    Core.$apply($scope);
                }
            }
        };
        $scope.migrateContainers = function () {
            var containerIds = $scope.selectedContainers.map(function (container) {
                return container.id;
            });
            var versionId = $scope.selectedVersion[0].id;
            notification('info', "Moving containers to version " + versionId);
            $location.path("/fabric/containers");
            Fabric.migrateContainers(jolokia, versionId, containerIds, function () {
                notification('success', "Successfully migrated containers");
            }, function (response) {
                notification('error', "Failed to migrate containers due to " + response.error);
            });
        };
        Core.register(jolokia, $scope, [
            {
                type: 'exec',
                mbean: Fabric.managerMBean,
                operation: 'versions()'
            }, 
            {
                type: 'exec',
                mbean: Fabric.managerMBean,
                operation: 'containerIds()'
            }
        ], onSuccess($scope.render));
    }
    Fabric.MigrateContainersController = MigrateContainersController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function NavBarController($scope, $location, jolokia, workspace, localStorage) {
        $scope.activeVersion = "1.0";
        $scope.mapsEnabled = localStorage['fabricEnableMaps'];
        $scope.$on('$routeUpdate', reloadVersion);
        $scope.isActive = function (href) {
            return workspace.isLinkActive(href);
        };
        $scope.clusterLink = function () {
            return Core.createHref($location, "#/fabric/clusters/fabric/registry/clusters", [
                "cv", 
                "cp", 
                "pv"
            ]);
        };
        function reloadVersion() {
            $scope.activeVersion = Fabric.activeVersion($location);
        }
        function reloadData() {
            reloadVersion();
            $scope.hasFabric = Fabric.hasFabric(workspace);
            $scope.hasMQManager = Fabric.hasMQManager(workspace);
            if ($scope.hasFabric) {
                var containerId = null;
                Fabric.containerWebAppURL(jolokia, "drools-wb-distribution-wars", containerId, onDroolsUrl, onDroolsUrl);
                $scope.canUpload = workspace.treeContainsDomainAndProperties('hawtio', {
                    type: 'UploadManager'
                });
            }
        }
        reloadData();
        function onDroolsUrl(response) {
            var url = response ? response.value : null;
            console.log("========== onDroolsUrl: " + url);
            $scope.droolsHref = url;
            Core.$apply($scope);
        }
    }
    Fabric.NavBarController = NavBarController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function PatchingController($scope, jolokia, localStorage, $location) {
        $scope.files = [];
        $scope.targetVersion = $location.search()['versionId'];
        $scope.newVersionName = '';
        $scope.proxyUser = localStorage['fabric.userName'];
        $scope.proxyPassword = localStorage['fabric.password'];
        $scope.saveJmxCredentials = false;
        $scope.cancel = function () {
            $location.url('/fabric/view').search({
                cv: $scope.targetVersion
            });
        };
        $scope.valid = function () {
            return $scope.files && $scope.files.length > 0 && $scope.targetVersion !== null && $scope.proxyUser && $scope.proxyPassword;
        };
        $scope.go = function () {
            var message = $scope.files.length + ' patches';
            if ($scope.files.length === 1) {
                message = "patch: " + $scope.files[0].fileName;
            }
            notification('info', "Applying " + message);
            if ($scope.saveJmxCredentials) {
                localStorage['fabric.userName'] = $scope.proxyUser;
                localStorage['fabric.password'] = $scope.proxyPassword;
            }
            var files = $scope.files.map(function (file) {
                return file.absolutePath;
            });
            Fabric.applyPatches(jolokia, files, $scope.targetVersion.id, $scope.newVersionName, $scope.proxyUser, $scope.proxyPassword, function () {
                notification('success', "Successfully applied " + message);
                $location.url("/fabric/view");
                Core.$apply($scope);
            }, function (response) {
                notification('error', "Failed to apply " + message + " due to " + response.error);
                Core.$apply($scope);
            });
        };
    }
    Fabric.PatchingController = PatchingController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function PIDController($scope, $routeParams, jolokia, $location) {
        $scope.versionId = $routeParams.versionId;
        $scope.profileId = $routeParams.profileId;
        $scope.fname = $routeParams.fname;
        $scope.response = undefined;
        $scope.data = "";
        $scope.dirty = false;
        $scope.getMode = function () {
            var parts = $scope.fname.split('.');
            var mode = parts[parts.length - 1];
            if (!mode) {
                return 'text';
            }
            switch(mode) {
                case 'cfg':
                    mode = "properties";
                    break;
            }
            return mode;
        };
        $scope.mode = $scope.getMode();
        if (angular.isDefined($scope.versionId) && angular.isDefined($scope.profileId) && angular.isDefined($scope.fname)) {
            Core.register(jolokia, $scope, {
                type: 'exec',
                mbean: Fabric.managerMBean,
                operation: 'getConfigurationFile(java.lang.String,java.lang.String,java.lang.String)',
                arguments: [
                    $scope.versionId, 
                    $scope.profileId, 
                    $scope.fname
                ]
            }, onSuccess(render));
        }
        $scope.save = function () {
            Fabric.saveConfigFile(jolokia, $scope.versionId, $scope.profileId, $scope.fname, $scope.data.encodeBase64(), function () {
                $scope.dirty = false;
                notification('success', "Saved " + $scope.fname);
                $location.path("/fabric/profile/" + $scope.versionId + "/" + $scope.profileId);
            }, function (response) {
                notification('error', "Failed to save " + $scope.fname + " due to " + response.error);
            });
        };
        function stringToBytes(s) {
            return s.codes();
        }
        function bytesToString(b) {
            var answer = [];
            b.forEach(function (b) {
                answer.push(String.fromCharCode(b));
            });
            return answer.join('');
        }
        function render(response) {
            if (!Object.equal($scope.response, response.value)) {
                $scope.response = response.value;
                $scope.data = $scope.response.decodeBase64();
                $scope.mode = $scope.getMode();
                Core.$apply($scope);
            }
        }
    }
    Fabric.PIDController = PIDController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function ProfileController($scope, $routeParams, jolokia, $location, workspace, $q) {
        Fabric.initScope($scope, $location, jolokia, workspace);
        $scope.loading = true;
        $scope.mavenMBean = Maven.getMavenIndexerMBean(workspace);
        if (!angular.isDefined($scope.versionId)) {
            $scope.versionId = $routeParams.versionId;
        }
        if (!angular.isDefined($scope.profileId)) {
            $scope.profileId = $routeParams.profileId;
        }
        $scope.newFileDialog = false;
        $scope.deleteFileDialog = false;
        $scope.newFileName = '';
        $scope.markedForDeletion = '';
        $scope.newProfileName = '';
        $scope.deleteThingDialog = false;
        $scope.changeParentsDialog = false;
        $scope.removeParentDialog = false;
        $scope.newThingName = '';
        $scope.selectedParents = [];
        $scope.profilePath = Fabric.profilePath;
        if ($scope.inDirective && angular.isDefined($scope.$parent.childActions) && $scope.versionId) {
            var actions = $scope.$parent.childActions;
            if ($scope.profileId) {
                actions.push({
                    doAction: function () {
                        $scope.showChangeParentsDialog();
                    },
                    title: "Edit parent profiles",
                    icon: "icon-edit",
                    name: "Change Parents"
                });
                actions.push({
                    doAction: function () {
                        $scope.copyProfileDialog = true;
                    },
                    title: "Copy Profile",
                    icon: "icon-copy",
                    name: "Copy Profile"
                });
                actions.push({
                    doAction: function () {
                        $scope.goto('/wiki/profile/' + $scope.versionId + '/' + $scope.profileId + '/editFeatures');
                    },
                    title: "Edit the features defined in this profile",
                    icon: "icon-edit",
                    name: "Edit Features"
                });
                actions.push({
                    doAction: function () {
                        $location.url('/fabric/assignProfile').search({
                            vid: $scope.versionId,
                            pid: $scope.profileId
                        });
                    },
                    title: "Assign profile to existing containers",
                    icon: "icon-truck",
                    name: "Assign to Container"
                });
                actions.push({
                    doAction: function () {
                        $location.url('/fabric/containers/createContainer').search({
                            versionId: $scope.versionId,
                            profileIds: $scope.profileId
                        });
                    },
                    title: "Create a new container with this profile",
                    icon: "icon-truck",
                    name: "New Container"
                });
            }
            var createVersionDialog = $scope.createVersionDialog;
            if (createVersionDialog) {
                actions.push({
                    doAction: function () {
                        $scope.createVersionDialog.open();
                    },
                    title: "Create a new version of this configuration so you can edit it and then perform rolling upgrades",
                    icon: "icon-plus",
                    name: "New Version"
                });
            }
        }
        $scope.$watch('activeTab', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $scope.newThingName = '';
            }
        });
        $scope.$watch('versionId', function (newValue, oldValue) {
            if (angular.isDefined($scope.versionId) && angular.isDefined($scope.profileId)) {
                $scope.doRegister();
            }
        });
        $scope.$watch('profileId', function (newValue, oldValue) {
            if (angular.isDefined($scope.versionId) && angular.isDefined($scope.profileId)) {
                $scope.doRegister();
            }
        });
        $scope.doCompletionFabric = function (something) {
            if (something.startsWith("mvn:")) {
                $scope.prefix = "mvn:";
                return Maven.completeMavenUri($q, $scope, workspace, jolokia, something.from(4));
            }
            $scope.prefix = "";
            return $q.when([]);
        };
        $scope.uriParts = [];
        $scope.$watch('newThingName', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $scope.uriParts = newValue.split("/");
            }
        });
        $scope.$watch('uriParts', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                if (!$scope.prefix || $scope.prefix === '') {
                    return;
                }
                if (newValue && newValue.length > 0 && !newValue.first().startsWith($scope.prefix)) {
                    if (newValue.first() === "" || newValue.first().length < $scope.prefix.length) {
                        return;
                    }
                    if (oldValue.length === 0) {
                        return;
                    }
                    if (oldValue.length === 1) {
                        $scope.newThingName = $scope.prefix + newValue.first();
                    } else {
                        var merged = oldValue.first(oldValue.length - 1).include(newValue.first());
                        $scope.newThingName = merged.join('/');
                    }
                }
            }
        }, true);
        $scope.doRegister = function () {
            Core.unregister(jolokia, $scope);
            if ($scope.versionId && $scope.profileId && !$scope.versionId.isBlank() && !$scope.profileId.isBlank()) {
                Core.register(jolokia, $scope, {
                    type: 'exec',
                    mbean: Fabric.managerMBean,
                    operation: 'getProfile(java.lang.String, java.lang.String)',
                    arguments: [
                        $scope.versionId, 
                        $scope.profileId
                    ]
                }, onSuccess(render));
            }
        };
        $scope.showChangeParentsDialog = function () {
            $scope.selectedParents = $scope.row.parentIds.map(function (parent) {
                return {
                    id: parent,
                    selected: true
                };
            });
            $scope.changeParentsDialog = true;
        };
        $scope.removeParentProfile = function (parent) {
            $scope.markedForDeletion = parent;
            $scope.removeParentDialog = true;
        };
        $scope.doRemoveParentProfile = function () {
            var parents = $scope.row.parentIds.exclude($scope.markedForDeletion);
            Fabric.changeProfileParents(jolokia, $scope.versionId, $scope.profileId, parents, function () {
                notification('success', 'Removed parent profile ' + $scope.markedForDeletion + ' from ' + $scope.profileId);
                Core.$apply($scope);
            }, function (response) {
                notification('error', 'Failed to change parent profiles of ' + $scope.profileId + ' due to ' + response.error);
                Core.$apply($scope);
            });
        };
        $scope.changeAttribute = function (attribute, value) {
            jolokia.request({
                type: 'exec',
                method: 'post',
                mbean: Fabric.managerMBean,
                operation: 'setProfileAttribute',
                arguments: [
                    $scope.versionId, 
                    $scope.profileId, 
                    attribute, 
                    value
                ]
            }, {
                success: function () {
                    Core.$apply($scope);
                },
                error: function (response) {
                    console.log("Failed to set attribute " + attribute + " to " + value + " due to " + response.error);
                    Core.$apply($scope);
                }
            });
        };
        $scope.doChangeParents = function () {
            $scope.changeParentsDialog = false;
            var parents = $scope.selectedParents.map(function (parent) {
                return parent.id;
            });
            Fabric.changeProfileParents(jolokia, $scope.versionId, $scope.profileId, parents, function () {
                notification('success', 'Successfully changed parent profiles of ' + $scope.profileId);
                Core.$apply($scope);
            }, function (response) {
                notification('error', 'Failed to change parent profiles of ' + $scope.profileId + ' due to ' + response.error);
                Core.$apply($scope);
            });
        };
        $scope.goto = function (location) {
            $location.url(location);
        };
        $scope.addNewThing = function (title, type, current) {
            $scope.thingName = title;
            $scope.currentThing = current;
            $scope.currentThingType = type;
            $scope.doAddThing();
        };
        $scope.deleteThing = function (title, type, current, item) {
            $scope.thingName = title;
            $scope.currentThing = current;
            $scope.currentThingType = type;
            $scope.currentThingItem = item;
            $scope.deleteThingDialog = true;
        };
        $scope.updateThing = function (title, type, current) {
            $scope.thingName = title;
            $scope.currentThing = current;
            $scope.currentThingType = type;
            $scope.callSetProfileThing("Changed", "change", title);
        };
        $scope.mavenLink = function (url) {
            return Maven.mavenLink(url);
        };
        $scope.callSetProfileThing = function (success, error, thing) {
            jolokia.request({
                type: 'exec',
                mbean: Fabric.managerMBean,
                operation: "setProfile" + $scope.currentThingType + "(java.lang.String, java.lang.String, java.util.List)",
                arguments: [
                    $scope.versionId, 
                    $scope.profileId, 
                    $scope.currentThing
                ]
            }, {
                method: 'POST',
                success: function () {
                    notification('success', success + ' ' + thing);
                    $scope.newThingName = '';
                    Core.$apply($scope);
                },
                error: function (response) {
                    notification('error', 'Failed to ' + error + ' ' + thing + ' due to ' + response.error);
                    Core.$apply($scope);
                }
            });
        };
        $scope.doDeleteThing = function () {
            $scope.currentThing.remove($scope.currentThingItem);
            $scope.callSetProfileThing('Deleted', 'delete', $scope.currentThingItem);
        };
        $scope.doAddThing = function () {
            if (!$scope.currentThing.any($scope.newThingName)) {
                $scope.currentThing.push($scope.newThingName);
                $scope.addThingDialog = false;
                $scope.callSetProfileThing('Added', 'add', $scope.newThingName);
            } else {
                notification('error', 'There is already a ' + $scope.thingName + ' with the name ' + $scope.newThingName);
            }
        };
        $scope.deleteFile = function (file) {
            $scope.markedForDeletion = file;
            $scope.deleteFileDialog = true;
        };
        $scope.doDeleteFile = function () {
            $scope.deleteFileDialog = false;
            Fabric.deleteConfigFile(jolokia, $scope.versionId, $scope.profileId, $scope.markedForDeletion, function () {
                notification('success', 'Deleted file ' + $scope.markedForDeletion);
                $scope.markedForDeletion = '';
                Core.$apply($scope);
            }, function (response) {
                notification('error', 'Failed to delete file ' + $scope.markedForDeletion + ' due to ' + response.error);
                $scope.markedForDeletion = '';
                Core.$apply($scope);
            });
        };
        $scope.doCreateFile = function () {
            $scope.newFileDialog = false;
            Fabric.newConfigFile(jolokia, $scope.versionId, $scope.profileId, $scope.newFileName, function () {
                notification('success', 'Created new configuration file ' + $scope.newFileName);
                $location.path("/fabric/profile/" + $scope.versionId + "/" + $scope.profileId + "/" + $scope.newFileName);
            }, function (response) {
                notification('error', 'Failed to create ' + $scope.newFileName + ' due to ' + response.error);
            });
        };
        $scope.copyProfile = function () {
            $scope.copyProfileDialog = false;
            notification('info', 'Copying ' + $scope.profileId + ' to ' + $scope.newProfileName);
            Fabric.copyProfile(jolokia, $scope.versionId, $scope.profileId, $scope.newProfileName, true, function () {
                notification('success', 'Created new profile ' + $scope.newProfileName);
                Fabric.gotoProfile(workspace, jolokia, localStorage, $location, $scope.versionId, {
                    id: $scope.newProfileName
                });
                Core.$apply($scope);
            }, function (response) {
                notification('error', 'Failed to create new profile ' + $scope.newProfileName + ' due to ' + response.error);
                Core.$apply($scope);
            });
        };
        function render(response) {
            if (!angular.isDefined($scope.row)) {
                $scope.loading = false;
            }
            var responseJson = angular.toJson(response.value);
            if ($scope.profileResponseJson !== responseJson) {
                if (!$scope.activeTab) {
                    $scope.activeTab = "features";
                }
                $scope.profileResponseJson = responseJson;
                $scope.row = response.value;
                var id = $scope.row.id;
                var version = $scope.row.version;
                $scope.configFolderLink = null;
                if ($scope.hasFabricWiki() && id && version) {
                    $scope.configFolderLink = "#/wiki/branch/" + version + "/view/fabric/profiles/" + Fabric.profilePath(id);
                }
                Core.$apply($scope);
            }
        }
    }
    Fabric.ProfileController = ProfileController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    var ProfileDetails = (function () {
        function ProfileDetails() {
            this.restrict = 'A';
            this.replace = true;
            this.templateUrl = Fabric.templatePath + "profileDetailsDirective.html";
            this.scope = {
                versionId: '=',
                profileId: '='
            };
            this.controller = function ($scope, $element, $attrs, $routeParams, jolokia, $location, workspace, $q) {
                $scope.inDirective = true;
                Fabric.ProfileController($scope, $routeParams, jolokia, $location, workspace, $q);
            };
        }
        return ProfileDetails;
    })();
    Fabric.ProfileDetails = ProfileDetails;    
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    var ProfileSelector = (function () {
        function ProfileSelector() {
            this.restrict = 'A';
            this.replace = true;
            this.templateUrl = Fabric.templatePath + "profileSelector.html";
            this.scope = {
                selectedProfiles: '=fabricProfileSelector',
                versionId: '=',
                filterWatch: '@',
                selectedWatch: '@',
                clearOnVersionChange: '@',
                showLinks: '@',
                showHeader: '@',
                useCircles: '@',
                expanded: '@',
                excludedProfiles: '=',
                includedProfiles: '='
            };
            this.controller = function ($scope, $element, $attrs, workspace, jolokia, localStorage, $location) {
                $scope.profiles = [];
                $scope.responseJson = '';
                $scope.filterText = '';
                $scope.clearOnVersionChange = false;
                $scope.showLinks = false;
                $scope.selectedAll = false;
                $scope.indeterminate = false;
                $scope.showFilter = true;
                $scope.useCircles = false;
                $scope.expanded = false;
                $scope.tree = [];
                $scope.showProfile = function (profile) {
                    return $scope.filterText.isBlank() || profile.id.has($scope.filterText);
                };
                $scope.showBranch = function (branch) {
                    return $scope.filterText.isBlank() || branch.profiles.some(function (profile) {
                        return profile.id.has($scope.filterText);
                    });
                };
                $scope.goto = function (profile) {
                    Fabric.gotoProfile(workspace, jolokia, localStorage, $location, $scope.versionId, profile);
                };
                $scope.render = function (response) {
                    var responseJson = angular.toJson(response.value);
                    if ($scope.responseJson !== responseJson) {
                        $scope.responseJson = responseJson;
                        var selected = $scope.selectedProfiles;
                        $scope.profiles = response.value.sortBy(function (profile) {
                            return profile.id;
                        });
                        angular.forEach(selected, function (profile) {
                            var p = $scope.profiles.find(function (p) {
                                return p.id === profile.id;
                            });
                            if (p && profile) {
                                p.selected = profile.selected;
                            }
                        });
                        $scope.profiles = $scope.profiles.exclude(function (p) {
                            return p.hidden;
                        });
                        if ($scope.excludedProfiles) {
                            $scope.profiles = $scope.excluded();
                        }
                        if ($scope.includedProfiles) {
                            $scope.profiles = $scope.included();
                        }
                        var paths = [];
                        $scope.profiles.each(function (profile) {
                            var path = profile.id.split('-');
                            profile.name = path.last();
                            profile.path = path.exclude(profile.name).join(' / ');
                            paths.push(profile.path);
                        });
                        paths = paths.unique().sortBy('length').sortBy(function (n) {
                            return n;
                        });
                        var tree = [];
                        paths.forEach(function (path) {
                            var branch = {
                                expanded: $scope.expanded,
                                path: path,
                                profiles: $scope.profiles.filter(function (profile) {
                                    return profile.path === path;
                                })
                            };
                            tree.push(branch);
                        });
                        $scope.tree = tree;
                        Core.$apply($scope);
                    }
                };
                $scope.excluded = function () {
                    return $scope.profiles.exclude(function (p) {
                        return $scope.excludedProfiles.some(function (e) {
                            return e === p.id;
                        });
                    });
                };
                $scope.included = function () {
                    return $scope.profiles.exclude(function (p) {
                        return $scope.includedProfiles.none(function (e) {
                            return e === p.id;
                        });
                    });
                };
                $scope.isOpen = function (branch) {
                    if ($scope.filterText !== '') {
                        return "opened";
                    }
                    if (branch.expanded) {
                        return "opened";
                    }
                    return "closed";
                };
                $scope.isOpenIcon = function (branch) {
                    if (branch.expanded) {
                        return "icon-folder-open";
                    }
                    return "icon-folder-closed";
                };
                $scope.$watch('includedProfiles', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        $scope.init();
                    }
                }, true);
                $scope.$watch('excludedProfiles', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        $scope.init();
                    }
                }, true);
                $scope.selected = function () {
                    return $scope.profiles.filter(function (profile) {
                        return profile['selected'];
                    });
                };
                $scope.selectAll = function () {
                    $scope.profiles.each(function (profile) {
                        profile.selected = true;
                    });
                };
                $scope.selectNone = function () {
                    $scope.profiles.each(function (profile) {
                        delete profile.selected;
                    });
                };
                $scope.$parent.profileSelectAll = $scope.selectAll;
                $scope.$parent.profileSelectNone = $scope.selectNone;
                $scope.getSelectedClass = function (profile) {
                    if (profile.selected) {
                        return "selected";
                    }
                    return "";
                };
                $scope.$watch('selectedAll', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        if ($scope.indeterminate) {
                            $scope.selectNone();
                        } else {
                            if (newValue) {
                                $scope.selectAll();
                            } else {
                                $scope.selectNone();
                            }
                        }
                    }
                });
                $scope.$watch('profiles', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        $scope.selectedProfiles = $scope.selected();
                    }
                }, true);
                $scope.$on("fabricProfileRefresh", function () {
                    if ($scope.versionId) {
                        jolokia.request({
                            type: 'exec',
                            mbean: Fabric.managerMBean,
                            operation: 'getProfiles(java.lang.String, java.util.List)',
                            arguments: [
                                $scope.versionId, 
                                [
                                    'id', 
                                    'hidden'
                                ]
                            ]
                        }, {
                            method: 'POST',
                            success: function (response) {
                                $scope.render(response);
                            }
                        });
                    }
                });
                $scope.init = function () {
                    $scope.responseJson = null;
                    Core.unregister(jolokia, $scope);
                    if ($scope.versionId !== '') {
                        if ($scope.clearOnVersionChange) {
                            $scope.selectNone();
                        }
                        if ($scope.versionId) {
                            Core.register(jolokia, $scope, {
                                type: 'exec',
                                mbean: Fabric.managerMBean,
                                operation: 'getProfiles(java.lang.String, java.util.List)',
                                arguments: [
                                    $scope.versionId, 
                                    [
                                        'id', 
                                        'hidden'
                                    ]
                                ]
                            }, onSuccess($scope.render));
                        }
                    }
                };
                $scope.$watch('versionId', function (newValue, oldValue) {
                    if ($scope.versionId && $scope.versionId !== '') {
                        jolokia.request({
                            type: 'exec',
                            mbean: Fabric.managerMBean,
                            operation: 'versions()',
                            arguments: []
                        }, {
                            method: 'POST',
                            success: function (response) {
                                if (response.value.some(function (version) {
                                    return version.id === newValue;
                                })) {
                                    $scope.init();
                                } else {
                                    Core.unregister(jolokia, $scope);
                                }
                                Core.$apply($scope);
                            },
                            error: function (response) {
                                Core.unregister(jolokia, $scope);
                                Core.$apply($scope);
                            }
                        });
                    }
                });
            };
            this.link = function ($scope, $element, $attrs) {
                var selector = $element.find('#selector');
                if (!angular.isDefined($attrs['showHeader'])) {
                    $scope.showFilter = true;
                } else {
                    $scope.showFilter = $attrs['showHeader'];
                }
                if (angular.isDefined($attrs['filterWatch'])) {
                    $scope.$parent.$watch($attrs['filterWatch'], function (newValue, oldValue) {
                        if (newValue !== oldValue) {
                            $scope.filterText = newValue;
                        }
                    });
                }
                $scope.$watch('indeterminate', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        selector.prop('indeterminate', $scope.indeterminate);
                    }
                });
                $scope.$watch('selectedProfiles', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        if ($scope.selectedProfiles.length > 0) {
                            if ($scope.selectedProfiles.length !== $scope.profiles.length) {
                                $scope.indeterminate = true;
                                $scope.selectedAll = false;
                                $scope.$parent.profileSomeSelected = true;
                                $scope.$parent.profileNoneSelected = false;
                                $scope.$parent.profileAllSelected = false;
                            } else {
                                $scope.indeterminate = false;
                                $scope.selectedAll = true;
                                $scope.$parent.profileSomeSelected = false;
                                $scope.$parent.profileNoneSelected = false;
                                $scope.$parent.profileAllSelected = true;
                            }
                        } else {
                            $scope.indeterminate = false;
                            $scope.selectedAll = false;
                            $scope.$parent.profileSomeSelected = false;
                            $scope.$parent.profileNoneSelected = true;
                            $scope.$parent.profileAllSelected = false;
                        }
                    }
                }, true);
            };
        }
        return ProfileSelector;
    })();
    Fabric.ProfileSelector = ProfileSelector;    
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function ProfilesController($scope, $location, workspace, jolokia) {
        Fabric.initScope($scope, $location, jolokia, workspace);
        $scope.defaultVersion = Fabric.getDefaultVersion(jolokia);
        $scope.version = {
            id: $scope.defaultVersion.id
        };
        $scope.selected = [];
        $scope.selectedParents = [];
        $scope.selectedParentVersion = [];
        $scope.deleteVersionDialog = false;
        $scope.deleteProfileDialog = false;
        $scope.createProfileDialog = false;
        $scope.createVersionDialog = false;
        $scope.triggerResize = function () {
            setTimeout(function () {
                $('.dialogGrid').trigger('resize');
            }, 10);
        };
        $scope.$watch('createProfileDialog', function () {
            if ($scope.createProfileDialog) {
                $scope.triggerResize();
            }
        });
        $scope.$watch('createVersionDialog', function () {
            if ($scope.createVersionDialog) {
                $scope.triggerResize();
            }
        });
        $scope.newProfileName = '';
        $scope.newVersionName = '';
        var key = $location.search()['pv'];
        if (key) {
            $scope.version = {
                id: key
            };
        }
        key = $location.search()['ao'];
        $scope.activeOnly = !angular.isDefined(key) || key === 'true';
        $scope.versions = [];
        $scope.profiles = [];
        $scope.versionResponse = [];
        $scope.profilesResponse = [];
        $scope.$watch('activeOnly', function (oldValue, newValue) {
            if (oldValue === newValue) {
                return;
            }
            var q = $location.search();
            q['ao'] = "" + $scope.activeOnly;
            $location.search(q);
        });
        $scope.$watch('version', function (oldValue, newValue) {
            var q = $location.search();
            q['pv'] = $scope.version.id;
            $location.search(q);
            if (oldValue === newValue) {
                notification('info', "Please wait, fetching profile data for version " + $scope.version.id);
            }
            Core.unregister(jolokia, $scope);
            var versionId = $scope.version.id;
            if (versionId) {
                Core.register(jolokia, $scope, [
                    {
                        type: 'exec',
                        mbean: Fabric.managerMBean,
                        operation: 'versions()'
                    }, 
                    {
                        type: 'exec',
                        mbean: Fabric.managerMBean,
                        operation: 'getProfiles(java.lang.String, java.util.List)',
                        arguments: [
                            versionId, 
                            [
                                "id", 
                                "parentIds", 
                                "childIds", 
                                "containerCount", 
                                "locked", 
                                "abstract"
                            ]
                        ]
                    }
                ], onSuccess(render));
            }
        });
        $scope.selectedHasContainers = function () {
            return $scope.selected.findAll(function (item) {
                return item.containerCount > 0;
            }).length > 0;
        };
        $scope.versionCanBeDeleted = function () {
            if ($scope.version.id === $scope.defaultVersion.id) {
                return true;
            }
            if ($scope.versions.length === 0) {
                return true;
            }
            return $scope.profiles.findAll(function (item) {
                return item.containerCount > 0;
            }).length > 0;
        };
        $scope.createProfileGridOptions = {
            data: 'profiles',
            selectedItems: $scope.selectedParents,
            showSelectionCheckbox: true,
            multiSelect: true,
            selectWithCheckboxOnly: false,
            keepLastSelected: false,
            columnDefs: [
                {
                    field: 'id',
                    displayName: 'Name'
                }
            ]
        };
        $scope.createVersionGridOptions = {
            data: 'versions',
            selectedItems: $scope.selectedParentVersion,
            showSelectionCheckbox: true,
            multiSelect: false,
            selectWithCheckboxOnly: false,
            keepLastSelected: false,
            columnDefs: [
                {
                    field: 'id',
                    displayName: 'Name'
                }
            ]
        };
        $scope.gridOptions = {
            data: 'profiles',
            showFilter: false,
            showColumnMenu: false,
            filterOptions: {
                filterText: ''
            },
            selectedItems: $scope.selected,
            showSelectionCheckbox: true,
            multiSelect: true,
            selectWithCheckboxOnly: true,
            keepLastSelected: false,
            checkboxCellTemplate: '<div class="ngSelectionCell"><input tabindex="-1" class="ngSelectionCheckbox" type="checkbox" ng-checked="row.selected" ng-disabled="row.entity.containerCount > 0 || row.entity.childIds.length > 0"/></div>',
            columnDefs: [
                {
                    field: 'id',
                    displayName: 'Name',
                    cellTemplate: '<div class="ngCellText"><a ng-href="#/fabric/profile/{{$parent.version.id}}/{{row.getProperty(col.field)}}{{hash}}">{{row.getProperty(col.field)}}</a></div>',
                    width: 300
                }, 
                {
                    field: 'attributes',
                    displayName: 'A',
                    headerCellTemplate: '<div ng-click="col.sort()" class="ngHeaderSortColumn {{col.headerClass}}" ng-style="{\'cursor\': col.cursor}" ng-class="{ \'ngSorted\': !noSortVisible }"><div class="ngHeaderText colt{{$index}} pagination-centered" title="Attributes"><i class="icon-cogs"></i></div><div class="ngSortButtonDown" ng-show="col.showSortButtonDown()"></div><div class="ngSortButtonUp" ng-show="col.showSortButtonUp()"></div></div>',
                    cellTemplate: '<div class="ngCellText"><ul class="unstyled inline"><li class="attr-column"><i ng-show="row.entity.locked" title="Locked" class="icon-lock"></i></li><li class="attr-column"><i ng-show="row.entity.abstract" title="Abstract" class="icon-font"></i></li></ul></div>',
                    width: 52
                }, 
                {
                    field: 'containerCount',
                    displayName: 'C',
                    headerCellTemplate: '<div ng-click="col.sort()" class="ngHeaderSortColumn {{col.headerClass}}" ng-style="{\'cursor\': col.cursor}" ng-class="{ \'ngSorted\': !noSortVisible }"><div class="ngHeaderText colt{{$index}} pagination-centered" title="Containers"><i class="icon-truck"></i></div><div class="ngSortButtonDown" ng-show="col.showSortButtonDown()"></div><div class="ngSortButtonUp" ng-show="col.showSortButtonUp()"></div></div>',
                    cellTemplate: '<div class="ngCellText pagination-centered"><a ng-show="row.getProperty(col.field) > 0" title="{{row.entity.containers.sortBy().join(\'\n\')}}" href="#/fabric/containers?cv={{$parent.version.id}}&cp={{row.entity.id}}{{hash}}">{{row.getProperty(col.field)}}</a></div>',
                    width: 28
                }, 
                {
                    field: 'parentIds',
                    displayName: 'Parent Profiles',
                    cellTemplate: '<div class="ngCellText"><ul class="unstyled inline"><li ng-repeat="profile in row.entity.parentIds.sortBy()"><a href="#/fabric/profile/{{$parent.version.id}}/{{profile}}">{{profile}}</a></li></ul></div>',
                    width: 400
                }, 
                {
                    field: 'childIds',
                    displayName: 'Child Profiles',
                    cellTemplate: '<div class="ngCellText"><ul class="unstyled inline"><li ng-repeat="profile in row.entity.childIds.sortBy()"><a href="#/fabric/profile/{{$parent.version.id}}/{{profile}}">{{profile}}</a></li></ul></div>',
                    width: 800
                }
            ]
        };
        $scope.doCreateProfile = function () {
            $scope.createProfileDialog = false;
            var parents = $scope.selectedParents.map(function (profile) {
                return profile.id;
            });
            Fabric.createProfile(jolokia, $scope.version.id, $scope.newProfileName, parents, function () {
                notification('success', "Created profile " + $scope.newProfileName);
                $scope.newProfileName = "";
                Core.$apply($scope);
            }, function (response) {
                notification('error', "Failed to create profile " + $scope.newProfileName + " due to " + response.error);
            });
        };
        $scope.doCreateVersion = function () {
            $scope.createVersionDialog = false;
            var success = function (response) {
                notification('success', "Created version " + response.value.id);
                $scope.newVersionName = '';
                $scope.version = response.value;
                Core.$apply($scope);
            };
            var error = function (response) {
                var msg = "Error creating new version: " + response.error;
                if ($scope.newVersionName !== '') {
                    msg = "Error creating " + $scope.newVersionName + " : " + response.error;
                }
                notification('error', msg);
            };
            if ($scope.selectedParentVersion.length > 0 && $scope.newVersionName !== '') {
                Fabric.createVersionWithParentAndId(jolokia, $scope.selectedParentVersion[0].id, $scope.newVersionName, success, error);
            } else if ($scope.newVersionName !== '') {
                Fabric.createVersionWithId(jolokia, $scope.newVersionName, success, error);
            } else {
                Fabric.createVersion(jolokia, success, error);
            }
        };
        $scope.deleteVersion = function () {
            Core.unregister(jolokia, $scope);
            Fabric.deleteVersion(jolokia, $scope.version.id, function () {
                notification('success', "Deleted version " + $scope.version.id);
                $scope.version = $scope.defaultVersion;
                Core.$apply($scope);
            }, function (response) {
                notification('error', "Failed to delete version " + $scope.version.id + " due to " + response.error);
                $scope.version = $scope.defaultVersion;
                Core.$apply($scope);
            });
        };
        $scope.deleteSelected = function () {
            $scope.selected.each(function (profile) {
                Fabric.deleteProfile(jolokia, $scope.version.id, profile.id, function () {
                    notification('success', "Deleted profile " + profile.id);
                }, function (response) {
                    notification('error', "Failed to delete profile " + profile.id + ' due to ' + response.error);
                });
            });
        };
        function filterActive(data) {
            var rc = data;
            if ($scope.activeOnly) {
                rc = data.filter(function (item) {
                    return item.containerCount > 0;
                });
            }
            return rc;
        }
        function render(response) {
            clearNotifications();
            if (response.request.operation === 'versions()') {
                if (!Object.equal($scope.versionResponse, response.value)) {
                    $scope.versionResponse = response.value;
                    $scope.versions = response.value.map(function (version) {
                        var v = {
                            id: version.id,
                            'defaultVersion': version.defaultVersion
                        };
                        if (v['defaultVersion']) {
                            $scope.defaultVersion = v;
                        }
                        return v;
                    });
                    $scope.version = Fabric.setSelect($scope.version, $scope.versions);
                    Core.$apply($scope);
                }
            } else {
                if (!Object.equal($scope.profilesResponse, response.value)) {
                    $scope.profilesResponse = response.value;
                    $scope.profiles = [];
                    $scope.profilesResponse.forEach(function (profile) {
                        $scope.profiles.push({
                            id: profile.id,
                            parentIds: profile.parentIds,
                            childIds: profile.childIds,
                            containerCount: profile.containerCount,
                            containers: profile.containers,
                            locked: profile.locked,
                            abstract: profile['abstract']
                        });
                    });
                    $scope.profiles = filterActive($scope.profiles);
                    Core.$apply($scope);
                }
            }
        }
    }
    Fabric.ProfilesController = ProfilesController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function customizeSchema(id, schema) {
        Core.pathSet(schema, [
            "properties", 
            "name", 
            "required"
        ], true);
        delete schema.properties['metadataMap'];
        delete schema.properties['zookeeperUrl'];
        delete schema.properties['zookeeperPassword'];
        delete schema.properties['globalResolver'];
        delete schema.properties['zooKeeperServerPort'];
        delete schema.properties['zooKeeperServerConnectionPort'];
        delete schema.properties['agentEnabled'];
        delete schema.properties['autoImportEnabled'];
        delete schema.properties['importPath'];
        delete schema.properties['users'];
        Core.pathSet(schema, [
            'properties', 
            'providerType', 
            'type'
        ], 'hidden');
        Core.pathSet(schema, [
            'properties', 
            'profiles', 
            'type'
        ], 'hidden');
        Core.pathSet(schema, [
            'properties', 
            'version', 
            'type'
        ], 'hidden');
        Core.pathSet(schema.properties, [
            'name', 
            'label'
        ], 'Container Name');
        Core.pathSet(schema.properties, [
            'name', 
            'tooltip'
        ], 'Name of the container to create (or prefix of the container name if you create multiple containers)');
        Core.pathSet(schema.properties, [
            'number', 
            'tooltip'
        ], 'The number of containers to create');
        Core.pathSet(schema.properties, [
            'login', 
            'input-attributes', 
            "autofill"
        ], "true");
        Core.pathSet(schema.properties, [
            'password', 
            'input-attributes', 
            "autofill"
        ], "true");
        Core.pathSet(schema.properties, [
            'jmxUser', 
            'input-attributes', 
            "autofill"
        ], "true");
        Core.pathSet(schema.properties, [
            'jmxPassword', 
            'input-attributes', 
            "autofill"
        ], "true");
        setResolverEnum(schema);
        switch(id) {
            case 'child':
                delete schema.properties['manualIp'];
                delete schema.properties['preferredAddress'];
                delete schema.properties['resolver'];
                delete schema.properties['ensembleServer'];
                delete schema.properties['proxyUri'];
                delete schema.properties['adminAccess'];
                schema.properties['jmxPassword']['type'] = 'password';
                schema.properties['saveJmxCredentials'] = {
                    'type': 'boolean'
                };
                Core.pathSet(schema.properties, [
                    'parent', 
                    'label'
                ], 'Parent Container');
                Core.pathSet(schema.properties, [
                    'parent', 
                    'tooltip'
                ], 'The name of the parent container used to create the child container');
                Core.pathSet(schema.properties, [
                    'parent', 
                    'input-element'
                ], "select");
                Core.pathSet(schema.properties, [
                    'parent', 
                    'input-attributes', 
                    "ng-options"
                ], "c for c in child.rootContainers");
                bulkSet(schema, [
                    "jmxUser", 
                    "jmxPassword", 
                    "parent"
                ], 'required', true);
                schema['tabs'] = {
                    'Default': [
                        'name', 
                        'parent', 
                        'jmxUser', 
                        'jmxPassword', 
                        'saveJmxCredentials', 
                        'number'
                    ],
                    'Advanced': [
                        '*'
                    ]
                };
                break;
            case 'ssh':
                delete schema.properties['parent'];
                bulkSet(schema, [
                    'host'
                ], 'required', true);
                Core.pathSet(schema.properties, [
                    'password', 
                    'type'
                ], 'password');
                schema['tabs'] = {
                    'Default': [
                        'name', 
                        'host', 
                        'port', 
                        'username', 
                        'password', 
                        'privateKeyFile', 
                        'passPhrase'
                    ],
                    'Advanced': [
                        '*'
                    ]
                };
                break;
            case 'jclouds':
                delete schema.properties['parent'];
                schema['tabs'] = {
                    'Default': [
                        'name', 
                        'owner', 
                        'credential', 
                        'providerName', 
                        'imageId', 
                        'hardwareId', 
                        'locationId', 
                        'number', 
                        'instanceType'
                    ],
                    'Advanced': [
                        '*'
                    ]
                };
                break;
            case 'openshift':
                delete schema.properties['parent'];
                delete schema.properties['manualIp'];
                delete schema.properties['preferredAddress'];
                delete schema.properties['resolver'];
                delete schema.properties['ensembleServer'];
                delete schema.properties['proxyUri'];
                delete schema.properties['adminAccess'];
                delete schema.properties['path'];
                delete schema.properties['bindAddress'];
                delete schema.properties['hostNameContext'];
                schema.properties['serverUrl']['default'] = 'openshift.redhat.com';
                Core.pathSet(schema.properties, [
                    'resolver', 
                    'default'
                ], 'publichostname');
                Core.pathSet(schema.properties, [
                    'serverUrl', 
                    'label'
                ], 'OpenShift Broker');
                Core.pathSet(schema.properties, [
                    'serverUrl', 
                    'tooltip'
                ], 'The OpenShift broker host name of the cloud to create the container inside. This is either the URL for your local OpenShift Enterprise installation, or its the public OpenShift online URL: openshift.redhat.com');
                Core.pathSet(schema.properties, [
                    'login', 
                    'label'
                ], 'OpenShift Login');
                Core.pathSet(schema.properties, [
                    'login', 
                    'tooltip'
                ], 'Your personal login to the OpenShift portal');
                Core.pathSet(schema.properties, [
                    'login', 
                    'input-attributes', 
                    "autofill"
                ], "true");
                Core.pathSet(schema.properties, [
                    'password', 
                    'label'
                ], 'OpenShift Password');
                Core.pathSet(schema.properties, [
                    'password', 
                    'tooltip'
                ], 'Your personal password on the OpenShift portal');
                Core.pathSet(schema.properties, [
                    'password', 
                    'type'
                ], 'password');
                Core.pathSet(schema.properties, [
                    'tryLogin', 
                    'type'
                ], 'string');
                Core.pathSet(schema.properties, [
                    'tryLogin', 
                    'input-attributes', 
                    "ng-model"
                ], "openShift.tryLogin");
                Core.pathSet(schema.properties, [
                    'tryLogin', 
                    'label'
                ], 'Authenticate');
                Core.pathSet(schema.properties, [
                    'tryLogin', 
                    'tooltip'
                ], 'Authenticate with the OpenShift Broker using your login and password');
                Core.pathSet(schema.properties, [
                    'tryLogin', 
                    'formTemplate'
                ], '<a ng-click="openShift.login()" ng-disabled="!entity.login || !entity.password || !entity.serverUrl" ' + 'title="Test you entered the correct OpenShift Broker, login and password" class="btn btn-primary">Login to OpenShift</a>' + '<div class="alert" ng-show="openShift.loginFailed" ' + 'title="Are you sure you correctly entered the OpenShift Broker, login and password correctly?">Login failed</div>');
                Core.pathSet(schema.properties, [
                    'domain', 
                    'label'
                ], 'OpenShift Domain');
                Core.pathSet(schema.properties, [
                    'domain', 
                    'tooltip'
                ], 'What is your unique domain name used for applications you create on OpenShift. Often this is your own user name or group name');
                Core.pathSet(schema.properties, [
                    'domain', 
                    'input-element'
                ], "select");
                Core.pathSet(schema.properties, [
                    'domain', 
                    'input-attributes', 
                    "ng-options"
                ], "c for c in openShift.domains");
                Core.pathSet(schema.properties, [
                    'gearProfile', 
                    'tooltip'
                ], 'Which kind of gear to create');
                Core.pathSet(schema.properties, [
                    'gearProfile', 
                    'input-element'
                ], "select");
                Core.pathSet(schema.properties, [
                    'gearProfile', 
                    'input-attributes', 
                    "ng-options"
                ], "c for c in openShift.gearProfiles");
                bulkSet(schema, [
                    'serverUrl', 
                    'login', 
                    'password', 
                    'domain'
                ], 'required', true);
                schema['tabs'] = {
                    'Default': [
                        'name', 
                        'serverUrl', 
                        'login', 
                        'password', 
                        'tryLogin', 
                        'domain', 
                        'gearProfile', 
                        'number'
                    ],
                    'Advanced': [
                        'environmentalVariables', 
                        'systemProperties', 
                        'jvmOpts', 
                        '*'
                    ]
                };
                break;
            case 'createEnsemble':
                delete schema['properties']['name'];
                angular.forEach([
                    "username", 
                    "password", 
                    "role", 
                    "zookeeperPassword"
                ], function (name) {
                    Core.pathSet(schema, [
                        "properties", 
                        name, 
                        "type"
                    ], 'string');
                    Core.pathSet(schema, [
                        "properties", 
                        name, 
                        "required"
                    ], true);
                });
                setGlobalResolverEnum(schema);
                setResolverEnum(schema);
                Core.pathSet(schema, [
                    "properties", 
                    "profiles", 
                    "type"
                ], "hidden");
                Core.pathSet(schema, [
                    'properties', 
                    'password', 
                    'type'
                ], "password");
                Core.pathSet(schema, [
                    'properties', 
                    'zookeeperPassword', 
                    'type'
                ], "password");
                delete schema['properties']['users'];
                schema['tabs'] = {
                    'Basic': [
                        'username', 
                        'password', 
                        'role', 
                        'zookeeperPassword', 
                        'zooKeeperServerPort', 
                        'globalResolver', 
                        'resolver', 
                        'manualIp'
                    ],
                    'Advanced': [
                        '*'
                    ]
                };
            default:
        }
        return schema;
    }
    Fabric.customizeSchema = customizeSchema;
    function bulkSet(schema, properties, field, value) {
        properties.each(function (name) {
            Core.pathSet(schema, [
                'properties', 
                name, 
                field
            ], value);
        });
    }
    function setGlobalResolverEnum(schema) {
        var globalResolverEnum = [
            'localip', 
            'localhostname', 
            'publicip', 
            'publichostname'
        ];
        Core.pathSet(schema, [
            'properties', 
            'globalResolver', 
            'enum'
        ], globalResolverEnum);
    }
    function setResolverEnum(schema) {
        var resolverEnum = [
            'localip', 
            'localhostname', 
            'publicip', 
            'publichostname', 
            'manualip'
        ];
        Core.pathSet(schema, [
            'properties', 
            'resolver', 
            'enum'
        ], resolverEnum);
    }
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    function TestController($scope, jolokia, $q, workspace, $templateCache) {
        $scope.mavenMBean = Maven.getMavenIndexerMBean(workspace);
        $scope.html = "text/html";
        $scope.versionSelector = $templateCache.get("versionSelectorTemplate");
        $scope.profileIncludes = $templateCache.get("profile-includes");
        $scope.profileExcludes = $templateCache.get("profile-excludes");
        $scope.containerList = $templateCache.get("containerListTemplate");
        $scope.profileLink = $templateCache.get("profileLinkTemplate");
        $scope.version = {};
        $scope.versionId = '';
        $scope.someUri = '';
        $scope.uriParts = [];
        $scope.version = {};
        $scope.osp = [];
        $scope.vid = '1.0';
        $scope.someProfiles = [
            'a-mq', 
            'aws-ec2'
        ];
        $scope.selectedProfiles = [
            {
                id: '1-dot-0',
                selected: true
            }, 
            {
                id: 'a-mq',
                selected: true
            }
        ];
        $scope.selectedProfilesString = "";
        $scope.$watch('version', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                if ($scope.version && !Object.equal($scope.version, {})) {
                    $scope.versionId = $scope.version.id;
                }
            }
        });
        $scope.$watch('osp', function (newValue, oldValue) {
            $scope.selectedProfilesString = angular.toJson($scope.osp);
        });
        $scope.$watch('someUri', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $scope.uriParts = newValue.split("/");
            }
        });
        $scope.$watch('uriParts', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                if (newValue.length === 1 && newValue.length < oldValue.length) {
                    if (oldValue.last() !== '' && newValue.first().has(oldValue.last())) {
                        var merged = oldValue.first(oldValue.length - 1).include(newValue.first());
                        $scope.someUri = merged.join('/');
                    }
                }
            }
        }, true);
        $scope.doCompletionMaven = function (something) {
            return Maven.completeMavenUri($q, $scope, workspace, jolokia, something);
        };
        $scope.doCompletionFabric = function (something) {
            return Fabric.completeUri($q, $scope, workspace, jolokia, something);
        };
    }
    Fabric.TestController = TestController;
})(Fabric || (Fabric = {}));
var Fabric;
(function (Fabric) {
    var VersionSelector = (function () {
        function VersionSelector() {
            this.restrict = 'A';
            this.replace = true;
            this.templateUrl = Fabric.templatePath + "versionSelector.html";
            this.scope = {
                selectedVersion: '=fabricVersionSelector'
            };
            this.controller = function ($scope, $element, $attrs, jolokia) {
                $scope.versions = [];
                $scope.responseJson = '';
                $scope.$watch('selectedVersion', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        if (newValue && 'id' in newValue) {
                            $scope.selectedVersion = $scope.versions.find(function (version) {
                                return version.id === newValue['id'];
                            });
                        } else {
                            $scope.selectedVersion = $scope.versions.find(function (version) {
                                return version.defaultVersion;
                            });
                        }
                    }
                });
                $scope.$watch('versions', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        if ($scope.selectedVersion && 'id' in $scope.selectedVersion) {
                            $scope.selectedVersion = $scope.versions.find(function (version) {
                                return version.id === $scope.selectedVersion['id'];
                            });
                        } else {
                            $scope.selectedVersion = $scope.versions.find(function (version) {
                                return version.defaultVersion;
                            });
                        }
                    }
                }, true);
                $scope.render = function (response) {
                    var responseJson = angular.toJson(response.value);
                    if ($scope.responseJson !== responseJson) {
                        $scope.responseJson = responseJson;
                        $scope.versions = response.value;
                        Core.$apply($scope);
                    }
                };
                Core.register(jolokia, $scope, {
                    type: 'exec',
                    mbean: Fabric.managerMBean,
                    operation: 'versions(java.util.List)',
                    arguments: [
                        [
                            'id', 
                            'defaultVersion'
                        ]
                    ]
                }, onSuccess($scope.render));
            };
        }
        return VersionSelector;
    })();
    Fabric.VersionSelector = VersionSelector;    
})(Fabric || (Fabric = {}));
var ForceGraph;
(function (ForceGraph) {
    var log = Logger.get("ForceGraph");
    var ForceGraphDirective = (function () {
        function ForceGraphDirective() {
            this.restrict = 'A';
            this.replace = true;
            this.transclude = false;
            this.scope = {
                graph: '=graph',
                nodesize: '@',
                selectedModel: '@',
                linkDistance: '@',
                markerKind: '@',
                charge: '@'
            };
            this.link = function ($scope, $element, $attrs) {
                $scope.trans = [
                    0, 
                    0
                ];
                $scope.scale = 1;
                $scope.$watch('graph', function (oldVal, newVal) {
                    updateGraph();
                });
                $scope.redraw = function () {
                    $scope.trans = d3.event.translate;
                    $scope.scale = d3.event.scale;
                    $scope.viewport.attr("transform", "translate(" + $scope.trans + ")" + " scale(" + $scope.scale + ")");
                };
                $scope.tick = function () {
                    $scope.graphEdges.attr("d", function (d) {
                        var dx = d.target.x - d.source.x, dy = d.target.y - d.source.y, dr = Math.sqrt(dx * dx + dy * dy);
                        return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
                    });
                    $scope.graphNodes.attr("transform", function (d) {
                        return "translate(" + d.x + "," + d.y + ")";
                    });
                    $scope.graphLabels.attr("transform", function (d) {
                        return "translate(" + d.x + "," + d.y + ")";
                    });
                };
                $scope.mover = function (d) {
                    if (d.popup != null) {
                        $("#pop-up").fadeOut(100, function () {
                            if (d.popup.title != null) {
                                $("#pop-up-title").html(d.popup.title);
                            } else {
                                $("#pop-up-title").html("");
                            }
                            if (d.popup.content != null) {
                                $("#pop-up-content").html(d.popup.content);
                            } else {
                                $("#pop-up-content").html("");
                            }
                            var popLeft = (d.x * $scope.scale) + $scope.trans[0] + 20;
                            var popTop = (d.y * $scope.scale) + $scope.trans[1] + 20;
                            $("#pop-up").css({
                                "left": popLeft,
                                "top": popTop
                            });
                            $("#pop-up").fadeIn(100);
                        });
                    }
                };
                $scope.mout = function (d) {
                    $("#pop-up").fadeOut(50);
                };
                var updateGraph = function () {
                    var canvas = $($element);
                    var h = $($element).parent().height();
                    var w = $($element).parent().width();
                    var i = 0;
                    canvas.children("svg").remove();
                    $scope.svg = d3.select(canvas[0]).append("svg").attr("width", w).attr("height", h);
                    var linkTypes = null;
                    if ($scope.graph) {
                        linkTypes = $scope.graph.linktypes;
                    }
                    if (!linkTypes) {
                        return;
                    }
                    $scope.svg.append("svg:defs").selectAll("marker").data(linkTypes).enter().append("svg:marker").attr("id", String).attr("viewBox", "0 -5 10 10").attr("refX", 15).attr("refY", -1.5).attr("markerWidth", 6).attr("markerHeight", 6).attr("orient", "auto").append("svg:path").attr("d", "M0,-5L10,0L0,5");
                    $scope.svg.append("svg:g").append("svg:rect").attr("class", "graphbox.frame").attr('width', w).attr('height', h);
                    $scope.viewport = $scope.svg.append("svg:g").call(d3.behavior.zoom().on("zoom", $scope.redraw)).append("svg:g");
                    $scope.viewport.append("svg:rect").attr("width", 1000000).attr("height", 1000000).attr("class", "graphbox").attr("transform", "translate(-50000, -500000)");
                    if ($scope.graph) {
                        var ownerScope = $scope.$parent || $scope;
                        var selectedModel = $scope.selectedModel || "selectedNode";
                        $scope.force = d3.layout.force().nodes($scope.graph.nodes).links($scope.graph.links).size([
                            w, 
                            h
                        ]).on("tick", $scope.tick);
                        if (angular.isDefined($scope.linkDistance)) {
                            $scope.force.linkDistance($scope.linkDistance);
                        }
                        if (angular.isDefined($scope.charge)) {
                            $scope.force.charge($scope.charge);
                        }
                        var markerTypeName = $scope.markerKind || "marker-end";
                        $scope.graphEdges = $scope.viewport.append("svg:g").selectAll("path").data($scope.force.links()).enter().append("svg:path").attr("class", function (d) {
                            return "link " + d.type;
                        }).attr(markerTypeName, function (d) {
                            return "url(#" + d.type + ")";
                        });
                        $scope.graphNodes = $scope.viewport.append("svg:g").selectAll("circle").data($scope.force.nodes()).enter().append("a").attr("xlink:href", function (d) {
                            return d.navUrl;
                        }).on("mouseover.onLink", function (d, i) {
                            var sel = d3.select(d3.event.target);
                            sel.classed('selected', true);
                            ownerScope[selectedModel] = d;
                            Core.pathSet(ownerScope, selectedModel, d);
                            Core.$apply(ownerScope);
                        }).on("mouseout.onLink", function (d, i) {
                            var sel = d3.select(d3.event.target);
                            sel.classed('selected', false);
                        });
                        function hasImage(d) {
                            return d.image && d.image.url;
                        }
                        $scope.graphNodes.filter(function (d) {
                            return d.image != null;
                        }).append("image").attr("xlink:href", function (d) {
                            return d.image.url;
                        }).attr("x", function (d) {
                            return -(d.image.width / 2);
                        }).attr("y", function (d) {
                            return -(d.image.height / 2);
                        }).attr("width", function (d) {
                            return d.image.width;
                        }).attr("height", function (d) {
                            return d.image.height;
                        });
                        $scope.graphNodes.filter(function (d) {
                            return !hasImage(d);
                        }).append("circle").attr("class", function (d) {
                            return d.type;
                        }).attr("r", function (d) {
                            return d.size || $scope.nodesize;
                        });
                        $scope.graphLabels = $scope.viewport.append("svg:g").selectAll("g").data($scope.force.nodes()).enter().append("svg:g");
                        $scope.graphLabels.append("svg:text").attr("x", 8).attr("y", ".31em").attr("class", "shadow").text(function (d) {
                            return d.name;
                        });
                        $scope.graphLabels.append("svg:text").attr("x", 8).attr("y", ".31em").text(function (d) {
                            return d.name;
                        });
                        $scope.force.start();
                        $scope.graphNodes.call($scope.force.drag).on("mouseover", $scope.mover).on("mouseout", $scope.mout);
                    }
                };
            };
        }
        return ForceGraphDirective;
    })();
    ForceGraph.ForceGraphDirective = ForceGraphDirective;    
    ;
})(ForceGraph || (ForceGraph = {}));
var ForceGraph;
(function (ForceGraph) {
    var pluginName = 'forceGraph';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'hawtioCore'
    ]).directive('hawtioForceGraph', function () {
        return new ForceGraph.ForceGraphDirective();
    }).run(function (helpRegistry) {
        helpRegistry.addDevDoc('Force Graph', 'app/forcegraph/doc/developer.md');
    });
    hawtioPluginLoader.addModule(pluginName);
})(ForceGraph || (ForceGraph = {}));
var ForceGraph;
(function (ForceGraph) {
    var GraphBuilder = (function () {
        function GraphBuilder() {
            this.nodes = {};
            this.links = [];
            this.linkTypes = {};
        }
        GraphBuilder.prototype.addNode = function (node) {
            if (!this.nodes[node.id]) {
                this.nodes[node.id] = node;
            }
        };
        GraphBuilder.prototype.getNode = function (id) {
            return this.nodes[id];
        };
        GraphBuilder.prototype.hasLinks = function (id) {
            var _this = this;
            var result = false;
            this.links.forEach(function (link) {
                if (link.source.id == id || link.target.id == id) {
                    result = result || (_this.nodes[link.source.id] != null && _this.nodes[link.target.id] != null);
                }
            });
            return result;
        };
        GraphBuilder.prototype.addLink = function (srcId, targetId, linkType) {
            if ((this.nodes[srcId] != null) && (this.nodes[targetId] != null)) {
                this.links.push({
                    source: this.nodes[srcId],
                    target: this.nodes[targetId],
                    type: linkType
                });
                if (!this.linkTypes[linkType]) {
                    this.linkTypes[linkType] = {
                        used: true
                    };
                }
                ;
            }
        };
        GraphBuilder.prototype.nodeIndex = function (id, nodes) {
            var result = -1;
            var index = 0;
            for(index = 0; index < nodes.length; index++) {
                var node = nodes[index];
                if (node.id == id) {
                    result = index;
                    break;
                }
            }
            return result;
        };
        GraphBuilder.prototype.filterNodes = function (filter) {
            var filteredNodes = {};
            var newLinks = [];
            d3.values(this.nodes).forEach(function (node) {
                if (filter(node)) {
                    filteredNodes[node.id] = node;
                }
            });
            this.links.forEach(function (link) {
                if (filteredNodes[link.source.id] && filteredNodes[link.target.id]) {
                    newLinks.push(link);
                }
            });
            this.nodes = filteredNodes;
            this.links = newLinks;
        };
        GraphBuilder.prototype.buildGraph = function () {
            var _this = this;
            var graphNodes = [];
            var linktypes = d3.keys(this.linkTypes);
            var graphLinks = [];
            d3.values(this.nodes).forEach(function (node) {
                if (node.includeInGraph == null || node.includeInGraph) {
                    node.includeInGraph = true;
                    graphNodes.push(node);
                }
            });
            this.links.forEach(function (link) {
                if (_this.nodes[link.source.id] != null && _this.nodes[link.target.id] != null && _this.nodes[link.source.id].includeInGraph && _this.nodes[link.target.id].includeInGraph) {
                    graphLinks.push({
                        source: _this.nodeIndex(link.source.id, graphNodes),
                        target: _this.nodeIndex(link.target.id, graphNodes),
                        type: link.type
                    });
                }
            });
            return {
                nodes: graphNodes,
                links: graphLinks,
                linktypes: linktypes
            };
        };
        return GraphBuilder;
    })();
    ForceGraph.GraphBuilder = GraphBuilder;    
})(ForceGraph || (ForceGraph = {}));
var Forms;
(function (Forms) {
    var InputBaseConfig = (function () {
        function InputBaseConfig() {
            this.name = 'input';
            this.type = '';
            this.description = '';
            this._default = '';
            this.scope = null;
            this.mode = 'edit';
            this.schemaName = "schema";
            this.controlgroupclass = 'control-group';
            this.controlclass = 'controls';
            this.labelclass = 'control-label';
            this.showtypes = 'false';
            this.formtemplate = null;
            this.entity = 'entity';
            this.model = undefined;
        }
        InputBaseConfig.prototype.getEntity = function () {
            return this.entity || "entity";
        };
        InputBaseConfig.prototype.getMode = function () {
            return this.mode || "edit";
        };
        InputBaseConfig.prototype.isReadOnly = function () {
            return this.getMode() === "view";
        };
        return InputBaseConfig;
    })();
    Forms.InputBaseConfig = InputBaseConfig;    
    var InputBase = (function () {
        function InputBase(workspace, $compile) {
            this.workspace = workspace;
            this.$compile = $compile;
            var _this = this;
            this.restrict = 'A';
            this.scope = true;
            this.replace = false;
            this.transclude = false;
            this.attributeName = '';
            this.link = function (scope, element, attrs) {
                return _this.doLink(scope, element, attrs);
            };
        }
        InputBase.prototype.doLink = function (scope, element, attrs) {
            var config = new InputBaseConfig();
            config = Forms.configure(config, null, attrs);
            config.scope = scope;
            config.schemaName = attrs["schema"] || "schema";
            var id = Forms.safeIdentifier(config.name);
            var group = this.getControlGroup(config, config, id);
            var modelName = config.model;
            if (!angular.isDefined(modelName)) {
                modelName = config.getEntity() + "." + id;
            }
            var defaultLabel = id;
            if ("true" === attrs["ignorePrefixInLabel"]) {
                var idx = id.lastIndexOf('.');
                if (idx > 0) {
                    defaultLabel = id.substring(idx + 1);
                }
            }
            group.append(Forms.getLabel(config, config, attrs["title"] || humanizeValue(defaultLabel)));
            var controlDiv = Forms.getControlDiv(config);
            controlDiv.append(this.getInput(config, config, id, modelName));
            controlDiv.append(Forms.getHelpSpan(config, config, id));
            group.append(controlDiv);
            $(element).append(this.$compile(group)(scope));
            if (scope && modelName) {
                scope.$watch(modelName, onModelChange);
            }
            function onModelChange(newValue) {
                scope.$emit("hawtio.form.modelChange", modelName, newValue);
            }
        };
        InputBase.prototype.getControlGroup = function (config1, config2, id) {
            return Forms.getControlGroup(config1, config2, id);
        };
        InputBase.prototype.getInput = function (config, arg, id, modelName) {
            var rc = $('<span class="form-data"></span>');
            if (modelName) {
                rc.attr('ng-model', modelName);
                rc.append('{{' + modelName + '}}');
            }
            return rc;
        };
        return InputBase;
    })();
    Forms.InputBase = InputBase;    
    var TextInput = (function (_super) {
        __extends(TextInput, _super);
        function TextInput(workspace, $compile) {
            _super.call(this, workspace, $compile);
            this.workspace = workspace;
            this.$compile = $compile;
            this.type = "text";
        }
        TextInput.prototype.getInput = function (config, arg, id, modelName) {
            if (config.isReadOnly()) {
                return _super.prototype.getInput.call(this, config, arg, id, modelName);
            }
            var rc = $('<input type="' + this.type + '">');
            rc.attr('name', id);
            if (modelName) {
                rc.attr('ng-model', modelName);
            }
            if (config.isReadOnly()) {
                rc.attr('readonly', 'true');
            }
            var required = config.$attr["required"];
            if (required && required !== "false") {
                rc.attr('required', 'true');
            }
            return rc;
        };
        return TextInput;
    })(InputBase);
    Forms.TextInput = TextInput;    
    var HiddenText = (function (_super) {
        __extends(HiddenText, _super);
        function HiddenText(workspace, $compile) {
            _super.call(this, workspace, $compile);
            this.workspace = workspace;
            this.$compile = $compile;
            this.type = "hidden";
        }
        HiddenText.prototype.getControlGroup = function (config1, config2, id) {
            var group = _super.prototype.getControlGroup.call(this, config1, config2, id);
            group.css({
                'display': 'none'
            });
            return group;
        };
        HiddenText.prototype.getInput = function (config, arg, id, modelName) {
            var rc = _super.prototype.getInput.call(this, config, arg, id, modelName);
            rc.attr('readonly', 'true');
            return rc;
        };
        return HiddenText;
    })(TextInput);
    Forms.HiddenText = HiddenText;    
    var PasswordInput = (function (_super) {
        __extends(PasswordInput, _super);
        function PasswordInput(workspace, $compile) {
            _super.call(this, workspace, $compile);
            this.workspace = workspace;
            this.$compile = $compile;
            this.type = "password";
        }
        return PasswordInput;
    })(TextInput);
    Forms.PasswordInput = PasswordInput;    
    var CustomInput = (function (_super) {
        __extends(CustomInput, _super);
        function CustomInput(workspace, $compile) {
            _super.call(this, workspace, $compile);
            this.workspace = workspace;
            this.$compile = $compile;
        }
        CustomInput.prototype.getInput = function (config, arg, id, modelName) {
            var template = arg.formtemplate;
            template = Core.unescapeHtml(template);
            var rc = $(template);
            if (!rc.attr("name")) {
                rc.attr('name', id);
            }
            if (modelName) {
                rc.attr('ng-model', modelName);
            }
            if (config.isReadOnly()) {
                rc.attr('readonly', 'true');
            }
            return rc;
        };
        return CustomInput;
    })(InputBase);
    Forms.CustomInput = CustomInput;    
    var SelectInput = (function (_super) {
        __extends(SelectInput, _super);
        function SelectInput(workspace, $compile) {
            _super.call(this, workspace, $compile);
            this.workspace = workspace;
            this.$compile = $compile;
        }
        SelectInput.prototype.getInput = function (config, arg, id, modelName) {
            if (config.isReadOnly()) {
                return _super.prototype.getInput.call(this, config, arg, id, modelName);
            }
            var required = true;
            var defaultOption = required ? "" : '<option value=""></option>';
            var rc = $('<select>' + defaultOption + '</select>');
            rc.attr('name', id);
            var scope = config.scope;
            var data = config.data;
            if (data && scope) {
                var fullSchema = scope[config.schemaName];
                var model = scope[data];
                var paths = id.split(".");
                var property = null;
                angular.forEach(paths, function (path) {
                    property = Core.pathGet(model, [
                        "properties", 
                        path
                    ]);
                    var typeName = Core.pathGet(property, [
                        "type"
                    ]);
                    var alias = Forms.lookupDefinition(typeName, fullSchema);
                    if (alias) {
                        model = alias;
                    }
                });
                var values = Core.pathGet(property, [
                    "enum"
                ]);
                scope["$selectValues"] = values;
                rc.attr("ng-options", "value for value in $selectValues");
            }
            if (modelName) {
                rc.attr('ng-model', modelName);
            }
            if (config.isReadOnly()) {
                rc.attr('readonly', 'true');
            }
            return rc;
        };
        return SelectInput;
    })(InputBase);
    Forms.SelectInput = SelectInput;    
    var NumberInput = (function (_super) {
        __extends(NumberInput, _super);
        function NumberInput(workspace, $compile) {
            _super.call(this, workspace, $compile);
            this.workspace = workspace;
            this.$compile = $compile;
        }
        NumberInput.prototype.getInput = function (config, arg, id, modelName) {
            if (config.isReadOnly()) {
                return _super.prototype.getInput.call(this, config, arg, id, modelName);
            }
            var rc = $('<input type="number">');
            rc.attr('name', id);
            if (angular.isDefined(arg.def)) {
                rc.attr('value', arg.def);
            }
            if (angular.isDefined(arg.minimum)) {
                rc.attr('min', arg.minimum);
            }
            if (angular.isDefined(arg.maximum)) {
                rc.attr('max', arg.maximum);
            }
            if (modelName) {
                rc.attr('ng-model', modelName);
            }
            if (config.isReadOnly()) {
                rc.attr('readonly', 'true');
            }
            var scope = config.scope;
            if (scope) {
                function onModelChange() {
                    var value = Core.pathGet(scope, modelName);
                    if (value && angular.isString(value)) {
                        var numberValue = Number(value);
                        Core.pathSet(scope, modelName, numberValue);
                    }
                }
                scope.$watch(modelName, onModelChange);
                onModelChange();
            }
            return rc;
        };
        return NumberInput;
    })(InputBase);
    Forms.NumberInput = NumberInput;    
    var StringArrayInput = (function (_super) {
        __extends(StringArrayInput, _super);
        function StringArrayInput(workspace, $compile) {
            _super.call(this, workspace, $compile);
            this.workspace = workspace;
            this.$compile = $compile;
        }
        StringArrayInput.prototype.getInput = function (config, arg, id, modelName) {
            var rowScopeName = "_" + id;
            var ngRepeat = rowScopeName + ' in ' + modelName;
            var readOnlyWidget = '{{' + rowScopeName + '}}';
            if (config.isReadOnly()) {
                return $('<ul><li ng-repeat="' + rowScopeName + ' in ' + modelName + '">' + readOnlyWidget + '</li></ul>');
            } else {
                var scope = config.scope;
                var schema = scope[config.schemaName] || {};
                var properties = schema.properties || {};
                var arrayProperty = properties[id] || {};
                var property = arrayProperty["items"] || {};
                var propTypeName = property.type;
                var ignorePrefixInLabel = true;
                var configScopeName = null;
                var value = Core.pathGet(scope, modelName);
                if (!value) {
                    Core.pathSet(scope, modelName, []);
                }
                var methodPrefix = "_form_stringArray" + rowScopeName + "_";
                var itemKeys = methodPrefix + "keys";
                var addMethod = methodPrefix + "add";
                var removeMethod = methodPrefix + "remove";
                function updateKeys() {
                    var value = Core.pathGet(scope, modelName) || [];
                    scope[itemKeys] = Object.keys(value);
                }
                updateKeys();
                scope[addMethod] = function () {
                    var value = Core.pathGet(scope, modelName) || [];
                    value.push("");
                    Core.pathSet(scope, modelName, value);
                    updateKeys();
                };
                scope[removeMethod] = function (idx) {
                    var value = Core.pathGet(scope, modelName) || [];
                    if (idx < value.length) {
                        value.splice(idx, 1);
                    }
                    Core.pathSet(scope, modelName, value);
                    updateKeys();
                };
                var itemId = modelName + "[" + rowScopeName + "]";
                var itemsConfig = {
                    model: itemId
                };
                var widget = Forms.createWidget(propTypeName, property, schema, itemsConfig, itemId, ignorePrefixInLabel, configScopeName, false);
                if (!widget) {
                    widget = $(readOnlyWidget);
                }
                var markup = $('<div style="white-space: nowrap" ng-repeat="' + rowScopeName + ' in ' + itemKeys + '"></div>');
                markup.append(widget);
                markup.append($('<a ng-click="' + removeMethod + '(' + rowScopeName + ')" title="Remove this value"><i class="red icon-remove"></i></a>'));
                markup.after($('<a ng-click="' + addMethod + '()" title="Add a new value"><i class="icon-plus"></i></a>'));
                return markup;
            }
        };
        return StringArrayInput;
    })(InputBase);
    Forms.StringArrayInput = StringArrayInput;    
    var ArrayInput = (function (_super) {
        __extends(ArrayInput, _super);
        function ArrayInput(workspace, $compile) {
            _super.call(this, workspace, $compile);
            this.workspace = workspace;
            this.$compile = $compile;
        }
        ArrayInput.prototype.doLink = function (scope, element, attrs) {
            var config = new InputBaseConfig();
            config = Forms.configure(config, null, attrs);
            var id = config.name;
            var dataName = attrs["data"] || "";
            var entityName = attrs["entity"] || config.entity;
            function renderRow(cell, type, data) {
                if (data) {
                    var description = data["description"];
                    if (!description) {
                        angular.forEach(data, function (value, key) {
                            if (value && !description) {
                                description = value;
                            }
                        });
                    }
                    return description;
                }
                return null;
            }
            var tableConfigPaths = [
                "properties", 
                id, 
                "inputTable"
            ];
            var tableConfig = null;
            Core.pathGet(scope, tableConfigPaths);
            if (!tableConfig) {
                var tableConfigScopeName = tableConfigPaths.join(".");
                var cellDescription = humanizeValue(id);
                tableConfig = {
                    formConfig: config,
                    title: cellDescription,
                    data: config.entity + "." + id,
                    displayFooter: false,
                    showFilter: false,
                    columnDefs: [
                        {
                            field: '_id',
                            displayName: cellDescription,
                            render: renderRow
                        }
                    ]
                };
                Core.pathSet(scope, tableConfigPaths, tableConfig);
            }
            var table = $('<div hawtio-input-table="' + tableConfigScopeName + '" data="' + dataName + '" property="' + id + '" entity="' + entityName + '"></div>');
            if (config.isReadOnly()) {
                table.attr("readonly", "true");
            }
            $(element).append(this.$compile(table)(scope));
        };
        return ArrayInput;
    })(InputBase);
    Forms.ArrayInput = ArrayInput;    
    var BooleanInput = (function (_super) {
        __extends(BooleanInput, _super);
        function BooleanInput(workspace, $compile) {
            _super.call(this, workspace, $compile);
            this.workspace = workspace;
            this.$compile = $compile;
        }
        BooleanInput.prototype.getInput = function (config, arg, id, modelName) {
            var rc = $('<input class="hawtio-checkbox" type="checkbox">');
            rc.attr('name', id);
            if (config.isReadOnly()) {
                rc.attr('disabled', 'true');
            }
            if (modelName) {
                rc.attr('ng-model', modelName);
            }
            if (config.isReadOnly()) {
                rc.attr('readonly', 'true');
            }
            var scope = config.scope;
            if (scope) {
                function onModelChange() {
                    var value = Core.pathGet(scope, modelName);
                    if (value && "true" === value) {
                        Core.pathSet(scope, modelName, true);
                    }
                }
                scope.$watch(modelName, onModelChange);
                onModelChange();
            }
            return rc;
        };
        return BooleanInput;
    })(InputBase);
    Forms.BooleanInput = BooleanInput;    
})(Forms || (Forms = {}));
var Forms;
(function (Forms) {
    function defaultValues(entity, schema) {
        if (entity && schema) {
            angular.forEach(schema.properties, function (property, key) {
                var defaultValue = property.default;
                if (defaultValue && !entity[key]) {
                    console.log("===== defaulting value " + defaultValue + " into entity[" + key + "]");
                    entity[key] = defaultValue;
                }
            });
        }
    }
    Forms.defaultValues = defaultValues;
    function resolveTypeNameAlias(type, schema) {
        if (type && schema) {
            var alias = lookupDefinition(type, schema);
            if (alias) {
                var realType = alias["type"];
                if (realType) {
                    type = realType;
                }
            }
        }
        return type;
    }
    Forms.resolveTypeNameAlias = resolveTypeNameAlias;
    function isJsonType(name, schema, typeName) {
        var definition = lookupDefinition(name, schema);
        while(definition) {
            var extendsTypes = Core.pathGet(definition, [
                "extends", 
                "type"
            ]);
            if (extendsTypes) {
                if (typeName === extendsTypes) {
                    return true;
                } else {
                    definition = lookupDefinition(extendsTypes, schema);
                }
            } else {
                return false;
            }
        }
        return false;
    }
    Forms.isJsonType = isJsonType;
    function safeIdentifier(id) {
        if (id) {
            return id.replace(/-/g, "_");
        }
        return id;
    }
    Forms.safeIdentifier = safeIdentifier;
    function lookupDefinition(name, schema) {
        if (schema) {
            var defs = schema.definitions;
            if (defs) {
                var answer = defs[name];
                if (answer) {
                    var fullSchema = answer["fullSchema"];
                    if (fullSchema) {
                        return fullSchema;
                    }
                    var extendsTypes = Core.pathGet(answer, [
                        "extends", 
                        "type"
                    ]);
                    if (extendsTypes) {
                        fullSchema = angular.copy(answer);
                        fullSchema.properties = fullSchema.properties || {};
                        if (!angular.isArray(extendsTypes)) {
                            extendsTypes = [
                                extendsTypes
                            ];
                        }
                        angular.forEach(extendsTypes, function (extendType) {
                            if (angular.isString(extendType)) {
                                var extendDef = lookupDefinition(extendType, schema);
                                var properties = Core.pathGet(extendDef, [
                                    "properties"
                                ]);
                                if (properties) {
                                    angular.forEach(properties, function (property, key) {
                                        fullSchema.properties[key] = property;
                                    });
                                }
                            }
                        });
                        answer["fullSchema"] = fullSchema;
                        return fullSchema;
                    }
                }
                return answer;
            }
        }
        return null;
    }
    Forms.lookupDefinition = lookupDefinition;
    function findArrayItemsSchema(property, schema) {
        var items = null;
        if (property && schema) {
            items = property.items;
            if (items) {
                var typeName = items["type"];
                if (typeName) {
                    var definition = lookupDefinition(typeName, schema);
                    if (definition) {
                        return definition;
                    }
                }
            }
            var additionalProperties = property.additionalProperties;
            if (additionalProperties) {
                if (additionalProperties["$ref"] === "#") {
                    return schema;
                }
            }
        }
        return items;
    }
    Forms.findArrayItemsSchema = findArrayItemsSchema;
    function isObjectType(definition) {
        var typeName = Core.pathGet(definition, "type");
        return typeName && "object" === typeName;
    }
    Forms.isObjectType = isObjectType;
    function isArrayOrNestedObject(property, schema) {
        if (property) {
            var propType = resolveTypeNameAlias(property["type"], schema);
            if (propType) {
                if (propType === "object" || propType === "array") {
                    return true;
                }
            }
        }
        return false;
    }
    Forms.isArrayOrNestedObject = isArrayOrNestedObject;
    function configure(config, scopeConfig, attrs) {
        if (angular.isDefined(scopeConfig)) {
            config = angular.extend(config, scopeConfig);
        }
        return angular.extend(config, attrs);
    }
    Forms.configure = configure;
    function getControlGroup(config, arg, id) {
        var rc = $('<div class="' + config.controlgroupclass + '"></div>');
        if (angular.isDefined(arg.description)) {
            rc.attr('title', arg.description);
        }
        return rc;
    }
    Forms.getControlGroup = getControlGroup;
    function getLabel(config, arg, label) {
        return $('<label class="' + config.labelclass + '">' + label + ': </label>');
    }
    Forms.getLabel = getLabel;
    function getControlDiv(config) {
        return $('<div class="' + config.controlclass + '"></div>');
    }
    Forms.getControlDiv = getControlDiv;
    function getHelpSpan(config, arg, id) {
        var rc = '';
        if (angular.isDefined(arg.type) && config.showtypes !== 'false') {
            $('<span class="help-block">Type: ' + arg.type + '</span>');
        }
        return rc;
    }
    Forms.getHelpSpan = getHelpSpan;
})(Forms || (Forms = {}));
var Forms;
(function (Forms) {
    Forms.pluginName = 'hawtio-forms';
    var log = Logger.get("Forms");
    angular.module(Forms.pluginName, [
        'bootstrap', 
        'ngResource', 
        'hawtioCore', 
        'datatable', 
        'ui.bootstrap', 
        'ui.bootstrap.dialog', 
        'hawtio-ui'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/forms/test', {
            templateUrl: 'app/forms/html/test.html'
        }).when('/forms/testTable', {
            templateUrl: 'app/forms/html/testTable.html'
        });
    }).directive('simpleForm', function (workspace, $compile) {
        return new Forms.SimpleForm(workspace, $compile);
    }).directive('hawtioInputTable', function (workspace, $compile) {
        return new Forms.InputTable(workspace, $compile);
    }).directive('hawtioFormText', function (workspace, $compile) {
        return new Forms.TextInput(workspace, $compile);
    }).directive('hawtioFormPassword', function (workspace, $compile) {
        return new Forms.PasswordInput(workspace, $compile);
    }).directive('hawtioFormHidden', function (workspace, $compile) {
        return new Forms.HiddenText(workspace, $compile);
    }).directive('hawtioFormNumber', function (workspace, $compile) {
        return new Forms.NumberInput(workspace, $compile);
    }).directive('hawtioFormSelect', function (workspace, $compile) {
        return new Forms.SelectInput(workspace, $compile);
    }).directive('hawtioFormArray', function (workspace, $compile) {
        return new Forms.ArrayInput(workspace, $compile);
    }).directive('hawtioFormStringArray', function (workspace, $compile) {
        return new Forms.StringArrayInput(workspace, $compile);
    }).directive('hawtioFormCheckbox', function (workspace, $compile) {
        return new Forms.BooleanInput(workspace, $compile);
    }).directive('hawtioFormCustom', function (workspace, $compile) {
        return new Forms.CustomInput(workspace, $compile);
    }).directive('hawtioSubmit', function () {
        return new Forms.SubmitForm();
    }).directive('hawtioReset', function () {
        return new Forms.ResetForm();
    }).run(function (helpRegistry) {
        helpRegistry.addDevDoc("forms", 'app/forms/doc/developer.md');
    });
    hawtioPluginLoader.addModule(Forms.pluginName);
})(Forms || (Forms = {}));
var Forms;
(function (Forms) {
    var InputTableConfig = (function () {
        function InputTableConfig() {
            this.name = 'form';
            this.method = 'post';
            this.entity = 'entity';
            this.tableConfig = 'tableConfig';
            this.mode = 'edit';
            this.data = {};
            this.json = undefined;
            this.properties = [];
            this.action = '';
            this.tableclass = 'gridStyle';
            this.controlgroupclass = 'control-group';
            this.controlclass = 'controls pull-right';
            this.labelclass = 'control-label';
            this.showtypes = 'true';
            this.removeicon = 'icon-remove';
            this.editicon = 'icon-edit';
            this.addicon = 'icon-plus';
            this.removetext = 'Remove';
            this.edittext = 'Edit';
            this.addtext = 'Add';
            this.onadd = 'onadd';
            this.onedit = 'onedit';
            this.onremove = 'onRemove';
        }
        InputTableConfig.prototype.getTableConfig = function () {
            return this.tableConfig || "tableConfig";
        };
        return InputTableConfig;
    })();
    Forms.InputTableConfig = InputTableConfig;    
    var InputTable = (function () {
        function InputTable(workspace, $compile) {
            this.workspace = workspace;
            this.$compile = $compile;
            var _this = this;
            this.restrict = 'A';
            this.scope = true;
            this.replace = true;
            this.transclude = true;
            this.attributeName = 'hawtioInputTable';
            this.link = function (scope, element, attrs) {
                return _this.doLink(scope, element, attrs);
            };
        }
        InputTable.prototype.doLink = function (scope, element, attrs) {
            var _this = this;
            var config = new InputTableConfig();
            var configName = attrs[this.attributeName];
            var tableConfig = Core.pathGet(scope, configName);
            config = Forms.configure(config, tableConfig, attrs);
            var entityName = attrs["entity"] || config.data || "entity";
            var propertyName = attrs["property"] || "arrayData";
            var entityPath = entityName + "." + propertyName;
            var tableName = config["title"] || entityName;
            if (angular.isDefined(config.json)) {
                config.data = $.parseJSON(config.json);
            } else {
                config.data = scope[config.data];
            }
            scope.selectedItems = [];
            var div = $("<div></div>");
            var tableConfig = Core.pathGet(scope, configName);
            if (!tableConfig) {
                console.log("No table configuration for table " + tableName);
            } else {
                tableConfig["selectedItems"] = scope.selectedItems;
            }
            var table = this.createTable(config, configName);
            var group = this.getControlGroup(config, {}, "");
            var controlDiv = this.getControlDiv(config);
            controlDiv.addClass('btn-group');
            group.append(controlDiv);
            function updateData(action) {
                var data = Core.pathGet(scope, entityPath);
                if (data) {
                    data = action(data);
                }
                Core.pathSet(scope, entityPath, data);
                scope.$emit("hawtio.datatable." + entityPath, data);
                Core.$apply(scope);
            }
            function removeSelected(data) {
                angular.forEach(scope.selectedItems, function (selected) {
                    var id = selected["_id"];
                    if (angular.isArray(data)) {
                        data = data.remove(function (value) {
                            return Object.equal(value, selected);
                        });
                        delete selected["_id"];
                        data = data.remove(function (value) {
                            return Object.equal(value, selected);
                        });
                    } else {
                        delete selected["_id"];
                        if (id) {
                            delete data[id];
                        } else {
                            var found = false;
                            angular.forEach(data, function (value, key) {
                                if (!found && (Object.equal(value, selected))) {
                                    console.log("Found row to delete! " + key);
                                    delete data[key];
                                    found = true;
                                }
                            });
                            if (!found) {
                                console.log("Could not find " + JSON.stringify(selected) + " in " + JSON.stringify(data));
                            }
                        }
                    }
                });
                return data;
            }
            var add = null;
            var edit = null;
            var remove = null;
            var addDialog = null;
            var editDialog = null;
            var readOnly = attrs["readonly"];
            if (!readOnly) {
                var property = null;
                var schema = null;
                var dataName = attrs["data"];
                if (dataName) {
                    schema = Core.pathGet(scope, dataName);
                }
                if (propertyName && schema) {
                    property = Core.pathGet(schema, [
                        "properties", 
                        propertyName
                    ]);
                }
                add = this.getAddButton(config);
                scope.addDialogOptions = {
                    backdropFade: true,
                    dialogFade: true
                };
                scope.showAddDialog = false;
                scope.openAddDialog = function () {
                    scope.addEntity = {};
                    scope.addFormConfig = Forms.findArrayItemsSchema(property, schema);
                    if (!addDialog) {
                        var title = "Add " + tableName;
                        addDialog = $('<div modal="showAddDialog" close="closeAddDialog()" options="addDialogOptions">\n' + '<div class="modal-header"><h4>' + title + '</h4></div>\n' + '<div class="modal-body"><div simple-form="addFormConfig" entity="addEntity"></div></div>\n' + '<div class="modal-footer">' + '<button class="btn btn-primary add" type="button" ng-click="addAndCloseDialog()">Add</button>' + '<button class="btn btn-warning cancel" type="button" ng-click="closeAddDialog()">Cancel</button>' + '</div></div>');
                        div.append(addDialog);
                        _this.$compile(addDialog)(scope);
                    }
                    scope.showAddDialog = true;
                    Core.$apply(scope);
                };
                scope.closeAddDialog = function () {
                    scope.showAddDialog = false;
                    scope.addEntity = {};
                };
                scope.addAndCloseDialog = function () {
                    var newData = scope.addEntity;
                    console.log("About to add the new entity " + JSON.stringify(newData));
                    if (newData) {
                        updateData(function (data) {
                            data.push(newData);
                            return data;
                        });
                    }
                    scope.closeAddDialog();
                };
                edit = this.getEditButton(config);
                scope.editDialogOptions = {
                    backdropFade: true,
                    dialogFade: true
                };
                scope.showEditDialog = false;
                scope.openEditDialog = function () {
                    var selected = scope.selectedItems;
                    var editObject = {};
                    if (selected && selected.length) {
                        angular.copy(selected[0], editObject);
                    }
                    scope.editEntity = editObject;
                    scope.editFormConfig = Forms.findArrayItemsSchema(property, schema);
                    if (!editDialog) {
                        var title = "Edit " + tableName;
                        editDialog = $('<div modal="showEditDialog" close="closeEditDialog()" options="editDialogOptions">\n' + '<div class="modal-header"><h4>' + title + '</h4></div>\n' + '<div class="modal-body"><div simple-form="editFormConfig" entity="editEntity"></div></div>\n' + '<div class="modal-footer">' + '<button class="btn btn-primary save" type="button" ng-click="editAndCloseDialog()">Save</button>' + '<button class="btn btn-warning cancel" type="button" ng-click="closeEditDialog()">Cancel</button>' + '</div></div>');
                        div.append(editDialog);
                        _this.$compile(editDialog)(scope);
                    }
                    scope.showEditDialog = true;
                    Core.$apply(scope);
                };
                scope.closeEditDialog = function () {
                    scope.showEditDialog = false;
                    scope.editEntity = {};
                };
                scope.editAndCloseDialog = function () {
                    var newData = scope.editEntity;
                    console.log("About to edit the new entity " + JSON.stringify(newData));
                    if (newData) {
                        updateData(function (data) {
                            data = removeSelected(data);
                            data.push(newData);
                            return data;
                        });
                    }
                    scope.closeEditDialog();
                };
                remove = this.getRemoveButton(config);
            }
            var findFunction = function (scope, func) {
                if (angular.isDefined(scope[func]) && angular.isFunction(scope[func])) {
                    return scope;
                }
                if (angular.isDefined(scope.$parent) && scope.$parent !== null) {
                    return findFunction(scope.$parent, func);
                } else {
                    return null;
                }
            };
            function maybeGet(scope, func) {
                if (scope !== null) {
                    return scope[func];
                }
                return null;
            }
            var onRemoveFunc = config.onremove.replace('(', '').replace(')', '');
            var onEditFunc = config.onedit.replace('(', '').replace(')', '');
            var onAddFunc = config.onadd.replace('(', '').replace(')', '');
            var onRemove = maybeGet(findFunction(scope, onRemoveFunc), onRemoveFunc);
            var onEdit = maybeGet(findFunction(scope, onEditFunc), onEditFunc);
            var onAdd = maybeGet(findFunction(scope, onAddFunc), onAddFunc);
            if (onRemove === null) {
                onRemove = function () {
                    updateData(function (data) {
                        return removeSelected(data);
                    });
                };
            }
            if (onEdit === null) {
                onEdit = function () {
                    scope.openEditDialog();
                };
            }
            if (onAdd === null) {
                onAdd = function (form) {
                    scope.openAddDialog();
                };
            }
            if (add) {
                add.click(function (event) {
                    onAdd();
                    return false;
                });
                controlDiv.append(add);
            }
            if (edit) {
                edit.click(function (event) {
                    onEdit();
                    return false;
                });
                controlDiv.append(edit);
            }
            if (remove) {
                remove.click(function (event) {
                    onRemove();
                    return false;
                });
                controlDiv.append(remove);
            }
            $(div).append(group);
            $(div).append(table);
            $(element).append(div);
            this.$compile(div)(scope);
        };
        InputTable.prototype.getAddButton = function (config) {
            return $('<button type="button" class="btn add"><i class="' + config.addicon + '"></i> ' + config.addtext + '</button>');
        };
        InputTable.prototype.getEditButton = function (config) {
            return $('<button type="button" class="btn edit" ng-disabled="!selectedItems.length"><i class="' + config.editicon + '"></i> ' + config.edittext + '</button>');
        };
        InputTable.prototype.getRemoveButton = function (config) {
            return $('<button type="remove" class="btn remove" ng-disabled="!selectedItems.length"><i class="' + config.removeicon + '"></i> ' + config.removetext + '</button>');
        };
        InputTable.prototype.createTable = function (config, tableConfig) {
            var table = $('<div class="' + config.tableclass + '" hawtio-datatable="' + tableConfig + '">');
            return table;
        };
        InputTable.prototype.getLegend = function (config) {
            var description = Core.pathGet(config, "data.description");
            if (description) {
                return '<legend>' + config.data.description + '</legend>';
            }
            return '';
        };
        InputTable.prototype.getControlGroup = function (config, arg, id) {
            var rc = $('<div class="' + config.controlgroupclass + '"></div>');
            if (angular.isDefined(arg.description)) {
                rc.attr('title', arg.description);
            }
            return rc;
        };
        InputTable.prototype.getControlDiv = function (config) {
            return $('<div class="' + config.controlclass + '"></div>');
        };
        InputTable.prototype.getHelpSpan = function (config, arg, id) {
            var rc = $('<span class="help-block"></span>');
            if (angular.isDefined(arg.type) && config.showtypes !== 'false') {
                rc.append('Type: ' + arg.type);
            }
            return rc;
        };
        return InputTable;
    })();
    Forms.InputTable = InputTable;    
})(Forms || (Forms = {}));
var Forms;
(function (Forms) {
    function createWidget(propTypeName, property, schema, config, id, ignorePrefixInLabel, configScopeName, wrapInGroup) {
        if (typeof wrapInGroup === "undefined") { wrapInGroup = true; }
        var input = null;
        var group = null;
        function copyElementAttributes(element, propertyName) {
            var propertyAttributes = property[propertyName];
            if (propertyAttributes) {
                angular.forEach(propertyAttributes, function (value, key) {
                    if (angular.isString(value)) {
                        element.attr(key, value);
                    }
                });
            }
        }
        function copyAttributes() {
            copyElementAttributes(input, "input-attributes");
            angular.forEach(property, function (value, key) {
                if (angular.isString(value) && key.indexOf("$") < 0 && key !== "type") {
                    var html = Core.escapeHtml(value);
                    input.attr(key, html);
                }
            });
        }
        var options = {
            valueConverter: null
        };
        var safeId = Forms.safeIdentifier(id);
        var inputMarkup = createStandardWidgetMarkup(propTypeName, property, schema, config, options, safeId);
        id;
        if (inputMarkup) {
            input = $(inputMarkup);
            copyAttributes();
            var id = safeId;
            var modelName = config.model || Core.pathGet(property, [
                "input-attributes", 
                "ng-model"
            ]);
            if (!modelName) {
                modelName = config.getEntity() + "." + id;
            }
            input.attr("ng-model", modelName);
            input.attr('name', id);
            var title = property.tooltip || property.label;
            if (title) {
                input.attr('title', title);
            }
            var defaultLabel = id;
            if (ignorePrefixInLabel || property.ignorePrefixInLabel) {
                var idx = id.lastIndexOf('.');
                if (idx > 0) {
                    defaultLabel = id.substring(idx + 1);
                }
            }
            if (input.attr("type") !== "hidden" && wrapInGroup) {
                group = this.getControlGroup(config, config, id);
                var labelElement = Forms.getLabel(config, config, property.title || property.label || humanizeValue(defaultLabel));
                if (title) {
                    labelElement.attr('title', title);
                }
                group.append(labelElement);
                var controlDiv = Forms.getControlDiv(config);
                controlDiv.append(input);
                controlDiv.append(Forms.getHelpSpan(config, config, id));
                group.append(controlDiv);
                copyElementAttributes(controlDiv, "control-attributes");
                copyElementAttributes(group, "control-group-attributes");
                var scope = config.scope;
                if (scope && modelName) {
                    var onModelChange = function (newValue) {
                        scope.$emit("hawtio.form.modelChange", modelName, newValue);
                    };
                    var fn = onModelChange;
                    var converterFn = options.valueConverter;
                    if (converterFn) {
                        fn = function () {
                            converterFn(scope, modelName);
                            var newValue = Core.pathGet(scope, modelName);
                            onModelChange(newValue);
                        };
                    }
                    scope.$watch(modelName, fn);
                }
            }
        } else {
            input = $('<div></div>');
            input.attr(Forms.normalize(propTypeName, property, schema), '');
            copyAttributes();
            input.attr('entity', config.getEntity());
            input.attr('mode', config.getMode());
            var fullSchemaName = config.schemaName;
            if (fullSchemaName) {
                input.attr('schema', fullSchemaName);
            }
            if (configScopeName) {
                input.attr('data', configScopeName);
            }
            if (ignorePrefixInLabel || property.ignorePrefixInLabel) {
                input.attr('ignore-prefix-in-label', true);
            }
            input.attr('name', id);
        }
        var label = property.label;
        if (label) {
            input.attr('title', label);
        }
        if (property.required) {
            if (input[0].localName === "input" && input.attr("type") === "checkbox") {
            } else {
                input.attr('required', 'true');
            }
        }
        return group ? group : input;
    }
    Forms.createWidget = createWidget;
    function createStandardWidgetMarkup(propTypeName, property, schema, config, options, id) {
        var type = Forms.resolveTypeNameAlias(propTypeName, schema);
        if (!type) {
            return '<input type="text"/>';
        }
        var custom = Core.pathGet(property, [
            "formTemplate"
        ]);
        if (custom) {
            return null;
        }
        var inputElement = Core.pathGet(property, [
            "input-element"
        ]);
        if (inputElement) {
            return "<" + inputElement + "></" + inputElement + ">";
        }
        var enumValues = Core.pathGet(property, [
            "enum"
        ]);
        if (enumValues) {
            var required = true;
            var valuesScopeName = null;
            var attributes = "";
            if (enumValues) {
                var scope = config.scope;
                var data = config.data;
                if (data && scope) {
                    var fullSchema = scope[config.schemaName];
                    var model = angular.isString(data) ? scope[data] : data;
                    var paths = id.split(".");
                    var property = null;
                    angular.forEach(paths, function (path) {
                        property = Core.pathGet(model, [
                            "properties", 
                            path
                        ]);
                        var typeName = Core.pathGet(property, [
                            "type"
                        ]);
                        var alias = Forms.lookupDefinition(typeName, fullSchema);
                        if (alias) {
                            model = alias;
                        }
                    });
                    var values = Core.pathGet(property, [
                        "enum"
                    ]);
                    valuesScopeName = "$values_" + id.replace(/\./g, "_");
                    scope[valuesScopeName] = values;
                }
            }
            if (valuesScopeName) {
                attributes += ' ng-options="value for value in ' + valuesScopeName + '"';
            }
            var defaultOption = required ? "" : '<option value=""></option>';
            return '<select' + attributes + '>' + defaultOption + '</select>';
        }
        if (angular.isArray(type)) {
            return null;
        }
        if (!angular.isString(type)) {
            return null;
        }
        var defaultValueConverter = null;
        var defaultValue = property.default;
        if (defaultValue) {
            defaultValueConverter = function (scope, modelName) {
                var value = Core.pathGet(scope, modelName);
                if (!value) {
                    Core.pathSet(scope, modelName, property.default);
                }
            };
            options.valueConverter = defaultValueConverter;
        }
        function getModelValueOrDefault(scope, modelName) {
            var value = Core.pathGet(scope, modelName);
            if (!value) {
                var defaultValue = property.default;
                if (defaultValue) {
                    value = defaultValue;
                    Core.pathSet(scope, modelName, value);
                }
            }
            return value;
        }
        switch(type.toLowerCase()) {
            case "int":
            case "integer":
            case "long":
            case "short":
            case "java.lang.integer":
            case "java.lang.long":
            case "float":
            case "double":
            case "java.lang.float":
            case "java.lang.double":
                options.valueConverter = function (scope, modelName) {
                    var value = getModelValueOrDefault(scope, modelName);
                    if (value && angular.isString(value)) {
                        var numberValue = Number(value);
                        Core.pathSet(scope, modelName, numberValue);
                    }
                };
                return '<input type="number"/>';
            case "array":
            case "java.lang.array":
            case "java.lang.iterable":
            case "java.util.list":
            case "java.util.collection":
            case "java.util.iterator":
            case "java.util.set":
            case "object[]":
                return null;
            case "boolean":
            case "bool":
            case "java.lang.boolean":
                options.valueConverter = function (scope, modelName) {
                    var value = getModelValueOrDefault(scope, modelName);
                    if (value && "true" === value) {
                        Core.pathSet(scope, modelName, true);
                    }
                };
                return '<input type="checkbox"/>';
            case "password":
                return '<input type="password"/>';
            case "hidden":
                return '<input type="hidden"/>';
            default:
                return '<input type="text"/>';
        }
    }
    Forms.createStandardWidgetMarkup = createStandardWidgetMarkup;
    function normalize(type, property, schema) {
        type = Forms.resolveTypeNameAlias(type, schema);
        if (!type) {
            return "hawtio-form-text";
        }
        var custom = Core.pathGet(property, [
            "formTemplate"
        ]);
        if (custom) {
            return "hawtio-form-custom";
        }
        var enumValues = Core.pathGet(property, [
            "enum"
        ]);
        if (enumValues) {
            return "hawtio-form-select";
        }
        if (angular.isArray(type)) {
            return null;
        }
        if (!angular.isString(type)) {
            try  {
                console.log("Unsupported JSON schema type value " + JSON.stringify(type));
            } catch (e) {
                console.log("Unsupported JSON schema type value " + type);
            }
            return null;
        }
        switch(type.toLowerCase()) {
            case "int":
            case "integer":
            case "long":
            case "short":
            case "java.lang.integer":
            case "java.lang.long":
            case "float":
            case "double":
            case "java.lang.float":
            case "java.lang.double":
                return "hawtio-form-number";
            case "array":
            case "java.lang.array":
            case "java.lang.iterable":
            case "java.util.list":
            case "java.util.collection":
            case "java.util.iterator":
            case "java.util.set":
            case "object[]":
                var items = property.items;
                if (items) {
                    var typeName = items.type;
                    if (typeName && typeName === "string") {
                        return "hawtio-form-string-array";
                    }
                }
                return "hawtio-form-array";
            case "boolean":
            case "bool":
            case "java.lang.boolean":
                return "hawtio-form-checkbox";
            case "password":
                return "hawtio-form-password";
            case "hidden":
                return "hawtio-form-hidden";
            default:
                return "hawtio-form-text";
        }
    }
    Forms.normalize = normalize;
})(Forms || (Forms = {}));
var Forms;
(function (Forms) {
    var ResetForm = (function () {
        function ResetForm() {
            var _this = this;
            this.restrict = 'A';
            this.scope = true;
            this.link = function (scope, element, attrs) {
                return _this.doLink(scope, element, attrs);
            };
        }
        ResetForm.prototype.doLink = function (scope, element, attrs) {
            var el = $(element);
            var target = 'form[name=' + attrs['hawtioReset'] + ']';
            el.click(function () {
                var forms = $(target);
                for(var i = 0; i < forms.length; i++) {
                    forms[i].reset();
                }
                return false;
            });
        };
        return ResetForm;
    })();
    Forms.ResetForm = ResetForm;    
})(Forms || (Forms = {}));
var Forms;
(function (Forms) {
    var SimpleFormConfig = (function () {
        function SimpleFormConfig() {
            this.name = 'form';
            this.method = 'post';
            this.entity = 'entity';
            this.schemaName = 'schema';
            this.mode = 'edit';
            this.data = {};
            this.json = undefined;
            this.scope = null;
            this.scopeName = null;
            this.properties = [];
            this.action = '';
            this.formclass = 'hawtio-form form-horizontal no-bottom-margin';
            this.controlgroupclass = 'control-group';
            this.controlclass = 'controls';
            this.labelclass = 'control-label';
            this.showtypes = 'false';
            this.onsubmit = 'onSubmit';
        }
        SimpleFormConfig.prototype.getMode = function () {
            return this.mode || "edit";
        };
        SimpleFormConfig.prototype.getEntity = function () {
            return this.entity || "entity";
        };
        SimpleFormConfig.prototype.isReadOnly = function () {
            return this.getMode() === "view";
        };
        return SimpleFormConfig;
    })();
    Forms.SimpleFormConfig = SimpleFormConfig;    
    var SimpleForm = (function () {
        function SimpleForm(workspace, $compile) {
            this.workspace = workspace;
            this.$compile = $compile;
            var _this = this;
            this.restrict = 'A';
            this.scope = true;
            this.replace = true;
            this.transclude = true;
            this.attributeName = 'simpleForm';
            this.link = function (scope, element, attrs) {
                return _this.doLink(scope, element, attrs);
            };
        }
        SimpleForm.prototype.isReadOnly = function () {
            return false;
        };
        SimpleForm.prototype.doLink = function (scope, element, attrs) {
            var config = new SimpleFormConfig();
            var fullSchemaName = attrs["schema"];
            var fullSchema = fullSchemaName ? scope[fullSchemaName] : null;
            var compiledNode = null;
            var childScope = null;
            var tabs = null;
            var fieldset = null;
            var schema = null;
            var configScopeName = attrs[this.attributeName] || attrs["data"];
            var firstControl = null;
            var simple = this;
            scope.$watch(configScopeName, onWidgetDataChange);
            function onWidgetDataChange(scopeData) {
                if (scopeData) {
                    onScopeData(scopeData);
                }
            }
            function onScopeData(scopeData) {
                config = Forms.configure(config, scopeData, attrs);
                config.schemaName = fullSchemaName;
                config.scopeName = configScopeName;
                config.scope = scope;
                var entityName = config.getEntity();
                if (angular.isDefined(config.json)) {
                    config.data = $.parseJSON(config.json);
                } else {
                    config.data = scopeData;
                }
                var form = simple.createForm(config);
                fieldset = form.find('fieldset');
                schema = config.data;
                tabs = {
                    elements: {},
                    locations: {},
                    use: false
                };
                if (schema && angular.isDefined(schema.tabs)) {
                    tabs.use = true;
                    tabs['div'] = $('<div class="tabbable hawtio-form-tabs"></div>');
                    angular.forEach(schema.tabs, function (value, key) {
                        tabs.elements[key] = $('<div class="tab-pane" title="' + key + '"></div>');
                        tabs['div'].append(tabs.elements[key]);
                        value.forEach(function (val) {
                            tabs.locations[val] = key;
                        });
                    });
                    if (!tabs.locations['*']) {
                        tabs.locations['*'] = Object.extended(schema.tabs).keys()[0];
                    }
                }
                if (!tabs.use) {
                    fieldset.append('<div class="spacer"></div>');
                }
                if (schema) {
                    if (tabs.use) {
                        var tabKeyToIdPropObject = {};
                        angular.forEach(schema.properties, function (property, id) {
                            var tabkey = findTabOrderValue(id);
                            var array = tabKeyToIdPropObject[tabkey];
                            if (!array) {
                                array = [];
                                tabKeyToIdPropObject[tabkey] = array;
                            }
                            array.push({
                                id: id,
                                property: property
                            });
                        });
                        angular.forEach(schema.tabs, function (value, key) {
                            value.forEach(function (val) {
                                var array = tabKeyToIdPropObject[val];
                                if (array) {
                                    angular.forEach(array, function (obj) {
                                        var id = obj.id;
                                        var property = obj.property;
                                        if (id && property) {
                                            addProperty(id, property);
                                        }
                                    });
                                }
                            });
                        });
                    } else {
                        angular.forEach(schema.properties, function (property, id) {
                            addProperty(id, property);
                        });
                    }
                }
                if (tabs.use) {
                    var tabDiv = tabs['div'];
                    var tabCount = Object.keys(tabs.elements).length;
                    if (tabCount < 2) {
                        angular.forEach(tabDiv.children().children(), function (control) {
                            fieldset.append(control);
                        });
                    } else {
                        fieldset.append(tabDiv);
                    }
                }
                var findFunction = function (scope, func) {
                    if (angular.isDefined(scope[func]) && angular.isFunction(scope[func])) {
                        return scope;
                    }
                    if (angular.isDefined(scope.$parent) && scope.$parent !== null) {
                        return findFunction(scope.$parent, func);
                    } else {
                        return null;
                    }
                };
                var onSubmitFunc = config.onsubmit.replace('(', '').replace(')', '');
                var onSubmit = maybeGet(findFunction(scope, onSubmitFunc), onSubmitFunc);
                if (onSubmit === null) {
                    onSubmit = function (json, form) {
                        notification('error', 'No submit handler defined for form ' + form.get(0).name);
                    };
                }
                if (angular.isDefined(onSubmit)) {
                    form.submit(function () {
                        var entity = scope[entityName];
                        onSubmit(entity, form);
                        return false;
                    });
                }
                fieldset.append('<input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;">');
                var autoFocus = form.find("*[autofocus]");
                if (!autoFocus || !autoFocus.length) {
                    if (firstControl) {
                        console.log("No autofocus element, so lets add one!");
                        var input = firstControl.find("input").first() || firstControl.find("select").first();
                        if (input) {
                            input.attr("autofocus", "true");
                        }
                    }
                }
                if (compiledNode) {
                    $(compiledNode).remove();
                }
                if (childScope) {
                    childScope.$destroy();
                }
                childScope = scope.$new(false);
                compiledNode = simple.$compile(form)(childScope);
                var formsScopeProperty = "forms";
                var forms = scope[formsScopeProperty];
                if (!forms) {
                    forms = {};
                    scope[formsScopeProperty] = forms;
                }
                var formName = config.name;
                if (formName) {
                    var formObject = childScope[formName];
                    if (formObject) {
                        forms[formName] = formObject;
                    }
                    var formScope = formName += "$scope";
                    forms[formScope] = childScope;
                }
                $(element).append(compiledNode);
            }
            function findTabKey(id) {
                var tabkey = tabs.locations[id];
                if (!tabkey) {
                    angular.forEach(tabs.locations, function (value, key) {
                        if (!tabkey && key !== "*" && id.match(key)) {
                            tabkey = value;
                        }
                    });
                }
                if (!tabkey) {
                    tabkey = tabs.locations['*'];
                }
                return tabkey;
            }
            function findTabOrderValue(id) {
                var answer = null;
                angular.forEach(schema.tabs, function (value, key) {
                    value.forEach(function (val) {
                        if (!answer && val !== "*" && id.match(val)) {
                            answer = val;
                        }
                    });
                });
                if (!answer) {
                    answer = '*';
                }
                return answer;
            }
            function addProperty(id, property, ignorePrefixInLabel) {
                if (typeof ignorePrefixInLabel === "undefined") { ignorePrefixInLabel = property.ignorePrefixInLabel; }
                var propTypeName = property.type;
                var propSchema = Forms.lookupDefinition(propTypeName, schema);
                if (!propSchema) {
                    propSchema = Forms.lookupDefinition(propTypeName, fullSchema);
                }
                if (property.hidden) {
                    return;
                }
                var nestedProperties = null;
                if (!propSchema && "object" === propTypeName && property.properties) {
                    nestedProperties = property.properties;
                } else if (propSchema && Forms.isObjectType(propSchema)) {
                    console.log("type name " + propTypeName + " has nested object type " + JSON.stringify(propSchema, null, "  "));
                    nestedProperties = propSchema.properties;
                }
                if (nestedProperties) {
                    angular.forEach(nestedProperties, function (childProp, childId) {
                        var newId = id + "." + childId;
                        addProperty(newId, childProp, property.ignorePrefixInLabel);
                    });
                } else {
                    var input = Forms.createWidget(propTypeName, property, schema, config, id, ignorePrefixInLabel, configScopeName);
                    if (tabs.use) {
                        var tabkey = findTabKey(id);
                        tabs.elements[tabkey].append(input);
                    } else {
                        fieldset.append(input);
                    }
                    if (!firstControl) {
                        firstControl = input;
                    }
                }
            }
            function maybeGet(scope, func) {
                if (scope !== null) {
                    return scope[func];
                }
                return null;
            }
        };
        SimpleForm.prototype.createForm = function (config) {
            var form = $('<form class="' + config.formclass + '" novalidate><fieldset></fieldset></form>');
            form.attr('name', config.name);
            form.attr('action', config.action);
            form.attr('method', config.method);
            form.find('fieldset').append(this.getLegend(config));
            return form;
        };
        SimpleForm.prototype.getLegend = function (config) {
            var description = Core.pathGet(config, "data.description");
            if (description) {
                return '<legend>' + description + '</legend>';
            }
            return '';
        };
        return SimpleForm;
    })();
    Forms.SimpleForm = SimpleForm;    
})(Forms || (Forms = {}));
var Forms;
(function (Forms) {
    var SubmitForm = (function () {
        function SubmitForm() {
            var _this = this;
            this.restrict = 'A';
            this.scope = true;
            this.link = function (scope, element, attrs) {
                return _this.doLink(scope, element, attrs);
            };
        }
        SubmitForm.prototype.doLink = function (scope, element, attrs) {
            var el = $(element);
            var target = 'form[name=' + attrs['hawtioSubmit'] + ']';
            el.click(function () {
                $(target).submit();
                return false;
            });
        };
        return SubmitForm;
    })();
    Forms.SubmitForm = SubmitForm;    
})(Forms || (Forms = {}));
var Forms;
(function (Forms) {
    function FormTestController($scope, workspace) {
        $scope.editing = false;
        $scope.html = "text/html";
        $scope.javascript = "javascript";
        $scope.basicFormEx1Entity = {
            'key': 'Some key',
            'value': 'Some value'
        };
        $scope.basicFormEx1EntityString = angular.toJson($scope.basicFormEx1Entity, true);
        $scope.basicFormEx1Result = '';
        $scope.toggleEdit = function () {
            $scope.editing = !$scope.editing;
        };
        $scope.view = function () {
            if (!$scope.editing) {
                return "view";
            }
            return "edit";
        };
        $scope.basicFormEx1 = '<div simple-form name="some-form" action="#/forms/test" method="post" data="basicFormEx1SchemaObject" entity="basicFormEx1Entity" onSubmit="callThis()"></div>';
        $scope.toObject = function (str) {
            return angular.fromJson(str.replace("'", "\""));
        };
        $scope.fromObject = function (str) {
            return angular.toJson($scope[str], true);
        };
        $scope.basicFormEx1Schema = '' + '{\n' + '   "properties": {\n' + '     "key": {\n' + '       "description": "Argument key",\n' + '       "type": "java.lang.String"\n' + '     },\n' + '     "value": {\n' + '       "description": "Argument Value",\n' + '       "type": "java.lang.String"\n' + '     },\n' + '     "longArg": {\n' + '       "description": "Long argument",\n' + '       "type": "Long",\n' + '       "minimum": "5",\n' + '       "maximum": "10"\n' + '     },\n' + '     "intArg": {\n' + '       "description": "Int argument",\n' + '       "type": "Integer"\n' + '     },\n' + '     "objectArg": {\n' + '       "description": "some object",\n' + '       "type": "object"\n' + '     },\n' + '     "booleanArg": {\n' + '       "description": "Some boolean value",\n' + '       "type": "java.lang.Boolean"\n' + '     }\n' + '   },\n' + '   "description": "Show some stuff in a form",\n' + '   "type": "java.lang.String",\n' + '   "tabs": {\n' + '     "Tab One": ["key", "value"],\n' + '     "Tab Two": ["*"],\n' + '     "Tab Three": ["booleanArg"]\n' + '   }\n' + '}';
        $scope.basicFormEx1SchemaObject = $scope.toObject($scope.basicFormEx1Schema);
        $scope.updateSchema = function () {
            $scope.basicFormEx1SchemaObject = $scope.toObject($scope.basicFormEx1Schema);
        };
        $scope.updateEntity = function () {
            $scope.basicFormEx1Entity = angular.fromJson($scope.basicFormEx1EntityString);
        };
        $scope.hawtioResetEx = '<a class="btn" href="" hawtio-reset="some-form"><i class="icon-refresh"></i> Clear</a>';
        $scope.hawtioSubmitEx = '      <a class="btn" href="" hawtio-submit="some-form"><i class="icon-save"></i> Save</a>';
        $scope.callThis = function (json, form) {
            $scope.basicFormEx1Result = angular.toJson(json, true);
            notification('success', 'Form "' + form.get(0).name + '" submitted...');
            Core.$apply($scope);
        };
        $scope.config = {
            name: 'form-with-config-object',
            action: "/some/url",
            method: "post",
            data: 'setVMOption',
            showtypes: 'false'
        };
        $scope.cheese = {
            key: "keyABC",
            value: "valueDEF",
            intArg: 999
        };
        $scope.onCancel = function (form) {
            notification('success', 'Cancel clicked on form "' + form.get(0).name + '"');
        };
        $scope.onSubmit = function (json, form) {
            notification('success', 'Form "' + form.get(0).name + '" submitted... (well not really), data:' + JSON.stringify(json));
        };
        $scope.derp = function (json, form) {
            notification('error', 'derp with json ' + JSON.stringify(json));
        };
        $scope.inputTableSchema = {
            properties: {
                'id': {
                    description: 'Object ID',
                    type: 'java.lang.String'
                }
            },
            description: 'Some objects'
        };
        $scope.inputTableData = [
            {
                id: "object1",
                name: 'foo'
            }, 
            {
                id: "object2",
                name: 'bar'
            }
        ];
        $scope.inputTableConfig = {
            data: 'inputTableData',
            displayFooter: false,
            showFilter: false,
            columnDefs: [
                {
                    field: 'id',
                    displayName: 'ID'
                }, 
                {
                    field: 'name',
                    displayName: 'Name'
                }
            ]
        };
    }
    Forms.FormTestController = FormTestController;
})(Forms || (Forms = {}));
var Git;
(function (Git) {
    var JolokiaGit = (function () {
        function JolokiaGit(mbean, jolokia, localStorage, branch) {
            if (typeof branch === "undefined") { branch = "master"; }
            this.mbean = mbean;
            this.jolokia = jolokia;
            this.localStorage = localStorage;
            this.branch = branch;
        }
        JolokiaGit.prototype.exists = function (branch, path, fn) {
            return this.jolokia.execute(this.mbean, "exists", branch, path, onSuccess(fn));
        };
        JolokiaGit.prototype.read = function (branch, path, fn) {
            return this.jolokia.execute(this.mbean, "read", branch, path, onSuccess(fn));
        };
        JolokiaGit.prototype.write = function (branch, path, commitMessage, contents, fn) {
            var authorName = this.getUserName();
            var authorEmail = this.getUserEmail();
            return this.jolokia.execute(this.mbean, "write", branch, path, commitMessage, authorName, authorEmail, contents, onSuccess(fn));
        };
        JolokiaGit.prototype.createDirectory = function (branch, path, commitMessage, fn) {
            var authorName = this.getUserName();
            var authorEmail = this.getUserEmail();
            return this.jolokia.execute(this.mbean, "createDirectory", branch, path, commitMessage, authorName, authorEmail, onSuccess(fn));
        };
        JolokiaGit.prototype.revertTo = function (objectId, blobPath, commitMessage, fn) {
            var authorName = this.getUserName();
            var authorEmail = this.getUserEmail();
            return this.jolokia.execute(this.mbean, "revertTo", this.branch, objectId, blobPath, commitMessage, authorName, authorEmail, onSuccess(fn));
        };
        JolokiaGit.prototype.rename = function (branch, oldPath, newPath, commitMessage, fn) {
            var authorName = this.getUserName();
            var authorEmail = this.getUserEmail();
            return this.jolokia.execute(this.mbean, "rename", branch, oldPath, newPath, commitMessage, authorName, authorEmail, onSuccess(fn));
        };
        JolokiaGit.prototype.remove = function (branch, path, commitMessage, fn) {
            var authorName = this.getUserName();
            var authorEmail = this.getUserEmail();
            return this.jolokia.execute(this.mbean, "remove", branch, path, commitMessage, authorName, authorEmail, onSuccess(fn));
        };
        JolokiaGit.prototype.completePath = function (branch, completionText, directoriesOnly, fn) {
            return this.jolokia.execute(this.mbean, "completePath", branch, completionText, directoriesOnly, onSuccess(fn));
        };
        JolokiaGit.prototype.history = function (branch, objectId, path, limit, fn) {
            return this.jolokia.execute(this.mbean, "history", branch, objectId, path, limit, onSuccess(fn));
        };
        JolokiaGit.prototype.commitTree = function (commitId, fn) {
            return this.jolokia.execute(this.mbean, "getCommitTree", commitId, onSuccess(fn));
        };
        JolokiaGit.prototype.commitInfo = function (commitId, fn) {
            return this.jolokia.execute(this.mbean, "getCommitInfo", commitId, onSuccess(fn));
        };
        JolokiaGit.prototype.diff = function (objectId, baseObjectId, path, fn) {
            return this.jolokia.execute(this.mbean, "diff", objectId, baseObjectId, path, onSuccess(fn));
        };
        JolokiaGit.prototype.getContent = function (objectId, blobPath, fn) {
            return this.jolokia.execute(this.mbean, "getContent", objectId, blobPath, onSuccess(fn));
        };
        JolokiaGit.prototype.readJsonChildContent = function (path, nameWildcard, search, fn) {
            return this.jolokia.execute(this.mbean, "readJsonChildContent", this.branch, path, nameWildcard, search, onSuccess(fn));
        };
        JolokiaGit.prototype.branches = function (fn) {
            return this.jolokia.execute(this.mbean, "branches", onSuccess(fn));
        };
        JolokiaGit.prototype.getUserName = function () {
            return this.localStorage["gitUserName"] || "anonymous";
        };
        JolokiaGit.prototype.getUserEmail = function () {
            return this.localStorage["gitUserEmail"] || "anonymous@gmail.com";
        };
        return JolokiaGit;
    })();
    Git.JolokiaGit = JolokiaGit;    
})(Git || (Git = {}));
var Git;
(function (Git) {
    function createGitRepository(workspace, jolokia, localStorage) {
        var mbean = getGitMBean(workspace);
        if (mbean && jolokia) {
            return new Git.JolokiaGit(mbean, jolokia, localStorage);
        }
        return null;
    }
    Git.createGitRepository = createGitRepository;
    Git.jmxDomain = "hawtio";
    Git.mbeanType = "GitFacade";
    function hasGit(workspace) {
        return getGitMBean(workspace) !== null;
    }
    Git.hasGit = hasGit;
    function getGitMBean(workspace) {
        return Core.getMBeanTypeObjectName(workspace, Git.jmxDomain, Git.mbeanType);
    }
    Git.getGitMBean = getGitMBean;
    function getGitMBeanFolder(workspace) {
        return Core.getMBeanTypeFolder(workspace, Git.jmxDomain, Git.mbeanType);
    }
    Git.getGitMBeanFolder = getGitMBeanFolder;
    function isGitMBeanFabric(workspace) {
        var folder = getGitMBeanFolder(workspace);
        return folder && folder.entries["repo"] === "fabric";
    }
    Git.isGitMBeanFabric = isGitMBeanFabric;
})(Git || (Git = {}));
var Health;
(function (Health) {
    function HealthController($scope, jolokia, workspace, $templateCache) {
        $scope.levelSorting = {
            'ERROR': 0,
            'WARNING': 1,
            'INFO': 2
        };
        $scope.colorMaps = {
            'ERROR': {
                'Health': '#ff0a47',
                'Remaining': '#e92614'
            },
            'WARNING': {
                'Health': '#33cc00',
                'Remaining': '#f7ee09'
            },
            'INFO': {
                'Health': '#33cc00',
                'Remaining': '#00cc33'
            }
        };
        $scope.results = [];
        $scope.responses = {};
        $scope.mbeans = [];
        $scope.mbeanStatus = {};
        $scope.displays = [];
        $scope.page = '';
        $scope.pageFilter = '';
        $scope.$watch('mbeans', function (newValue, oldValue) {
            Core.unregister(jolokia, $scope);
            if (!newValue) {
                return;
            }
            $scope.mbeanStatus = {};
            newValue.forEach(function (mbean) {
                Core.register(jolokia, $scope, {
                    type: 'exec',
                    mbean: mbean,
                    operation: "healthList()"
                }, {
                    success: $scope.render,
                    error: function (response) {
                        Health.log.error("Failed to invoke healthList() on mbean: " + mbean + " due to: ", response.error);
                        Health.log.info("Stack trace: ", response.stacktrace.split("\n"));
                    }
                });
                var error = function (response) {
                    if (!response.error.has("AttributeNotFoundException")) {
                        Health.log.error("Failed to read CurrentStatus on mbean: " + mbean + " due to: ", response.error);
                        Health.log.info("Stack trace: ", response.stacktrace.split("\n"));
                    }
                };
                jolokia.request({
                    type: 'read',
                    mbean: mbean,
                    attribute: 'CurrentStatus'
                }, {
                    success: function (response) {
                        $scope.mbeanStatus[response.request['mbean']] = response.value;
                        Core.register(jolokia, $scope, {
                            type: 'read',
                            mbean: mbean,
                            attribute: 'CurrentStatus'
                        }, {
                            success: function (response) {
                                if (response.value === $scope.mbeanStatus[response.request['mbean']]) {
                                    return;
                                }
                                $scope.mbeanStatus[response.request['mbean']] = response.value;
                                Core.$apply($scope);
                            },
                            error: error
                        });
                    },
                    error: error
                });
            });
        }, true);
        $scope.getMBeans = function () {
            var healthMap = Health.getHealthMBeans(workspace);
            Health.log.debug("HealthMap: ", healthMap);
            if (healthMap) {
                if (!angular.isArray(healthMap)) {
                    return [
                        healthMap.objectName
                    ];
                }
                var answer = healthMap.map(function (obj) {
                    return obj.objectName;
                });
                Health.log.debug("Health mbeans: ", answer);
                return answer;
            } else {
                Health.log.debug("No health mbeans found...");
                return [];
            }
        };
        $scope.$on('jmxTreeUpdated', function () {
            $scope.mbeans = $scope.getMBeans();
        });
        $scope.$on('$routeChangeSuccess', function () {
            $scope.mbeans = $scope.getMBeans();
        });
        $scope.mbeans = $scope.getMBeans();
        $scope.render = function (response) {
            var mbean = response.request['mbean'];
            var values = response.value;
            var responseJson = angular.toJson(values);
            if (mbean in $scope.responses) {
                if ($scope.responses[mbean] === responseJson) {
                    return;
                }
            }
            $scope.responses[mbean] = responseJson;
            var display = $scope.displays.find(function (m) {
                return m.mbean === mbean;
            });
            values = defaultValues(values);
            values = values.sortBy(function (value) {
                if (!value.level) {
                    return 99;
                }
                return $scope.levelSorting[value.level];
            });
            values.forEach(function (value) {
                var healthPercentCurrent = 0;
                var healthPercentRemaining = 1;
                if ('healthPercent' in value) {
                    var healthPercent = value['healthPercent'];
                    healthPercentCurrent = healthPercent.round(3);
                    healthPercentRemaining = 1 - healthPercentCurrent;
                    healthPercentRemaining = healthPercentRemaining.round(3);
                }
                value.data = {
                    total: 1,
                    terms: [
                        {
                            term: 'Health',
                            count: healthPercentCurrent
                        }, 
                        {
                            term: 'Remaining',
                            count: healthPercentRemaining
                        }
                    ]
                };
                value.colorMap = $scope.colorMaps[value.level];
            });
            if (!display) {
                $scope.displays.push({
                    mbean: mbean,
                    values: values
                });
            } else {
                display.values = values;
            }
            if ($scope.page === '') {
                $scope.page = $templateCache.get('pageTemplate');
            }
            Core.$apply($scope);
        };
        $scope.filterValues = function (value) {
            var json = angular.toJson(value);
            return json.has($scope.pageFilter);
        };
        $scope.sanitize = function (value) {
            var answer = {};
            Object.extended(value).keys().forEach(function (key) {
                if ($scope.showKey(key) && value[key]) {
                    answer[key] = value[key];
                }
            });
            return answer;
        };
        $scope.showKey = function (key) {
            if (key === "colorMap" || key === "data") {
                return false;
            }
            return true;
        };
        $scope.getTitle = function (value) {
            if (value['healthId'].endsWith('profileHealth')) {
                return 'Profile: <strong>' + value['profile'] + '</strong>';
            }
            return 'HealthID: <strong>' + value['healthId'] + '</strong>';
        };
        function defaultValues(values) {
            angular.forEach(values, function (aData) {
                var domain = aData["domain"];
                if (!domain) {
                    var id = aData["healthId"];
                    if (id) {
                        var idx = id.lastIndexOf('.');
                        if (idx > 0) {
                            domain = id.substring(0, idx);
                            var alias = Health.healthDomains[domain];
                            if (alias) {
                                domain = alias;
                            }
                            var kind = aData["kind"];
                            if (!kind) {
                                kind = humanizeValue(id.substring(idx + 1));
                                aData["kind"] = kind;
                            }
                        }
                    }
                    aData["domain"] = domain;
                }
            });
            return values;
        }
        function createOKStatus(object) {
            return {
                healthId: object.domain + ".status",
                level: "INFO",
                message: object.title + " is OK"
            };
        }
    }
    Health.HealthController = HealthController;
})(Health || (Health = {}));
var Health;
(function (Health) {
    Health.log = Logger.get("Health");
    Health.healthDomains = {
        "org.apache.activemq": "ActiveMQ",
        "org.apache.camel": "Camel",
        "org.fusesource.fabric": "Fabric"
    };
    function hasHealthMBeans(workspace) {
        var beans = getHealthMBeans(workspace);
        if (beans) {
            if (angular.isArray(beans)) {
                return beans.length >= 1;
            }
            return true;
        }
        return false;
    }
    Health.hasHealthMBeans = hasHealthMBeans;
    function getHealthMBeans(workspace) {
        if (workspace) {
            var healthMap = workspace.mbeanServicesToDomain["Health"] || {};
            var selection = workspace.selection;
            if (selection) {
                var domain = selection.domain;
                if (domain) {
                    var mbean = healthMap[domain];
                    if (mbean) {
                        return mbean;
                    }
                }
            }
            if (healthMap) {
                var answer = [];
                angular.forEach(healthMap, function (value) {
                    if (angular.isArray(value)) {
                        answer = answer.concat(value);
                    } else {
                        answer.push(value);
                    }
                });
                return answer;
            } else {
                return null;
            }
        }
    }
    Health.getHealthMBeans = getHealthMBeans;
})(Health || (Health = {}));
var Health;
(function (Health) {
    var pluginName = 'health';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'hawtioCore', 
        'hawtio-ui'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/health', {
            templateUrl: 'app/health/html/health.html'
        });
    }).run(function ($location, workspace, viewRegistry, layoutFull, helpRegistry) {
        viewRegistry['health'] = layoutFull;
        helpRegistry.addUserDoc('health', 'app/health/doc/help.md', function () {
            return Health.hasHealthMBeans(workspace);
        });
        workspace.topLevelTabs.push({
            content: "Health",
            title: "View the health of the various sub systems",
            isValid: function (workspace) {
                return Health.hasHealthMBeans(workspace);
            },
            href: function () {
                return "#/health";
            }
        });
    });
    hawtioPluginLoader.addModule(pluginName);
})(Health || (Health = {}));
var IDE;
(function (IDE) {
    function getIdeMBean(workspace) {
        return Core.getMBeanTypeObjectName(workspace, "hawtio", "IdeFacade");
    }
    IDE.getIdeMBean = getIdeMBean;
    function isOpenInIdeaSupported(workspace, localStorage) {
        var value = localStorage["openInIDEA"];
        return value !== "false";
    }
    IDE.isOpenInIdeaSupported = isOpenInIdeaSupported;
    function isOpenInTextMateSupported(workspace, localStorage) {
        var value = localStorage["openInTextMate"];
        return value !== "false";
    }
    IDE.isOpenInTextMateSupported = isOpenInTextMateSupported;
    function findClassAbsoluteFileName(mbean, jolokia, localStorage, fileName, className, onResult) {
        var sourceRoots = [];
        var answer = null;
        if (mbean) {
            answer = jolokia.execute(mbean, "findClassAbsoluteFileName", fileName, className, sourceRoots, onSuccess(onResult));
        } else {
            onResult(answer);
        }
        return answer;
    }
    IDE.findClassAbsoluteFileName = findClassAbsoluteFileName;
    function asNumber(value, defaultValue) {
        if (typeof defaultValue === "undefined") { defaultValue = 0; }
        if (angular.isNumber(value)) {
            return value;
        } else if (angular.isString(value)) {
            return parseInt(value);
        } else {
            return defaultValue;
        }
    }
    function max(v1, v2) {
        return (v1 >= v2) ? v1 : v2;
    }
    function ideaOpenAndNavigate(mbean, jolokia, absoluteFileName, line, column, fn) {
        if (typeof fn === "undefined") { fn = null; }
        var answer = null;
        if (mbean) {
            line = max(asNumber(line) - 1, 0);
            column = max(asNumber(column) - 1, 0);
            answer = jolokia.execute(mbean, "ideaOpenAndNavigate", absoluteFileName, line, column, onSuccess(fn));
        }
        return answer;
    }
    IDE.ideaOpenAndNavigate = ideaOpenAndNavigate;
})(IDE || (IDE = {}));
var IDE;
(function (IDE) {
    var pluginName = 'ide';
    angular.module(pluginName, [
        'bootstrap', 
        'hawtioCore'
    ]).directive('hawtioOpenIde', function (localStorage, workspace, jolokia) {
        return new IDE.OpenInIdeDirective(localStorage, workspace, jolokia);
    }).run(function (helpRegistry) {
        helpRegistry.addDevDoc('IDE', 'app/ide/doc/developer.md');
    });
    hawtioPluginLoader.addModule(pluginName);
})(IDE || (IDE = {}));
var IDE;
(function (IDE) {
    var log = Logger.get("IDE");
    var OpenInIdeDirective = (function () {
        function OpenInIdeDirective(localStorage, workspace, jolokia) {
            this.localStorage = localStorage;
            this.workspace = workspace;
            this.jolokia = jolokia;
            var _this = this;
            this.restrict = 'E';
            this.replace = true;
            this.transclude = false;
            this.scope = {
                fileName: '@',
                className: '@',
                line: '@',
                column: '@'
            };
            this.link = function (scope, element, attrs) {
                return _this.doLink(scope, element, attrs);
            };
        }
        OpenInIdeDirective.prototype.doLink = function ($scope, $element, $attrs) {
            var workspace = this.workspace;
            var jolokia = this.jolokia;
            var mbean = IDE.getIdeMBean(workspace);
            var fileName = $scope.fileName;
            if (mbean && fileName) {
                var className = $scope.className;
                var line = $scope.line;
                var col = $scope.col;
                if (!angular.isDefined(line) || line === null) {
                    line = 0;
                }
                if (!angular.isDefined(col) || col === null) {
                    col = 0;
                }
                if (IDE.isOpenInIdeaSupported(workspace, localStorage)) {
                    var ideaButton = $('<button class="btn btn-mini"><img src="app/ide/img/intellijidea.png" width="16" height="16"></button>');
                    function onResult(absoluteName) {
                        if (!absoluteName) {
                            log.info("Could not find file in source code: " + fileName + " class: " + className);
                            ideaButton.attr("title", "Could not find source file: " + fileName);
                        } else {
                            ideaButton.attr("title", "Opening in IDEA: " + absoluteName);
                            IDE.ideaOpenAndNavigate(mbean, jolokia, absoluteName, line, col);
                        }
                    }
                    ideaButton.on("click", function () {
                        log.info("Finding local file name: " + fileName + " className: " + className);
                        IDE.findClassAbsoluteFileName(mbean, jolokia, localStorage, fileName, className, onResult);
                    });
                    $element.append(ideaButton);
                }
            }
        };
        return OpenInIdeDirective;
    })();
    IDE.OpenInIdeDirective = OpenInIdeDirective;    
})(IDE || (IDE = {}));
var Infinispan;
(function (Infinispan) {
    var CLI = (function () {
        function CLI(workspace, jolokia) {
            this.workspace = workspace;
            this.jolokia = jolokia;
            this.cacheName = null;
            this.sessionId = null;
            this.useSessionIds = true;
        }
        CLI.prototype.setCacheName = function (name) {
            if (name) {
                name = trimQuotes(name);
                var postfix = "(local)";
                if (name.endsWith(postfix)) {
                    name = name.substring(0, name.length - postfix.length);
                }
            }
            if (!this.cacheName || this.cacheName !== name) {
                if (this.sessionId) {
                    this.deleteSession(this.sessionId);
                }
                this.cacheName = name;
                this.createSession();
            }
        };
        CLI.prototype.createSession = function () {
            var _this = this;
            if (this.useSessionIds) {
                var mbean = Infinispan.getInterpreterMBean(this.workspace);
                if (mbean) {
                    var cli = this;
                    this.jolokia.execute(mbean, "createSessionId", this.cacheName, onSuccess(function (value) {
                        console.log("Has session ID: " + value);
                        _this.sessionId = value;
                    }));
                } else {
                    this.warnMissingMBean();
                }
            }
        };
        CLI.prototype.execute = function (sql, handler) {
            if (sql) {
                sql = sql.trim();
                if (!sql.endsWith(";")) {
                    sql += ";";
                }
                var sessionId = (this.useSessionIds) ? this.sessionId : null;
                if (!this.useSessionIds) {
                    sql = "cache " + this.cacheName + "; " + sql;
                }
                if (sessionId || !this.useSessionIds) {
                    var mbean = Infinispan.getInterpreterMBean(this.workspace);
                    if (mbean) {
                        this.jolokia.execute(mbean, "execute", sessionId, sql, onSuccess(handler));
                    } else {
                        this.warnMissingMBean();
                    }
                } else {
                    notification("warning", "Cannot evaluate SQL as we don't have a sessionId yet!");
                }
            }
        };
        CLI.prototype.deleteSession = function (sessionId) {
        };
        CLI.prototype.warnMissingMBean = function () {
            notification("error", "No Interpreter MBean available");
        };
        return CLI;
    })();
    Infinispan.CLI = CLI;    
})(Infinispan || (Infinispan = {}));
var Infinispan;
(function (Infinispan) {
    function infinispanCacheName(entity) {
        if (entity) {
            var id = entity._id;
            if (id) {
                var prefix = 'name="';
                var idx = id.indexOf(prefix);
                if (idx > 0) {
                    idx += prefix.length;
                    var lastIdx = id.indexOf('"', idx + 1);
                    if (lastIdx > 0) {
                        return id.substring(idx, lastIdx);
                    } else {
                        return id.substring(idx);
                    }
                }
            }
            return id;
        }
        return null;
    }
    Infinispan.infinispanCacheName = infinispanCacheName;
    function getInterpreterMBean(workspace) {
        if (workspace) {
            var folder = workspace.findMBeanWithProperties(Infinispan.jmxDomain, {
                component: "Interpreter",
                type: "CacheManager"
            });
            if (folder) {
                return folder.objectName;
            }
        }
        return null;
    }
    Infinispan.getInterpreterMBean = getInterpreterMBean;
    function getSelectedCacheName(workspace) {
        var selection = workspace.selection;
        if (selection && selection.domain === Infinispan.jmxDomain) {
            return selection.entries["name"];
        }
        return null;
    }
    Infinispan.getSelectedCacheName = getSelectedCacheName;
})(Infinispan || (Infinispan = {}));
var Infinispan;
(function (Infinispan) {
    var pluginName = 'infinispan';
    Infinispan.jmxDomain = 'Infinispan';
    var toolBar = "app/infinispan/html/attributeToolBar.html";
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'hawtioCore'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/infinispan/query', {
            templateUrl: 'app/infinispan/html/query.html'
        });
    }).filter('infinispanCacheName', function () {
        return Infinispan.infinispanCacheName;
    }).run(function (workspace, viewRegistry, helpRegistry) {
        viewRegistry['infinispan'] = 'app/infinispan/html/layoutCacheTree.html';
        helpRegistry.addUserDoc('infinispan', 'app/infinispan/doc/help.md', function () {
            return workspace.treeContainsDomainAndProperties(Infinispan.jmxDomain);
        });
        var nameTemplate = '<div class="ngCellText" title="Infinispan Cache">{{row.entity | infinispanCacheName}}</div>';
        var attributes = workspace.attributeColumnDefs;
        attributes[Infinispan.jmxDomain + "/Caches/folder"] = [
            {
                field: '_id',
                displayName: 'Name',
                cellTemplate: nameTemplate,
                width: "**"
            }, 
            {
                field: 'numberOfEntries',
                displayName: 'Entries'
            }, 
            {
                field: 'hits',
                displayName: 'Hits'
            }, 
            {
                field: 'hitRatio',
                displayName: 'Hit Ratio'
            }, 
            {
                field: 'stores',
                displayName: 'Stores'
            }, 
            {
                field: 'averageReadTime',
                displayName: 'Avg Read Time'
            }, 
            {
                field: 'averageWriteTime',
                displayName: 'Avg Write Time'
            }
        ];
        workspace.topLevelTabs.push({
            content: "Infinispan",
            title: "View your distributed data",
            isValid: function (workspace) {
                return workspace.treeContainsDomainAndProperties(Infinispan.jmxDomain);
            },
            href: function () {
                return "#/jmx/attributes?tab=infinispan";
            },
            isActive: function (workspace) {
                return workspace.isTopTabActive("infinispan");
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-pencil"></i> Query',
            title: "Perform InSQL commands on the cache",
            isValid: function (workspace) {
                return Infinispan.getSelectedCacheName(workspace) && Infinispan.getInterpreterMBean(workspace);
            },
            href: function () {
                return "#/infinispan/query";
            }
        });
    });
    hawtioPluginLoader.addModule(pluginName);
})(Infinispan || (Infinispan = {}));
var Infinispan;
(function (Infinispan) {
    function QueryController($scope, $location, workspace, jolokia) {
        var interpreter = new Infinispan.CLI(workspace, jolokia);
        $scope.logs = [];
        $scope.filteredLogs = [];
        $scope.selectedItems = [];
        $scope.searchText = "";
        $scope.filter = {
            logLevelQuery: "",
            logLevelExactMatch: false
        };
        var columnDefs = [
            {
                field: 'key',
                displayName: 'Key'
            }, 
            {
                field: 'value',
                displayName: 'Value'
            }
        ];
        $scope.gridOptions = {
            selectedItems: $scope.selectedItems,
            data: 'filteredLogs',
            displayFooter: false,
            showFilter: false,
            filterOptions: {
                filterText: "searchText"
            },
            columnDefs: columnDefs,
            rowDetailTemplateId: "logDetailTemplate"
        };
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(refreshCacheName, 50);
        });
        $scope.$watch('workspace.selection', function () {
            refreshCacheName();
        });
        $scope.doQuery = function () {
            if ($scope.sql) {
                interpreter.execute($scope.sql, handleResults);
            }
        };
        function handleResults(results) {
            $scope.output = null;
            if (!results) {
                console.log("no output...");
            } else {
                var error = results["ERROR"] || "";
                var stackTrace = results["STACKTRACE"] || "";
                if (error || stackTrace) {
                    if (stackTrace) {
                        error += "\n" + stackTrace;
                    }
                    notification("error", error);
                } else {
                    var output = results["OUTPUT"];
                    if (!output) {
                        notification("error", "No results!");
                    } else {
                        $scope.output = output;
                        console.log("==== output: " + output);
                        Core.$apply($scope);
                    }
                }
            }
        }
        function refreshCacheName() {
            var cacheName = Infinispan.getSelectedCacheName(workspace);
            console.log("selected cacheName is: " + cacheName);
            if (cacheName) {
                interpreter.setCacheName(cacheName);
            }
        }
    }
    Infinispan.QueryController = QueryController;
})(Infinispan || (Infinispan = {}));
var Infinispan;
(function (Infinispan) {
    function TreeController($scope, $location, workspace) {
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateSelectionFromURL, 50);
        });
        $scope.$watch('workspace.tree', function () {
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            var children = [];
            var tree = workspace.tree;
            if (tree) {
                var domainName = Infinispan.jmxDomain;
                var folder = tree.get(domainName);
                if (folder) {
                    var cachesFolder = new Folder("Caches");
                    cachesFolder.domain = domainName;
                    cachesFolder.key = "root-Infinispan-Caches";
                    cachesFolder.typeName = "Caches";
                    children.push(cachesFolder);
                    addAllCacheStatistics(folder, cachesFolder);
                }
                var treeElement = $("#infinispantree");
                Jmx.enableTree($scope, $location, workspace, treeElement, children);
                setTimeout(updateSelectionFromURL, 50);
            }
        });
        function addAllCacheStatistics(folder, answer) {
            if (folder) {
                var children = folder.children;
                if (children) {
                    angular.forEach(folder.children, function (value, key) {
                        if (value.objectName && value.title === "Statistics") {
                            var cacheName = value.parent.parent.title || value.title;
                            var name = humanizeValue(cacheName);
                            var cacheFolder = new Folder(name);
                            cacheFolder.addClass = "org-infinispn-cache";
                            cacheFolder.typeName = "Cache";
                            cacheFolder.key = answer.key + "-" + cacheName;
                            cacheFolder.objectName = value.objectName;
                            cacheFolder.domain = value.domain;
                            cacheFolder.entries = value.entries;
                            answer.children.push(cacheFolder);
                        } else {
                            addAllCacheStatistics(value, answer);
                        }
                    });
                }
            }
        }
        function updateSelectionFromURL() {
            Jmx.updateTreeSelectionFromURL($location, $("#infinispantree"), true);
        }
    }
    Infinispan.TreeController = TreeController;
})(Infinispan || (Infinispan = {}));
var Insight;
(function (Insight) {
    function AllController($scope, jolokia, localStorage) {
        $scope.result = null;
        $scope.containers = [];
        $scope.profiles = [
            Insight.allContainers
        ];
        $scope.versions = [];
        $scope.profile = Insight.allContainers;
        $scope.time_options = [
            '1m', 
            '5m', 
            '15m', 
            '1h', 
            '6h', 
            '12h'
        ];
        $scope.timespan = '1m';
        $scope.updateRate = parseInt(localStorage['updateRate']);
        $scope.chartsMeta = [];
        Core.register(jolokia, $scope, {
            type: 'exec',
            mbean: Insight.managerMBean,
            operation: 'containers()',
            arguments: []
        }, onSuccess(onContainers));
        function onContainers(response) {
            if (!Object.equal($scope.result, response.value)) {
                $scope.result = response.value;
                $scope.containers = [];
                $scope.profiles = [
                    Insight.allContainers
                ];
                $scope.versions = [];
                $scope.result.forEach(function (container) {
                    $scope.profiles = $scope.profiles.union(container.profileIds.map(function (id) {
                        return {
                            id: id
                        };
                    }));
                    $scope.versions = $scope.versions.union([
                        container.versionId
                    ]);
                    $scope.containers.push({
                        name: container.id,
                        alive: container.alive,
                        version: container.versionId,
                        profileIds: container.profileIds
                    });
                });
                Core.$apply($scope);
            }
        }
        $scope.metrics = jQuery.parseJSON(jolokia.getAttribute("org.fusesource.insight:type=MetricsCollector", "Metrics"));
        var jreq = {
            type: 'exec',
            mbean: 'org.elasticsearch:service=restjmx',
            operation: 'exec',
            arguments: [
                'GET', 
                '/_all/_mapping', 
                ''
            ]
        };
        jolokia.request(jreq, {
            success: function (response) {
                var data = jQuery.parseJSON(response.value);
                var roots = {};
                var children = [];
                for(var index in data) {
                    if (index.startsWith("insight-")) {
                        for(var mapping in data[index]) {
                            if (mapping.startsWith("sta-")) {
                                var name = mapping.substring(4);
                                if (!roots[name]) {
                                    roots[name] = true;
                                    children.push({
                                        title: name,
                                        expand: true,
                                        children: getChildren(data[index][mapping], name, "", data[index][mapping]["properties"]["host"] !== undefined)
                                    });
                                }
                            }
                        }
                    }
                }
                $("#insighttree").dynatree({
                    checkbox: true,
                    selectMode: 2,
                    onSelect: onSelect,
                    onClick: onClick,
                    onKeydown: onKeydown,
                    children: children
                });
            }
        });
        $scope.set_timespan = function (t) {
            $scope.timespan = t;
            rebuildCharts();
        };
        $scope.profile_changed = function () {
            rebuildCharts();
        };
        function onSelect(flag, node) {
            var selNodes = node.tree.getSelectedNodes();
            $scope.chartsMeta = selNodes.map(function (node) {
                var data = node.data;
                return {
                    name: data["field"],
                    field: data["field"],
                    type: data["type"],
                    host: data["hasHost"]
                };
            });
            rebuildCharts();
        }
        function onClick(node, event) {
            if (node.getEventTargetType(event) === "title") {
                node.toggleSelect();
            }
            return true;
        }
        function onKeydown(node, event) {
            if (event.which === 32) {
                node.toggleSelect();
                return false;
            }
        }
        function rebuildCharts() {
            var chartsDef = [];
            $scope.chartsMeta.forEach(function (meta) {
                var metadata = $scope.metrics[meta.type] !== undefined ? $scope.metrics[meta.type][meta.field] : undefined;
                if (meta.host) {
                    $scope.containers.forEach(function (container) {
                        if ($scope.profile === Insight.allContainers || $.inArray($scope.profile.id, container.profileIds) >= 0) {
                            chartsDef.push({
                                name: (metadata !== undefined ? metadata['description'] : meta.name) + " [" + container.name + "]",
                                type: "sta-" + meta.type,
                                field: meta.field,
                                query: "host: \"" + container.name + "\"",
                                meta: metadata
                            });
                        }
                    });
                } else {
                    chartsDef.push({
                        name: metadata !== undefined ? metadata['description'] : meta.name,
                        type: "sta-" + meta.type,
                        field: meta.field,
                        meta: metadata
                    });
                }
            });
            Insight.createCharts($scope, chartsDef, "#charts", jolokia);
        }
    }
    Insight.AllController = AllController;
    function getChildren(node, type, field, hasHost) {
        var children = [];
        for(var p in node["properties"]) {
            var obj = node["properties"][p];
            if (obj["type"] === 'long' || obj["type"] === 'double') {
                children.push({
                    title: p,
                    field: field + p,
                    type: type,
                    hasHost: hasHost
                });
            } else if (obj["properties"]) {
                children.push({
                    title: p,
                    isFolder: true,
                    children: getChildren(obj, type, field + p + ".", hasHost)
                });
            }
        }
        return children;
    }
})(Insight || (Insight = {}));
var Insight;
(function (Insight) {
    function ElasticSearchController($scope, jolokia, localStorage) {
        $scope.time_options = [
            '1m', 
            '5m', 
            '15m', 
            '1h', 
            '6h', 
            '12h'
        ];
        $scope.timespan = '1m';
        $scope.metrics = [];
        $scope.updateRate = parseInt(localStorage['updateRate']);
        $scope.data = [];
        var chartsDef = [
            {
                name: "active primary shards",
                type: "sta-elasticsearch",
                field: "active_primary_shards"
            }, 
            {
                name: "active shards",
                type: "sta-elasticsearch",
                field: "active_shards"
            }, 
            {
                name: "relocating shards",
                type: "sta-elasticsearch",
                field: "relocating_shards"
            }, 
            {
                name: "initializing shards",
                type: "sta-elasticsearch",
                field: "initializing_shards"
            }, 
            {
                name: "unassigned shards",
                type: "sta-elasticsearch",
                field: "unassigned_shards"
            }
        ];
        var mainDiv = "#charts";
        $scope.set_timespan = function (t) {
            $scope.timespan = t;
            rebuildCharts();
        };
        rebuildCharts();
        function rebuildCharts() {
            Insight.createCharts($scope, chartsDef, mainDiv, jolokia);
        }
    }
    Insight.ElasticSearchController = ElasticSearchController;
})(Insight || (Insight = {}));
var Insight;
(function (Insight) {
    Insight.managerMBean = "org.fusesource.fabric:type=Fabric";
    Insight.allContainers = {
        id: '-- all --'
    };
    function hasInsight(workspace) {
        return workspace.treeContainsDomainAndProperties('org.elasticsearch', {
            service: 'restjmx'
        });
    }
    Insight.hasInsight = hasInsight;
    function createCharts($scope, chartsDef, element, jolokia) {
        var chartsDiv = $(element);
        var width = chartsDiv.width() - 80;
        var context = cubism.context().serverDelay(interval_to_seconds('1m') * 1000).clientDelay($scope.updateRate).step(interval_to_seconds($scope.timespan) * 1000).size(width);
        var d3Selection = d3.select(chartsDiv[0]);
        d3Selection.html("");
        d3Selection.selectAll(".axis").data([
            "top", 
            "bottom"
        ]).enter().append("div").attr("class", function (d) {
            return d + " axis";
        }).each(function (d) {
            d3.select(this).call(context.axis().ticks(12).orient(d));
        });
        d3Selection.append("div").attr("class", "rule").call(context.rule());
        context.on("focus", function (i) {
            d3Selection.selectAll(".value").style("right", i === null ? null : context.size() - i + "px");
        });
        chartsDef.forEach(function (chartDef) {
            d3Selection.call(function (div) {
                div.append("div").data([
                    chart(context, chartDef, jolokia)
                ]).attr("class", "horizon").call(context.horizon());
            });
        });
    }
    Insight.createCharts = createCharts;
    function chart(context, chartDef, jolokia) {
        return context.metric(function (start, stop, step, callback) {
            var values = [], value = 0, start = +start, stop = +stop;
            var range = {
                range: {
                    timestamp: {
                        from: new Date(start).toISOString(),
                        to: new Date(stop).toISOString()
                    }
                }
            };
            var filter;
            if (chartDef.query) {
                filter = {
                    fquery: {
                        query: {
                            filtered: {
                                query: {
                                    query_string: {
                                        query: chartDef.query
                                    }
                                },
                                filter: range
                            }
                        }
                    }
                };
            } else {
                filter = range;
            }
            var request = {
                size: 0,
                facets: {
                    histo: {
                        date_histogram: {
                            value_field: chartDef.field,
                            key_field: "timestamp",
                            interval: step + "ms"
                        },
                        facet_filter: filter
                    }
                }
            };
            var jreq = {
                type: 'exec',
                mbean: 'org.elasticsearch:service=restjmx',
                operation: 'exec',
                arguments: [
                    'POST', 
                    '/_all/' + chartDef.type + '/_search', 
                    JSON.stringify(request)
                ]
            };
            jolokia.request(jreq, {
                success: function (response) {
                    var map = {};
                    var data = jQuery.parseJSON(response.value)["facets"]["histo"]["entries"];
                    data.forEach(function (entry) {
                        map[entry.time] = entry.max;
                    });
                    var delta = 0;
                    if (chartDef.meta !== undefined) {
                        if (chartDef.meta['type'] === 'trends-up' || chartDef.meta['type'] === 'peak') {
                            delta = +1;
                        } else if (chartDef.meta['type'] === 'trends-down') {
                            delta = -1;
                        }
                    }
                    while(start < stop) {
                        var v = 0;
                        if (delta !== 0) {
                            if (map[start - step] !== undefined) {
                                var d = (map[start] - map[start - step]) * delta;
                                v = d > 0 ? d : 0;
                            }
                        } else {
                            if (map[start] !== undefined) {
                                v = map[start];
                            }
                        }
                        values.push(v);
                        start += step;
                    }
                    callback(null, values);
                }
            });
        }, chartDef.name);
    }
    function interval_to_seconds(string) {
        var matches = string.match(/(\d+)([Mwdhms])/);
        switch(matches[2]) {
            case 'M':
                return matches[1] * 2592000;
                ;
            case 'w':
                return matches[1] * 604800;
                ;
            case 'd':
                return matches[1] * 86400;
                ;
            case 'h':
                return matches[1] * 3600;
                ;
            case 'm':
                return matches[1] * 60;
                ;
            case 's':
                return matches[1];
        }
    }
    function time_ago(string) {
        return new Date(new Date().getTime() - (interval_to_seconds(string) * 1000));
    }
})(Insight || (Insight = {}));
var Insight;
(function (Insight) {
    var insightPlugin = angular.module('insight', [
        'hawtioCore'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/insight/all', {
            templateUrl: 'app/insight/html/all.html'
        }).when('/insight/jvms', {
            templateUrl: 'app/insight/html/jvms.html'
        }).when('/insight/elasticsearch', {
            templateUrl: 'app/insight/html/elasticsearch.html'
        });
    });
    insightPlugin.run(function (workspace, viewRegistry, helpRegistry) {
        viewRegistry["insight"] = "app/insight/html/layoutInsight.html";
        helpRegistry.addUserDoc('insight', 'app/insight/doc/help.md', function () {
            return Fabric.hasFabric(workspace) && workspace.treeContainsDomainAndProperties("org.elasticsearch", {
                service: "restjmx"
            });
        });
        workspace.topLevelTabs.push({
            content: "Metrics",
            title: "View Insight metrics",
            href: function () {
                return "#/insight/all";
            },
            isValid: function (workspace) {
                return Fabric.hasFabric(workspace) && workspace.treeContainsDomainAndProperties("org.elasticsearch", {
                    service: "restjmx"
                });
            }
        });
    });
    hawtioPluginLoader.addModule('insight');
})(Insight || (Insight = {}));
var Insight;
(function (Insight) {
    function JVMsController($scope, jolokia, localStorage) {
        $scope.time_options = [
            '1m', 
            '5m', 
            '15m', 
            '1h', 
            '6h', 
            '12h'
        ];
        $scope.timespan = '1m';
        $scope.containers = [];
        $scope.profiles = [
            Insight.allContainers
        ];
        $scope.versions = [];
        $scope.profile = Insight.allContainers;
        $scope.metrics = [];
        $scope.updateRate = parseInt(localStorage['updateRate']);
        $scope.data = [];
        var chartsMeta = [
            {
                name: "threads",
                type: "sta-jvm",
                field: "threads.count"
            }, 
            {
                name: "mem",
                type: "sta-jvm",
                field: "mem.heap_used"
            }
        ];
        var mainDiv = "#charts";
        $scope.set_timespan = function (t) {
            $scope.timespan = t;
            rebuildCharts();
        };
        $scope.profile_changed = function () {
            rebuildCharts();
        };
        Core.register(jolokia, $scope, {
            type: 'exec',
            mbean: Insight.managerMBean,
            operation: 'containers()',
            arguments: []
        }, onSuccess(onContainers));
        function onContainers(response) {
            if (!Object.equal($scope.result, response.value)) {
                $scope.result = response.value;
                $scope.containers = [];
                $scope.profiles = [
                    Insight.allContainers
                ];
                $scope.versions = [];
                $scope.result.forEach(function (container) {
                    $scope.profiles = $scope.profiles.union(container.profileIds.map(function (id) {
                        return {
                            id: id
                        };
                    }));
                    $scope.versions = $scope.versions.union([
                        container.versionId
                    ]);
                    $scope.containers.push({
                        name: container.id,
                        alive: container.alive,
                        version: container.versionId,
                        profileIds: container.profileIds
                    });
                });
                Core.$apply($scope);
                rebuildCharts();
            }
        }
        function rebuildCharts() {
            var chartsDef = [];
            chartsMeta.forEach(function (meta) {
                $scope.containers.forEach(function (container) {
                    if ($scope.profile === Insight.allContainers || $.inArray($scope.profile.id, container.profileIds) >= 0) {
                        chartsDef.push({
                            name: meta.name + " [" + container.name + "]",
                            type: meta.type,
                            field: meta.field,
                            query: "host: \"" + container.name + "\""
                        });
                    }
                });
            });
            Insight.createCharts($scope, chartsDef, mainDiv, jolokia);
        }
    }
    Insight.JVMsController = JVMsController;
})(Insight || (Insight = {}));
var JBoss;
(function (JBoss) {
    function ConnectorsController($scope, $location, workspace, jolokia) {
        var stateTemplate = '<div class="ngCellText pagination-centered" title="{{row.getProperty(col.field)}}"><i class="{{row.getProperty(col.field) | jbossIconClass}}"></i></div>';
        $scope.connectors = [];
        var columnDefs = [
            {
                field: 'bound',
                displayName: 'State',
                cellTemplate: stateTemplate,
                width: 56,
                minWidth: 56,
                maxWidth: 56,
                resizable: false
            }, 
            {
                field: 'name',
                displayName: 'Name',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'port',
                displayName: 'Port',
                cellFilter: null,
                width: "*",
                resizable: true
            }
        ];
        $scope.gridOptions = {
            data: 'connectors',
            displayFooter: false,
            displaySelectionCheckbox: false,
            canSelectRows: false,
            columnDefs: columnDefs,
            filterOptions: {
                filterText: ''
            }
        };
        function render(response) {
            $scope.connectors = [];
            function onAttributes(response) {
                var obj = response.value;
                if (obj) {
                    obj.mbean = response.request.mbean;
                    if (!obj.port) {
                        obj.port = obj.boundPort;
                    }
                    if (!obj.name) {
                        obj.name = "mail-smtp";
                    }
                    $scope.connectors.push(obj);
                    Core.$apply($scope);
                }
            }
            angular.forEach(response, function (value, key) {
                var mbean = value;
                if (mbean.toString() !== "jboss.as:socket-binding-group=standard-sockets") {
                    if (mbean.toString().lastIndexOf("management") > 0) {
                        jolokia.request({
                            type: "read",
                            mbean: mbean,
                            attribute: [
                                "boundPort", 
                                "name", 
                                "bound"
                            ]
                        }, onSuccess(onAttributes));
                    } else if (mbean.toString().lastIndexOf("mail-smtp") > 0) {
                        jolokia.request({
                            type: "read",
                            mbean: mbean,
                            attribute: [
                                "port"
                            ]
                        }, onSuccess(onAttributes));
                    } else {
                        jolokia.request({
                            type: "read",
                            mbean: mbean,
                            attribute: [
                                "port", 
                                "name", 
                                "bound"
                            ]
                        }, onSuccess(onAttributes));
                    }
                }
            });
            Core.$apply($scope);
        }
        ;
        $scope.$on('jmxTreeUpdated', reloadFunction);
        $scope.$watch('workspace.tree', reloadFunction);
        function reloadFunction() {
            setTimeout(loadData, 50);
        }
        function loadData() {
            console.log("Loading JBoss connector data...");
            jolokia.search("jboss.as:socket-binding-group=standard-sockets,*", onSuccess(render));
        }
    }
    JBoss.ConnectorsController = ConnectorsController;
})(JBoss || (JBoss = {}));
var JBoss;
(function (JBoss) {
    function DmrController($scope, $location, workspace) {
        var search = $location.search();
        var connectUrl = url("/proxy/localhost/9990/management");
        var user = search["_user"] || "";
        var pwd = search["_pwd"] || "";
        if (user) {
            connectUrl += "?_user=" + user;
            if (pwd) {
                connectUrl += "&_pwd=" + pwd;
            }
        }
        var isDmr = "dmr" === search["_format"];
        var data = null;
        var format = "application/dmr-encoded";
        if (isDmr) {
            var op = new dmr.ModelNode();
            op.get("operation").set("read-attribute");
            op.get("address").setEmptyList();
            op.get("name").set("release-version");
            data = op.toBase64String();
        } else {
            format = "application/json";
            var request = {
                "operation": "read-resource"
            };
            data = JSON.stringify(request);
        }
        console.log("Using dmr: " + isDmr + " with content type: " + format + " and data " + data);
        $.ajax({
            url: connectUrl,
            data: data,
            processData: false,
            type: "POST",
            dataType: "text",
            contentType: format,
            accepts: format,
            headers: {
                "Content-type": format,
                "Accept": format
            }
        }).done(onData);
        function onData(data) {
            if (data) {
                var json = null;
                if (isDmr) {
                    var response = dmr.ModelNode.fromBase64(data);
                    var jsonText = response.toJSONString();
                    json = JSON.parse(jsonText);
                } else {
                    json = JSON.parse(data);
                    json = json.result;
                }
                $scope.row = json;
                Core.$apply($scope);
                console.log("Response: " + JSON.stringify(json, null, "  "));
            }
        }
    }
    JBoss.DmrController = DmrController;
})(JBoss || (JBoss = {}));
var JBoss;
(function (JBoss) {
    function JBossController($scope, $location, jolokia) {
        var stateTemplate = '<div class="ngCellText pagination-centered" title="{{row.getProperty(col.field)}}"><i class="{{row.getProperty(col.field) | jbossIconClass}}"></i></div>';
        $scope.uninstallDialog = new Core.Dialog();
        $scope.webapps = [];
        $scope.selected = [];
        var columnDefs = [
            {
                field: 'status',
                displayName: 'State',
                cellTemplate: stateTemplate,
                width: 56,
                minWidth: 56,
                maxWidth: 56,
                resizable: false
            }, 
            {
                field: 'name',
                displayName: 'Name',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'contextPath',
                displayName: 'Context-Path',
                cellFilter: null,
                width: "*",
                resizable: true
            }
        ];
        $scope.gridOptions = {
            data: 'webapps',
            displayFooter: true,
            selectedItems: $scope.selected,
            selectWithCheckboxOnly: true,
            columnDefs: columnDefs,
            filterOptions: {
                filterText: ''
            }
        };
        function render(response) {
            $scope.webapps = [];
            $scope.mbeanIndex = {};
            $scope.selected.length = 0;
            function onAttributes(response) {
                var obj = response.value;
                if (obj) {
                    obj.mbean = response.request.mbean;
                    var mbean = obj.mbean;
                    if (mbean) {
                        obj.name = JBoss.cleanWebAppName(obj.name);
                        obj.contextPath = JBoss.cleanContextPath(obj.name);
                        var idx = $scope.mbeanIndex[mbean];
                        if (angular.isDefined(idx)) {
                            $scope.webapps[mbean] = obj;
                        } else {
                            $scope.mbeanIndex[mbean] = $scope.webapps.length;
                            $scope.webapps.push(obj);
                        }
                        Core.$apply($scope);
                    }
                }
            }
            angular.forEach(response, function (value, key) {
                var mbean = value;
                jolokia.request({
                    type: "read",
                    mbean: mbean,
                    attribute: [
                        "name", 
                        "status"
                    ]
                }, onSuccess(onAttributes));
            });
            Core.$apply($scope);
        }
        ;
        $scope.controlWebApps = function (op) {
            var mbeanNames = $scope.selected.map(function (b) {
                return b.mbean;
            });
            if (!angular.isArray(mbeanNames)) {
                mbeanNames = [
                    mbeanNames
                ];
            }
            var lastIndex = (mbeanNames.length || 1) - 1;
            angular.forEach(mbeanNames, function (mbean, idx) {
                var onResponse = (idx >= lastIndex) ? $scope.onLastResponse : $scope.onResponse;
                jolokia.request({
                    type: 'exec',
                    mbean: mbean,
                    operation: op,
                    arguments: null
                }, onSuccess(onResponse, {
                    error: onResponse
                }));
            });
        };
        $scope.start = function () {
            $scope.controlWebApps('deploy');
        };
        $scope.stop = function () {
            $scope.controlWebApps('undeploy');
        };
        $scope.reload = function () {
            $scope.controlWebApps('redeploy');
        };
        $scope.uninstall = function () {
            $scope.controlWebApps('remove');
            $scope.uninstallDialog.close();
        };
        $scope.onLastResponse = function (response) {
            $scope.onResponse(response);
            loadData();
        };
        $scope.onResponse = function (response) {
        };
        $scope.$on('jmxTreeUpdated', reloadFunction);
        $scope.$watch('workspace.tree', reloadFunction);
        function reloadFunction() {
            setTimeout(loadData, 50);
        }
        function loadData() {
            console.log("Loading JBoss webapp data...");
            jolokia.search("jboss.as:deployment=*", onSuccess(render));
        }
        $scope.jbossServerVersion = "";
        $scope.jbossServerName = "";
        $scope.jbossServerLaunchType = "";
        var servers = jolokia.search("jboss.as:management-root=*");
        if (servers && servers.length === 1) {
            $scope.jbossServerVersion = jolokia.getAttribute(servers[0], "releaseVersion");
            $scope.jbossServerName = jolokia.getAttribute(servers[0], "name");
            $scope.jbossServerLaunchType = jolokia.getAttribute(servers[0], "launchType");
        } else {
            var wildflyMBean = 'jboss.as:management-root=server';
            var response = jolokia.request({
                type: "read",
                mbean: wildflyMBean,
                attribute: [
                    "releaseVersion", 
                    "name", 
                    "launchType"
                ]
            });
            if (response) {
                var obj = response.value;
                if (obj) {
                    $scope.jbossServerVersion = obj.releaseVersion;
                    $scope.jbossServerName = obj.name;
                    $scope.jbossServerLaunchType = obj.launchType;
                }
            } else {
                console.log("Cannot find JBoss/Wildfly server or there was more than one server");
            }
        }
    }
    JBoss.JBossController = JBossController;
})(JBoss || (JBoss = {}));
var JBoss;
(function (JBoss) {
    function cleanWebAppName(name) {
        if (name && name.lastIndexOf(".war") > -1) {
            return name.replace(".war", "");
        } else {
            return name;
        }
    }
    JBoss.cleanWebAppName = cleanWebAppName;
    function cleanContextPath(contextPath) {
        if (contextPath) {
            return "/" + cleanWebAppName(contextPath);
        } else {
            return "";
        }
    }
    JBoss.cleanContextPath = cleanContextPath;
    function iconClass(state) {
        if (state) {
            switch(state.toString().toLowerCase()) {
                case 'started':
                    return "green icon-play-circle";
                case 'ok':
                    return "green icon-play-circle";
                case 'true':
                    return "green icon-play-circle";
            }
        }
        return "orange icon-off";
    }
    JBoss.iconClass = iconClass;
})(JBoss || (JBoss = {}));
var JBoss;
(function (JBoss) {
    var pluginName = 'jboss';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'ui.bootstrap.dialog', 
        'hawtioCore'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/jboss/server', {
            templateUrl: 'app/jboss/html/server.html'
        }).when('/jboss/applications', {
            templateUrl: 'app/jboss/html/applications.html'
        }).when('/jboss/dmr', {
            templateUrl: 'app/jboss/html/dmr.html'
        }).when('/jboss/connectors', {
            templateUrl: 'app/jboss/html/connectors.html'
        }).when('/jboss/mbeans', {
            templateUrl: 'app/jboss/html/mbeans.html'
        });
    }).filter('jbossIconClass', function () {
        return JBoss.iconClass;
    }).run(function ($location, workspace, viewRegistry, helpRegistry) {
        viewRegistry['jboss'] = "app/jboss/html/layoutJBossTabs.html";
        viewRegistry['jbossTree'] = "app/jboss/html/layoutJBossTree.html";
        helpRegistry.addUserDoc(pluginName, 'app/' + pluginName + '/doc/help.md', function () {
            return workspace.treeContainsDomainAndProperties("jboss.as") || workspace.treeContainsDomainAndProperties("jboss.jta") || workspace.treeContainsDomainAndProperties("jboss.modules");
        });
        workspace.topLevelTabs.push({
            content: "JBoss",
            title: "Manage your JBoss container",
            isValid: function (workspace) {
                return workspace.treeContainsDomainAndProperties("jboss.as") || workspace.treeContainsDomainAndProperties("jboss.jta") || workspace.treeContainsDomainAndProperties("jboss.modules");
            },
            href: function () {
                return "#/jboss/applications";
            },
            isActive: function (workspace) {
                return workspace.isTopTabActive("jboss");
            }
        });
    });
    hawtioPluginLoader.addModule(pluginName);
})(JBoss || (JBoss = {}));
var JBoss;
(function (JBoss) {
    function TreeController($scope, $location, workspace) {
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateSelectionFromURL, 50);
        });
        $scope.$watch('workspace.tree', function () {
            console.log("workspace tree has changed, lets reload!!");
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            var children = [];
            var tree = workspace.tree;
            if (tree) {
                var nodes = tree.children;
                angular.forEach(nodes, function (node) {
                    var nodeChildren = node.children;
                    if (node.title.startsWith("jboss") && nodeChildren) {
                        children = children.concat(nodeChildren);
                    }
                });
            }
            var treeElement = $("#jbossTree");
            Jmx.enableTree($scope, $location, workspace, treeElement, children, true);
            setTimeout(updateSelectionFromURL, 50);
        });
        function updateSelectionFromURL() {
            Jmx.updateTreeSelectionFromURL($location, $("#jbossTree"), true);
        }
    }
    JBoss.TreeController = TreeController;
})(JBoss || (JBoss = {}));
var Jclouds;
(function (Jclouds) {
    function ApiListController($scope, $location, workspace, jolokia) {
        $scope.result = {};
        $scope.apis = [];
        $scope.type = "";
        $scope.types = [
            "", 
            "blobstore", 
            "compute", 
            "loadbalancer"
        ];
        var key = $location.search()['type'];
        if (key) {
            $scope.type = key;
        }
        $scope.selectedApis = [];
        $scope.apiTable = {
            data: 'apis',
            showFilter: false,
            showColumnMenu: false,
            filterOptions: {
                useExternalFilter: true
            },
            selectedItems: $scope.selectedApis,
            rowHeight: 32,
            selectWithCheckboxOnly: true,
            columnDefs: [
                {
                    field: 'id',
                    displayName: 'Id',
                    cellTemplate: '<div class="ngCellText"><a href="#/jclouds/api/{{row.getProperty(col.field)}}{{hash}}">{{row.getProperty(col.field)}}</a></div>',
                    width: 200,
                    resizable: false
                }, 
                {
                    field: 'name',
                    displayName: 'Name',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 350
                }, 
                {
                    field: 'type',
                    displayName: 'Type',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 100
                }
            ]
        };
        Core.register(jolokia, $scope, {
            type: 'read',
            mbean: Jclouds.getSelectionJcloudsMBean(workspace)
        }, onSuccess(render));
        function render(response) {
            if (!Object.equal($scope.result, response.value)) {
                $scope.result = response.value;
                $scope.apis = $scope.result["Apis"];
                Jclouds.populateTypeForApis($scope.apis);
                Core.$apply($scope);
            }
        }
    }
    Jclouds.ApiListController = ApiListController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function ApiController($scope, $filter, workspace, $routeParams) {
        $scope.apiId = $routeParams.apiId;
        updateTableContents();
        function setApi(api) {
            Jclouds.populateTypeForApi(api);
            $scope.row = api;
            Core.$apply($scope);
        }
        ;
        function updateTableContents() {
            var jcloudsCoreMbean = Jclouds.getSelectionJcloudsMBean(workspace);
            var jolokia = workspace.jolokia;
            if (jcloudsCoreMbean) {
                setApi(jolokia.request({
                    type: 'exec',
                    mbean: Jclouds.getSelectionJcloudsMBean(workspace),
                    operation: 'findApiById(java.lang.String)',
                    arguments: [
                        $scope.apiId
                    ]
                }).value);
            }
        }
    }
    Jclouds.ApiController = ApiController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function BlobstoreNavigationController($scope, $routeParams, workspace) {
        $scope.blobstoreId = $routeParams.blobstoreId;
        $scope.isActive = function (nav) {
            if (angular.isString(nav)) {
                return workspace.isLinkActive(nav);
            }
            var fn = nav.isActive;
            if (fn) {
                return fn(workspace);
            }
            return workspace.isLinkActive(nav.href());
        };
    }
    Jclouds.BlobstoreNavigationController = BlobstoreNavigationController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function BlobstoreListController($scope, $location, workspace, jolokia) {
        $scope.result = {};
        $scope.blobstoreServiceIds = [];
        $scope.blobstoreServices = [];
        $scope.blobstoreTable = {
            plugins: [],
            data: 'blobstoreServices',
            showFilter: false,
            showColumnMenu: false,
            filterOptions: {
                useExternalFilter: true
            },
            selectedItems: $scope.selectedBlobstoreServices,
            rowHeight: 32,
            selectWithCheckboxOnly: true,
            columnDefs: [
                {
                    field: 'name',
                    displayName: 'Service Name',
                    cellTemplate: '<div class="ngCellText"><a href="#/jclouds/blobstore/service/{{row.getProperty(col.field)}}{{hash}}">{{row.getProperty(col.field)}}</a></div>',
                    width: 200,
                    resizable: false
                }, 
                {
                    field: 'providerId',
                    displayName: 'Proivder',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 200,
                    resizable: false
                }, 
                {
                    field: 'identity',
                    displayName: 'Identity',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 200,
                    resizable: false
                }
            ]
        };
        render(Jclouds.listJcloudsMBeanNameOfType(workspace, "blobstore"));
        function render(response) {
            if (!Object.equal($scope.result, response)) {
                $scope.result = response;
                $scope.blobstoreServiceIds = $scope.result;
                var blobstoreServices = [];
                angular.forEach($scope.blobstoreServiceIds, function (id) {
                    blobstoreServices.push(Jclouds.findContextByName(workspace, id));
                });
                $scope.blobstoreServices = blobstoreServices;
                Core.$apply($scope);
            }
        }
    }
    Jclouds.BlobstoreListController = BlobstoreListController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function BlobstoreContainerListController($scope, $location, workspace, jolokia, $routeParams) {
        $scope.blobstoreId = $routeParams.blobstoreId;
        $scope.result = {};
        $scope.containers = [];
        $scope.selectedContainers = [];
        $scope.containerTable = {
            plugins: [],
            data: 'containers',
            showFilter: false,
            showColumnMenu: false,
            filterOptions: {
                useExternalFilter: true
            },
            selectedItems: $scope.selectedContainers,
            rowHeight: 32,
            selectWithCheckboxOnly: true,
            columnDefs: [
                {
                    field: 'name',
                    displayName: 'Name',
                    cellTemplate: '<div class="ngCellText"><a href="#/jclouds/blobstore/container/{{blobstoreId}}/{{row.getProperty(col.field)}}{{hash}}">{{row.getProperty(col.field)}}</a></div>',
                    width: 200,
                    resizable: false
                }, 
                {
                    field: 'creationDate',
                    displayName: 'Created',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 200,
                    resizable: false
                }
            ]
        };
        Core.register(jolokia, $scope, {
            type: 'exec',
            mbean: Jclouds.getSelectionJcloudsBlobstoreMBean(workspace, $scope.blobstoreId),
            operation: 'list()'
        }, onSuccess(render));
        function render(response) {
            if (!Object.equal($scope.result, response.value)) {
                $scope.result = response.value;
                $scope.containers = $scope.result;
                Core.$apply($scope);
            }
        }
    }
    Jclouds.BlobstoreContainerListController = BlobstoreContainerListController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function BlobstoreContainerController($scope, $filter, workspace, $routeParams) {
        $scope.blobstoreId = $routeParams.blobstoreId;
        $scope.containerId = $routeParams.containerId;
        $scope.directory = $routeParams.directory;
        $scope.contents = [];
        $scope.breadcrumbs = loadBreadcrumbs($scope.blobstoreId, $scope.containerId, $scope.directory);
        $scope.contentTable = {
            data: 'contents',
            displayFooter: false,
            columnDefs: [
                {
                    field: 'name',
                    displayName: 'Content',
                    cellTemplate: '<div class="ngCellText"><a href="#/jclouds/blobstore/container/{{blobstoreId}}/{{containerId}}/{{row.entity.fullpath}}{{hash}}">{{row.getProperty(col.field)}}</a></div>',
                    cellFilter: ""
                }, 
                {
                    field: 'createdDate',
                    displayName: 'Created',
                    cellFilter: "date:'EEE, MMM d, y : hh:mm:ss a'"
                }, 
                {
                    field: 'lastModifiedDate',
                    displayName: 'Modified',
                    cellFilter: "date:'EEE, MMM d, y : hh:mm:ss a'"
                }
            ]
        };
        updateTableContents();
        function setContainers(containers) {
            $scope.contents = populatePathAndName(filterContainers(containers, $scope.directory), $scope.directory);
            Core.$apply($scope);
        }
        ;
        function updateTableContents() {
            var jolokia = workspace.jolokia;
            var blobstoreMbean = Jclouds.getSelectionJcloudsBlobstoreMBean(workspace, $scope.blobstoreId);
            if (blobstoreMbean) {
                if ($scope.directory) {
                    setContainers(jolokia.request({
                        type: 'exec',
                        mbean: blobstoreMbean,
                        operation: 'list(java.lang.String, java.lang.String)',
                        arguments: [
                            $scope.containerId, 
                            $scope.directory
                        ]
                    }).value);
                } else {
                    setContainers(jolokia.request({
                        type: 'exec',
                        mbean: blobstoreMbean,
                        operation: 'list(java.lang.String)',
                        arguments: [
                            $scope.containerId
                        ]
                    }).value);
                }
            }
        }
        function filterContainers(containers, directory) {
            return containers.filter(function (container) {
                return container.name !== directory;
            });
        }
        function populatePathAndName(containers, directory) {
            var updatedContainers = [];
            angular.forEach(containers, function (container) {
                var updateContainer = container;
                updateContainer.fullpath = container.name;
                if (updateContainer.name.startsWith(directory)) {
                    updateContainer.name = updateContainer.name.substring(directory.length + 1);
                }
                updatedContainers.push(updateContainer);
            });
            return updatedContainers;
        }
        $scope.isBlob = function (container) {
            return container.type === 'BLOB';
        };
        function loadBreadcrumbs(blobstore, container, directory) {
            var href = "#/jclouds/blobstore/container/" + blobstore + "/" + container;
            var breadcrumbs = [
                {
                    href: href,
                    name: "/" + container
                }
            ];
            var array = directory ? directory.split("/") : [];
            angular.forEach(array, function (name) {
                if (!name.startsWith("/") && !href.endsWith("/")) {
                    href += "/";
                }
                href += name;
                breadcrumbs.push({
                    href: href,
                    name: name
                });
            });
            return breadcrumbs;
        }
    }
    Jclouds.BlobstoreContainerController = BlobstoreContainerController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function BlobstoreLocationListController($scope, $location, workspace, jolokia, $routeParams) {
        $scope.blobstoreId = $routeParams.blobstoreId;
        $scope.result = {};
        $scope.locations = [];
        $scope.selectedLocations = [];
        $scope.locationTable = {
            plugins: [],
            data: 'locations',
            showFilter: false,
            showColumnMenu: false,
            filterOptions: {
                useExternalFilter: true
            },
            selectedItems: $scope.selectedLocations,
            rowHeight: 32,
            selectWithCheckboxOnly: true,
            columnDefs: [
                {
                    field: 'id',
                    displayName: 'Id',
                    cellTemplate: '<div class="ngCellText"><a href="#/jclouds/blobstore/location/{{blobstoreId}}/{{row.getProperty(col.field)}}{{hash}}">{{row.getProperty(col.field)}}</a></div>',
                    width: 200,
                    resizable: false
                }, 
                {
                    field: 'description',
                    displayName: 'Description',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 200,
                    resizable: false
                }
            ]
        };
        Core.register(jolokia, $scope, {
            type: 'exec',
            mbean: Jclouds.getSelectionJcloudsBlobstoreMBean(workspace, $scope.blobstoreId),
            operation: 'listAssignableLocations()'
        }, onSuccess(render));
        function render(response) {
            if (!Object.equal($scope.result, response.value)) {
                $scope.result = response.value;
                $scope.locations = $scope.result;
                Core.$apply($scope);
            }
        }
    }
    Jclouds.BlobstoreLocationListController = BlobstoreLocationListController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function BlobstoreLocationController($scope, $filter, workspace, $routeParams) {
        $scope.blobstoreId = $routeParams.blobstoreId;
        $scope.locationId = $routeParams.locationId;
        updateTableContents();
        function setLocationProfiles(locationProfiles) {
            $scope.row = findLocationById(locationProfiles, $scope.locationId);
            Core.$apply($scope);
        }
        ;
        function updateTableContents() {
            var jolokia = workspace.jolokia;
            var blobstoreMbean = Jclouds.getSelectionJcloudsBlobstoreMBean(workspace, $scope.blobstoreId);
            if (blobstoreMbean) {
                setLocationProfiles(jolokia.request({
                    type: 'exec',
                    mbean: blobstoreMbean,
                    operation: 'listAssignableLocations()'
                }).value);
            }
        }
        function findLocationById(locationProfiles, id) {
            return locationProfiles.find(function (location) {
                return location.id === id;
            });
        }
    }
    Jclouds.BlobstoreLocationController = BlobstoreLocationController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function ComputeNavigationController($scope, $routeParams, workspace) {
        $scope.computeId = $routeParams.computeId;
        $scope.isActive = function (nav) {
            if (angular.isString(nav)) {
                return workspace.isLinkActive(nav);
            }
            var fn = nav.isActive;
            if (fn) {
                return fn(workspace);
            }
            return workspace.isLinkActive(nav.href());
        };
    }
    Jclouds.ComputeNavigationController = ComputeNavigationController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function ComputeListController($scope, $location, workspace, jolokia) {
        $scope.result = {};
        $scope.computeServiceIds = [];
        $scope.computeServices = [];
        $scope.computeTable = {
            plugins: [],
            data: 'computeServices',
            showFilter: false,
            showColumnMenu: false,
            filterOptions: {
                useExternalFilter: true
            },
            selectedItems: $scope.selectedComputeServices,
            rowHeight: 32,
            selectWithCheckboxOnly: true,
            columnDefs: [
                {
                    field: 'name',
                    displayName: 'Service Name',
                    cellTemplate: '<div class="ngCellText"><a href="#/jclouds/compute/service/{{row.getProperty(col.field)}}{{hash}}">{{row.getProperty(col.field)}}</a></div>',
                    width: 200,
                    resizable: false
                }, 
                {
                    field: 'providerId',
                    displayName: 'Proivder',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 200,
                    resizable: false
                }, 
                {
                    field: 'identity',
                    displayName: 'Identity',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 200,
                    resizable: false
                }
            ]
        };
        render(Jclouds.listJcloudsMBeanNameOfType(workspace, "compute"));
        function render(response) {
            if (!Object.equal($scope.result, response)) {
                $scope.result = response;
                $scope.computeServiceIds = $scope.result;
                var computeServices = [];
                angular.forEach($scope.computeServiceIds, function (id) {
                    computeServices.push(Jclouds.findContextByName(workspace, id));
                });
                $scope.computeServices = computeServices;
                Core.$apply($scope);
            }
        }
    }
    Jclouds.ComputeListController = ComputeListController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function HardwareListController($scope, $location, workspace, jolokia, $routeParams) {
        $scope.computeId = $routeParams.computeId;
        $scope.result = {};
        $scope.hardwares = [];
        $scope.selectedHardwares = [];
        $scope.hardwareTable = {
            plugins: [],
            data: 'hardwares',
            showFilter: false,
            showColumnMenu: false,
            filterOptions: {
                useExternalFilter: true
            },
            selectedItems: $scope.selectedHardwares,
            rowHeight: 32,
            selectWithCheckboxOnly: true,
            columnDefs: [
                {
                    field: 'id',
                    displayName: 'Id',
                    cellTemplate: '<div class="ngCellText"><a href="#/jclouds/compute/hardware/{{computeId}}/{{row.getProperty(col.field)}}{{hash}}">{{row.getProperty(col.field)}}</a></div>',
                    width: 200,
                    resizable: false
                }, 
                {
                    field: 'name',
                    displayName: 'Name',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 200,
                    resizable: false
                }, 
                {
                    field: 'ram',
                    displayName: 'Ram',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 200,
                    resizable: false
                }, 
                {
                    field: 'hypervisor',
                    displayName: 'Hypervisor',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 200,
                    resizable: false
                }
            ]
        };
        Core.register(jolokia, $scope, {
            type: 'exec',
            mbean: Jclouds.getSelectionJcloudsComputeMBean(workspace, $scope.computeId),
            operation: 'listHardwareProfiles()'
        }, onSuccess(render));
        function render(response) {
            if (!Object.equal($scope.result, response.value)) {
                $scope.result = response.value;
                $scope.hardwares = $scope.result;
                Core.$apply($scope);
            }
        }
        $scope.is64BitIcon = function (is64bit) {
            if (is64bit) {
                return 'icon-thumbs-up';
            } else {
                return 'icon-thumbs-down';
            }
        };
    }
    Jclouds.HardwareListController = HardwareListController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function HardwareController($scope, $filter, workspace, $routeParams) {
        $scope.computeId = $routeParams.computeId;
        $scope.hardwareId = $routeParams.hardwareId;
        updateTableContents();
        $scope.processorsTable = {
            plugins: [],
            data: 'processors',
            showFilter: false,
            displayFooter: false,
            displaySelectionCheckbox: false,
            showColumnMenu: false,
            rowHeight: 32,
            columnDefs: [
                {
                    field: 'cores',
                    displayName: 'Cores',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 50,
                    resizable: false
                }, 
                {
                    field: 'speed',
                    displayName: 'Speed',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 100,
                    resizable: false
                }
            ]
        };
        $scope.volumesTable = {
            plugins: [],
            data: 'volumes',
            showFilter: false,
            displayFooter: false,
            displaySelectionCheckbox: false,
            showColumnMenu: false,
            rowHeight: 32,
            columnDefs: [
                {
                    field: 'id',
                    displayName: 'Id',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 100,
                    resizable: false
                }, 
                {
                    field: 'type',
                    displayName: 'Type',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 100,
                    resizable: false
                }, 
                {
                    field: 'device',
                    displayName: 'Device',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 100,
                    resizable: false
                }, 
                {
                    field: 'size',
                    displayName: 'Size',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 100,
                    resizable: false
                }, 
                {
                    field: 'bootDevice',
                    displayName: 'Boot Device',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 100,
                    resizable: false
                }, 
                {
                    field: 'durable',
                    displayName: 'Durable',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 100,
                    resizable: false
                }
            ]
        };
        function setHardwareProfiles(hardwareProfiles) {
            $scope.row = findHardwareById(hardwareProfiles, $scope.hardwareId);
            $scope.processors = $scope.row["processors"];
            $scope.volumes = $scope.row["volumes"];
            Core.$apply($scope);
        }
        ;
        function updateTableContents() {
            var jolokia = workspace.jolokia;
            var computeMbean = Jclouds.getSelectionJcloudsComputeMBean(workspace, $scope.computeId);
            if (computeMbean) {
                setHardwareProfiles(jolokia.request({
                    type: 'exec',
                    mbean: computeMbean,
                    operation: 'listHardwareProfiles()'
                }).value);
            }
        }
        function findHardwareById(hardwareProfiles, id) {
            return hardwareProfiles.find(function (hardware) {
                return hardware.id === id;
            });
        }
    }
    Jclouds.HardwareController = HardwareController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function ImageListController($scope, $location, workspace, jolokia, $routeParams) {
        $scope.computeId = $routeParams.computeId;
        $scope.result = {};
        $scope.images = [];
        $scope.operatingSystemFamily = "";
        $scope.operatingSystemFamilies = [];
        var os = $location.search()['os'];
        if (os) {
            $scope.operatingSystemFamily = os;
        }
        $scope.selectedImages = [];
        $scope.imageTable = {
            data: 'images',
            showFilter: false,
            showColumnMenu: false,
            filterOptions: {
                useExternalFilter: true
            },
            selectedItems: $scope.selectedImages,
            rowHeight: 32,
            selectWithCheckboxOnly: true,
            columnDefs: [
                {
                    field: 'id',
                    displayName: 'Id',
                    cellTemplate: '<div class="ngCellText"><a href="#/jclouds/compute/image/{{computeId}}/{{row.getProperty(col.field)}}{{hash}}">{{row.getProperty(col.field)}}</a></div>',
                    width: 200,
                    resizable: false
                }, 
                {
                    field: 'name',
                    displayName: 'Name',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 200,
                    resizable: false
                }, 
                {
                    field: 'operatingSystem.family',
                    displayName: 'Operating System',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 200
                }, 
                {
                    field: 'operatingSystem.is64Bit',
                    displayName: '64 bit',
                    cellTemplate: '<div class="ngCellText pagination-centered"><i class="icon1point5x {{is64BitIcon(row.getProperty(col.field))}}"></i></div>',
                    width: 200
                }, 
                {
                    field: 'status',
                    displayName: 'Status',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 300
                }
            ]
        };
        Core.register(jolokia, $scope, {
            type: 'exec',
            mbean: Jclouds.getSelectionJcloudsComputeMBean(workspace, $scope.computeId),
            operation: 'listImages()'
        }, onSuccess(render));
        function render(response) {
            if (!Object.equal($scope.result, response.value)) {
                $scope.result = response.value;
                $scope.images = $scope.result;
                $scope.operatingSystemFamilies = extractOperatingSystemFamilies($scope.images);
                Core.$apply($scope);
            }
        }
        function extractOperatingSystemFamilies(images) {
            var operatingSystemFamilies = [];
            operatingSystemFamilies.push("");
            angular.forEach(images, function (image) {
                var operatingSystemFamily = image["operatingSystem"]["family"];
                operatingSystemFamilies.push(operatingSystemFamily);
            });
            return operatingSystemFamilies.unique();
        }
        $scope.is64BitIcon = function (is64bit) {
            if (is64bit) {
                return 'icon-thumbs-up';
            } else {
                return 'icon-thumbs-down';
            }
        };
    }
    Jclouds.ImageListController = ImageListController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function ImageController($scope, $filter, workspace, $routeParams) {
        $scope.computeId = $routeParams.computeId;
        $scope.imageId = $routeParams.imageId;
        updateTableContents();
        function setImage(api) {
            $scope.row = api;
            Core.$apply($scope);
        }
        ;
        function updateTableContents() {
            var jolokia = workspace.jolokia;
            var computeMbean = Jclouds.getSelectionJcloudsComputeMBean(workspace, $scope.computeId);
            if (computeMbean) {
                setImage(jolokia.request({
                    type: 'exec',
                    mbean: computeMbean,
                    operation: 'getImage(java.lang.String)',
                    arguments: [
                        $scope.imageId
                    ]
                }).value);
            }
        }
    }
    Jclouds.ImageController = ImageController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function ComputeLocationListController($scope, $location, workspace, jolokia, $routeParams) {
        $scope.computeId = $routeParams.computeId;
        $scope.result = {};
        $scope.locations = [];
        $scope.selectedLocations = [];
        $scope.locationTable = {
            plugins: [],
            data: 'locations',
            showFilter: false,
            showColumnMenu: false,
            filterOptions: {
                useExternalFilter: true
            },
            selectedItems: $scope.selectedLocations,
            rowHeight: 32,
            selectWithCheckboxOnly: true,
            columnDefs: [
                {
                    field: 'id',
                    displayName: 'Id',
                    cellTemplate: '<div class="ngCellText"><a href="#/jclouds/compute/location/{{computeId}}/{{row.getProperty(col.field)}}{{hash}}">{{row.getProperty(col.field)}}</a></div>',
                    width: 200,
                    resizable: false
                }, 
                {
                    field: 'description',
                    displayName: 'Description',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 200,
                    resizable: false
                }
            ]
        };
        Core.register(jolokia, $scope, {
            type: 'exec',
            mbean: Jclouds.getSelectionJcloudsComputeMBean(workspace, $scope.computeId),
            operation: 'listAssignableLocations()'
        }, onSuccess(render));
        function render(response) {
            if (!Object.equal($scope.result, response.value)) {
                $scope.result = response.value;
                $scope.locations = $scope.result;
                Core.$apply($scope);
            }
        }
    }
    Jclouds.ComputeLocationListController = ComputeLocationListController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function ComputeLocationController($scope, $filter, workspace, $routeParams) {
        $scope.computeId = $routeParams.computeId;
        $scope.locationId = $routeParams.locationId;
        updateTableContents();
        function setLocationProfiles(locationProfiles) {
            $scope.row = findLocationById(locationProfiles, $scope.locationId);
            Core.$apply($scope);
        }
        ;
        function updateTableContents() {
            var jolokia = workspace.jolokia;
            var computeMbean = Jclouds.getSelectionJcloudsComputeMBean(workspace, $scope.computeId);
            if (computeMbean) {
                setLocationProfiles(jolokia.request({
                    type: 'exec',
                    mbean: computeMbean,
                    operation: 'listAssignableLocations()'
                }).value);
            }
        }
        function findLocationById(locationProfiles, id) {
            return locationProfiles.find(function (location) {
                return location.id === id;
            });
        }
    }
    Jclouds.ComputeLocationController = ComputeLocationController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function NodeListController($scope, $location, workspace, jolokia, $routeParams) {
        $scope.computeId = $routeParams.computeId;
        $scope.result = {};
        $scope.nodes = [];
        $scope.group = "";
        $scope.groups = [];
        $scope.location = "";
        $scope.locations = [];
        var grp = $location.search()['group'];
        if (grp) {
            $scope.group = grp;
        }
        var loc = $location.search()['location'];
        if (loc) {
            $scope.location = loc;
        }
        $scope.selectedNodes = [];
        $scope.nodeTable = {
            data: 'nodes',
            showFilter: false,
            showColumnMenu: false,
            filterOptions: {
                useExternalFilter: true
            },
            selectedItems: $scope.selectedNodes,
            rowHeight: 32,
            selectWithCheckboxOnly: true,
            columnDefs: [
                {
                    field: 'id',
                    displayName: 'Id',
                    cellTemplate: '<div class="ngCellText"><a href="#/jclouds/compute/node/{{computeId}}/{{row.getProperty(col.field)}}{{hash}}">{{row.getProperty(col.field)}}</a></div>',
                    width: 200,
                    resizable: false
                }, 
                {
                    field: 'group',
                    displayName: 'Group',
                    cellTemplate: '<div class="ngCellText"><a href="#/jclouds/compute/node/{{row.getProperty(col.field)}}{{hash}}">{{row.getProperty(col.field)}}</a></div>',
                    width: 200,
                    resizable: false
                }, 
                {
                    field: 'operatingSystem.family',
                    displayName: 'Operating System',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 200
                }, 
                {
                    field: 'locationId',
                    displayName: 'Location',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 200
                }, 
                {
                    field: 'hostname',
                    displayName: 'Host Name',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 300
                }
            ]
        };
        Core.register(jolokia, $scope, {
            type: 'exec',
            mbean: Jclouds.getSelectionJcloudsComputeMBean(workspace, $scope.computeId),
            operation: 'listNodes()'
        }, onSuccess(render));
        function render(response) {
            if (!Object.equal($scope.result, response.value)) {
                $scope.result = response.value;
                $scope.nodes = $scope.result;
                $scope.locations = extractLocations($scope.nodes);
                $scope.groups = extractGroups($scope.nodes);
                Core.$apply($scope);
            }
        }
        function extractGroups(nodes) {
            var groups = [];
            groups.push("");
            angular.forEach(nodes, function (node) {
                var group = node["group"];
                groups.push(group);
            });
            return groups.unique();
        }
        function extractLocations(nodes) {
            var locations = [];
            locations.push("");
            angular.forEach(nodes, function (node) {
                var location = node["locationId"];
                locations.push(location);
            });
            return locations.unique();
        }
        $scope.resume = function () {
            $scope.selectedNodes.forEach(function (node) {
                Jclouds.resumeNode(workspace, jolokia, $scope.computeId, node.id, function () {
                    console.log("Resumed!");
                }, function () {
                    console.log("Failed to resume!");
                });
            });
        };
        $scope.suspend = function () {
            $scope.selectedNodes.forEach(function (node) {
                Jclouds.suspendNode(workspace, jolokia, $scope.computeId, node.id, function () {
                    console.log("Suspended!");
                }, function () {
                    console.log("Failed to suspend!");
                });
            });
        };
        $scope.reboot = function () {
            $scope.selectedNodes.forEach(function (node) {
                Jclouds.rebootNode(workspace, jolokia, $scope.computeId, node.id, function () {
                    console.log("Rebooted!");
                }, function () {
                    console.log("Failed to reboot!");
                });
            });
        };
        $scope.destroy = function () {
            $scope.selectedNodes.forEach(function (node) {
                Jclouds.destroyNode(workspace, jolokia, $scope.computeId, node.id, function () {
                    console.log("Destroyed!");
                }, function () {
                    console.log("Failed to destroy!");
                });
            });
        };
    }
    Jclouds.NodeListController = NodeListController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function NodeController($scope, $filter, workspace, $routeParams) {
        $scope.computeId = $routeParams.computeId;
        $scope.nodeId = $routeParams.nodeId;
        updateTableContents();
        function setNode(api) {
            $scope.row = api;
            Core.$apply($scope);
        }
        ;
        function updateTableContents() {
            var computeMbean = Jclouds.getSelectionJcloudsComputeMBean(workspace, $scope.computeId);
            var jolokia = workspace.jolokia;
            if (computeMbean) {
                setNode(jolokia.request({
                    type: 'exec',
                    mbean: computeMbean,
                    operation: 'getNode(java.lang.String)',
                    arguments: [
                        $scope.nodeId
                    ]
                }).value);
            }
        }
        $scope.resume = function () {
            Jclouds.resumeNode(workspace, workspace.jolokia, $scope.computeId, $scope.nodeId, function () {
                console.log("Resumed!");
            }, function () {
                console.log("Failed to resume!");
            });
        };
        $scope.suspend = function () {
            Jclouds.suspendNode(workspace, workspace.jolokia, $scope.computeId, $scope.nodeId, function () {
                console.log("Suspended!");
            }, function () {
                console.log("Failed to suspend!");
            });
        };
        $scope.reboot = function () {
            Jclouds.rebootNode(workspace, workspace.jolokia, $scope.computeId, $scope.nodeId, function () {
                console.log("Rebooted!");
            }, function () {
                console.log("Failed to reboot!");
            });
        };
        $scope.destroy = function () {
            Jclouds.destroyNode(workspace, workspace.jolokia, $scope.computeId, $scope.nodeId, function () {
                console.log("Destroyed!");
            }, function () {
                console.log("Failed to destroy!");
            });
        };
    }
    Jclouds.NodeController = NodeController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    Array.prototype.unique = function () {
        var a = [], l = this.length;
        for(var i = 0; i < l; i++) {
            for(var j = i + 1; j < l; j++) {
                if (this[i] === this[j]) {
                    j = ++i;
                }
            }
            a.push(this[i]);
        }
        return a;
    };
    function setSelect(selection, group) {
        if (!angular.isDefined(selection)) {
            return group[0];
        }
        var answer = group.findIndex(function (item) {
            return item === selection;
        });
        if (answer !== -1) {
            return group[answer];
        } else {
            return group[0];
        }
    }
    Jclouds.setSelect = setSelect;
    function findContextByName(workspace, name) {
        var jcloudsMBean = getSelectionJcloudsMBean(workspace);
        var response = workspace.jolokia.request({
            type: 'read',
            mbean: jcloudsMBean
        });
        return response.value["Contexts"].find(function (context) {
            return context.name === name;
        });
    }
    Jclouds.findContextByName = findContextByName;
    function populateTypeForApis(apis) {
        angular.forEach(apis, function (api) {
            populateTypeForApi(api);
        });
    }
    Jclouds.populateTypeForApis = populateTypeForApis;
    function populateTypeForApi(api) {
        var views = api["views"];
        var found = false;
        angular.forEach(views, function (view) {
            if (!found) {
                if (view.has("blob")) {
                    api["type"] = "blobstore";
                    found = true;
                } else if (view.has("compute")) {
                    api["type"] = "compute";
                    found = true;
                }
            }
        });
    }
    Jclouds.populateTypeForApi = populateTypeForApi;
    function filterImages(images, operatingSystemFamily) {
        if (operatingSystemFamily === "") {
            return images;
        } else {
            return images.findAll(function (image) {
                return image["operatingSystem"]["family"] === operatingSystemFamily;
            });
        }
    }
    Jclouds.filterImages = filterImages;
    function filterNodes(nodes, group, location) {
        var filteredNodes = [];
        if (group === "") {
            filteredNodes = nodes;
        } else {
            filteredNodes = nodes.findAll(function (node) {
                return node.group === group;
            });
        }
        if (location === "") {
            return filteredNodes;
        } else {
            return filteredNodes.findAll(function (node) {
                return node.locationId === location;
            });
        }
    }
    Jclouds.filterNodes = filterNodes;
    function resumeNode(workspace, jolokia, compute, id, success, error) {
        jolokia.request({
            type: 'exec',
            mbean: getSelectionJcloudsComputeMBean(workspace, compute),
            operation: 'resumeNode(java.lang.String)',
            arguments: [
                id
            ]
        }, onSuccess(success, {
            error: error
        }));
    }
    Jclouds.resumeNode = resumeNode;
    function suspendNode(workspace, jolokia, compute, id, success, error) {
        jolokia.request({
            type: 'exec',
            mbean: getSelectionJcloudsComputeMBean(workspace, compute),
            operation: 'suspendNode(java.lang.String)',
            arguments: [
                id
            ]
        }, onSuccess(success, {
            error: error
        }));
    }
    Jclouds.suspendNode = suspendNode;
    function rebootNode(workspace, jolokia, compute, id, success, error) {
        jolokia.request({
            type: 'exec',
            mbean: getSelectionJcloudsComputeMBean(workspace, compute),
            operation: 'rebootNode(java.lang.String)',
            arguments: [
                id
            ]
        }, onSuccess(success, {
            error: error
        }));
    }
    Jclouds.rebootNode = rebootNode;
    function destroyNode(workspace, jolokia, compute, id, success, error) {
        jolokia.request({
            type: 'exec',
            mbean: getSelectionJcloudsComputeMBean(workspace, compute),
            operation: 'destroyNode(java.lang.String)',
            arguments: [
                id
            ]
        }, onSuccess(success, {
            error: error
        }));
    }
    Jclouds.destroyNode = destroyNode;
    function apisOfType(apis, type) {
        if (type === "") {
            return apis;
        }
        return apis.findAll(function (api) {
            return api.type === type;
        });
    }
    Jclouds.apisOfType = apisOfType;
    function populateTypeForProviders(providers) {
        angular.forEach(providers, function (provider) {
            populateTypeForProvider(provider);
        });
    }
    Jclouds.populateTypeForProviders = populateTypeForProviders;
    function populateTypeForProvider(provider) {
        var views = provider["api"]["views"];
        var found = false;
        angular.forEach(views, function (view) {
            if (!found) {
                if (view.has("blob")) {
                    provider["type"] = "blobstore";
                    found = true;
                } else if (view.has("compute")) {
                    provider["type"] = "compute";
                    found = true;
                }
            }
        });
    }
    Jclouds.populateTypeForProvider = populateTypeForProvider;
    function providersOfType(providers, type) {
        if (type === "") {
            return providers;
        }
        return providers.findAll(function (provider) {
            return provider.type === type;
        });
    }
    Jclouds.providersOfType = providersOfType;
    function findFirstObjectName(node) {
        if (node) {
            var answer = node.objectName;
            if (answer) {
                return answer;
            } else {
                var children = node.children;
                if (children && children.length) {
                    return findFirstObjectName(children[0]);
                }
            }
        }
        return null;
    }
    Jclouds.findFirstObjectName = findFirstObjectName;
    function childsOfType(node) {
        var types = [];
        angular.forEach(node.children, function (child) {
            types.push(child.title);
        });
        return types;
    }
    Jclouds.childsOfType = childsOfType;
    function listJcloudsMBeanNameOfType(workspace, type) {
        if (workspace) {
            var folder = workspace.tree.navigate("org.jclouds", type);
            return childsOfType(folder);
        }
        return null;
    }
    Jclouds.listJcloudsMBeanNameOfType = listJcloudsMBeanNameOfType;
    function getSelectionJcloudsMBean(workspace) {
        if (workspace) {
            var folder = workspace.tree.navigate("org.jclouds", "management", "core");
            return findFirstObjectName(folder);
        }
        return null;
    }
    Jclouds.getSelectionJcloudsMBean = getSelectionJcloudsMBean;
    function getSelectionJcloudsComputeMBean(workspace, name) {
        if (workspace) {
            var folder = workspace.tree.navigate("org.jclouds", "compute", name);
            return findFirstObjectName(folder);
        }
        return null;
    }
    Jclouds.getSelectionJcloudsComputeMBean = getSelectionJcloudsComputeMBean;
    function getSelectionJcloudsBlobstoreMBean(workspace, name) {
        if (workspace) {
            var folder = workspace.tree.navigate("org.jclouds", "blobstore", name);
            return findFirstObjectName(folder);
        }
        return null;
    }
    Jclouds.getSelectionJcloudsBlobstoreMBean = getSelectionJcloudsBlobstoreMBean;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    var pluginName = 'jclouds';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'ngGrid', 
        'hawtioCore'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/jclouds/api', {
            templateUrl: 'app/jclouds/html/api-list.html'
        }).when('/jclouds/api/:apiId', {
            templateUrl: 'app/jclouds/html/api.html'
        }).when('/jclouds/provider', {
            templateUrl: 'app/jclouds/html/provider-list.html'
        }).when('/jclouds/provider/:providerId', {
            templateUrl: 'app/jclouds/html/provider.html'
        }).when('/jclouds/compute/service', {
            templateUrl: 'app/jclouds/html/compute/compute-service-list.html'
        }).when('/jclouds/compute/service/:computeId', {
            templateUrl: 'app/jclouds/html/compute/compute-service.html'
        }).when('/jclouds/compute/node/:computeId', {
            templateUrl: 'app/jclouds/html/compute/node-list.html'
        }).when('/jclouds/compute/node/:computeId/*nodeId', {
            templateUrl: 'app/jclouds/html/compute/node.html'
        }).when('/jclouds/compute/image/:computeId', {
            templateUrl: 'app/jclouds/html/compute/image-list.html'
        }).when('/jclouds/compute/image/:computeId/*imageId', {
            templateUrl: 'app/jclouds/html/compute/image.html'
        }).when('/jclouds/compute/hardware/:computeId', {
            templateUrl: 'app/jclouds/html/compute/hardware-list.html'
        }).when('/jclouds/compute/hardware/:computeId/*hardwareId', {
            templateUrl: 'app/jclouds/html/compute/hardware.html'
        }).when('/jclouds/compute/location/:computeId', {
            templateUrl: 'app/jclouds/html/compute/location-list.html'
        }).when('/jclouds/compute/location/:computeId/*locationId', {
            templateUrl: 'app/jclouds/html/compute/location.html'
        }).when('/jclouds/blobstore/service', {
            templateUrl: 'app/jclouds/html/blobstore/blobstore-service-list.html'
        }).when('/jclouds/blobstore/service/:blobstoreId', {
            templateUrl: 'app/jclouds/html/blobstore/blobstore-service.html'
        }).when('/jclouds/blobstore/location/:blobstoreId', {
            templateUrl: 'app/jclouds/html/blobstore/location-list.html'
        }).when('/jclouds/blobstore/location/:blobstoreId/*locationId', {
            templateUrl: 'app/jclouds/html/blobstore/location.html'
        }).when('/jclouds/blobstore/container/:blobstoreId', {
            templateUrl: 'app/jclouds/html/blobstore/container-list.html'
        }).when('/jclouds/blobstore/container/:blobstoreId/:containerId', {
            templateUrl: 'app/jclouds/html/blobstore/container.html'
        }).when('/jclouds/blobstore/container/:blobstoreId/:containerId/*directory', {
            templateUrl: 'app/jclouds/html/blobstore/container.html'
        });
    }).run(function (workspace, viewRegistry, helpRegistry) {
        viewRegistry['jclouds'] = "app/jclouds/html/layoutJclouds.html";
        helpRegistry.addUserDoc('jclouds', 'app/' + 'jclouds' + '/doc/help.md', function () {
            return workspace.treeContainsDomainAndProperties("org.jclouds");
        });
        workspace.topLevelTabs.push({
            content: "jclouds",
            title: "Visualise and manage the Jclouds Compute/BlobStore providers and apis",
            isValid: function (workspace) {
                return workspace.treeContainsDomainAndProperties("org.jclouds");
            },
            href: function () {
                return "#/jclouds/api";
            },
            isActive: function (workspace) {
                return workspace.isLinkActive("jclouds");
            }
        });
    });
    hawtioPluginLoader.addModule(pluginName);
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function ProviderListController($scope, $location, workspace, jolokia) {
        $scope.result = {};
        $scope.providers = [];
        $scope.type = "";
        $scope.types = [
            "", 
            "blobstore", 
            "compute", 
            "loadbalancer"
        ];
        var key = $location.search()['type'];
        if (key) {
            $scope.type = key;
        }
        $scope.selectedProviders = [];
        $scope.providerTable = {
            data: 'providers',
            showFilter: false,
            showColumnMenu: false,
            filterOptions: {
                useExternalFilter: true
            },
            selectedItems: $scope.selectedProviders,
            rowHeight: 32,
            selectWithCheckboxOnly: true,
            columnDefs: [
                {
                    field: 'id',
                    displayName: 'Id',
                    cellTemplate: '<div class="ngCellText"><a href="#/jclouds/provider/{{row.getProperty(col.field)}}{{hash}}">{{row.getProperty(col.field)}}</a></div>',
                    width: 200,
                    resizable: false
                }, 
                {
                    field: 'name',
                    displayName: 'Name',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 350
                }, 
                {
                    field: 'type',
                    displayName: 'Type',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 100
                }
            ]
        };
        Core.register(jolokia, $scope, {
            type: 'read',
            mbean: Jclouds.getSelectionJcloudsMBean(workspace)
        }, onSuccess(render));
        function render(response) {
            if (!Object.equal($scope.result, response.value)) {
                $scope.result = response.value;
                $scope.providers = $scope.result["Providers"];
                Jclouds.populateTypeForProviders($scope.providers);
                Core.$apply($scope);
            }
        }
    }
    Jclouds.ProviderListController = ProviderListController;
})(Jclouds || (Jclouds = {}));
var Jclouds;
(function (Jclouds) {
    function ProviderController($scope, $filter, workspace, $routeParams) {
        $scope.providerId = $routeParams.providerId;
        updateTableContents();
        function setProvider(provider) {
            Jclouds.populateTypeForProvider(provider);
            $scope.row = provider;
            Core.$apply($scope);
        }
        ;
        function updateTableContents() {
            var jcloudsCoreMbean = Jclouds.getSelectionJcloudsMBean(workspace);
            var jolokia = workspace.jolokia;
            if (jcloudsCoreMbean) {
                setProvider(jolokia.request({
                    type: 'exec',
                    mbean: Jclouds.getSelectionJcloudsMBean(workspace),
                    operation: 'findProviderById(java.lang.String)',
                    arguments: [
                        $scope.providerId
                    ]
                }).value);
            }
        }
    }
    Jclouds.ProviderController = ProviderController;
})(Jclouds || (Jclouds = {}));
var Jetty;
(function (Jetty) {
    function ConnectorsController($scope, $location, workspace, jolokia) {
        var stateTemplate = '<div class="ngCellText pagination-centered" title="{{row.getProperty(col.field)}}"><i class="{{row.getProperty(col.field) | jettyIconClass}}"></i></div>';
        $scope.connectors = [];
        $scope.selected = [];
        var columnDefs = [
            {
                field: 'running',
                displayName: 'State',
                cellTemplate: stateTemplate,
                width: 56,
                minWidth: 56,
                maxWidth: 56,
                resizable: false
            }, 
            {
                field: 'port',
                displayName: 'Port',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'protocols',
                displayName: 'Protocols',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'default',
                displayName: 'Default',
                cellFilter: null,
                width: "*",
                resizable: true
            }
        ];
        $scope.gridOptions = {
            data: 'connectors',
            displayFooter: true,
            selectedItems: $scope.selected,
            columnDefs: columnDefs,
            filterOptions: {
                filterText: ''
            },
            title: "Connectors"
        };
        $scope.controlConnectors = function (op) {
            var mbeanNames = $scope.selected.map(function (b) {
                return b.mbean;
            });
            if (!angular.isArray(mbeanNames)) {
                mbeanNames = [
                    mbeanNames
                ];
            }
            var lastIndex = (mbeanNames.length || 1) - 1;
            angular.forEach(mbeanNames, function (mbean, idx) {
                var onResponse = (idx >= lastIndex) ? $scope.onLastResponse : $scope.onResponse;
                jolokia.request({
                    type: 'exec',
                    mbean: mbean,
                    operation: op,
                    arguments: null
                }, onSuccess(onResponse, {
                    error: onResponse
                }));
            });
        };
        $scope.stop = function () {
            $scope.controlConnectors('stop');
        };
        $scope.start = function () {
            $scope.controlConnectors('start');
        };
        $scope.anySelectionIsRunning = function () {
            var selected = $scope.selected || [];
            return selected.length && selected.any(function (s) {
                return s.running;
            });
        };
        $scope.everySelectionIsRunning = function (state) {
            var selected = $scope.selected || [];
            return selected.length && selected.every(function (s) {
                return s.running;
            });
        };
        function render78(response) {
            $scope.connectors = [];
            $scope.selected.length = 0;
            function onAttributes(response) {
                var obj = response.value;
                if (obj) {
                    obj.mbean = response.request.mbean;
                    obj.protocols = "[http]";
                    obj.default = "http";
                    obj.port = obj.port;
                    obj.running = obj['running'] !== undefined ? obj['running'] : true;
                    $scope.connectors.push(obj);
                    if (obj.confidentialPort) {
                        var copyObj = {
                            protocols: "[https]",
                            default: "https",
                            port: obj.confidentialPort,
                            running: obj.running,
                            mbean: obj.mbean
                        };
                        $scope.connectors.push(copyObj);
                    }
                    Core.$apply($scope);
                }
            }
            angular.forEach(response, function (value, key) {
                var mbean = value;
                jolokia.request({
                    type: "read",
                    mbean: mbean,
                    attribute: []
                }, onSuccess(onAttributes));
            });
            Core.$apply($scope);
        }
        ;
        function render9(response) {
            $scope.connectors = [];
            $scope.selected.length = 0;
            function onAttributes(response) {
                var obj = response.value;
                if (obj) {
                    obj.mbean = response.request.mbean;
                    obj.protocols = obj['protocols'];
                    obj.default = obj['defaultProtocol'];
                    obj.port = obj.port;
                    obj.running = obj['state'] == "STARTED";
                    $scope.connectors.push(obj);
                    Core.$apply($scope);
                }
            }
            angular.forEach(response, function (value, key) {
                var mbean = value;
                jolokia.request({
                    type: "read",
                    mbean: mbean,
                    attribute: []
                }, onSuccess(onAttributes));
            });
            Core.$apply($scope);
        }
        ;
        $scope.onLastResponse = function (response) {
            $scope.onResponse(response);
            loadData();
        };
        $scope.onResponse = function (response) {
        };
        $scope.$on('jmxTreeUpdated', reloadFunction);
        $scope.$watch('workspace.tree', reloadFunction);
        function reloadFunction() {
            setTimeout(loadData, 50);
        }
        function loadData() {
            console.log("Loading Jetty connector data...");
            var tree = workspace.tree;
            jolokia.search("org.eclipse.jetty.server.nio:type=selectchannelconnector,*", onSuccess(render78));
            jolokia.search("org.eclipse.jetty.server:type=serverconnector,*", onSuccess(render9));
        }
    }
    Jetty.ConnectorsController = ConnectorsController;
})(Jetty || (Jetty = {}));
var Jetty;
(function (Jetty) {
    function JettyController($scope, $location, workspace, jolokia) {
        var stateTemplate = '<div class="ngCellText pagination-centered" title="{{row.getProperty(col.field)}}"><i class="{{row.getProperty(col.field) | jettyIconClass}}"></i></div>';
        $scope.uninstallDialog = new Core.Dialog();
        $scope.webapps = [];
        $scope.selected = [];
        var columnDefs = [
            {
                field: 'state',
                displayName: 'State',
                cellTemplate: stateTemplate,
                width: 56,
                minWidth: 56,
                maxWidth: 56,
                resizable: false
            }, 
            {
                field: 'displayName',
                displayName: 'Name',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'contextPath',
                displayName: 'Context-Path',
                cellFilter: null,
                width: "*",
                resizable: true
            }
        ];
        $scope.gridOptions = {
            data: 'webapps',
            displayFooter: true,
            selectedItems: $scope.selected,
            columnDefs: columnDefs,
            filterOptions: {
                filterText: ''
            },
            title: "Web applications"
        };
        $scope.controlWebApps = function (op) {
            var mbeanNames = $scope.selected.map(function (b) {
                return b.mbean;
            });
            if (!angular.isArray(mbeanNames)) {
                mbeanNames = [
                    mbeanNames
                ];
            }
            var lastIndex = (mbeanNames.length || 1) - 1;
            angular.forEach(mbeanNames, function (mbean, idx) {
                var onResponse = (idx >= lastIndex) ? $scope.onLastResponse : $scope.onResponse;
                jolokia.request({
                    type: 'exec',
                    mbean: mbean,
                    operation: op,
                    arguments: null
                }, onSuccess(onResponse, {
                    error: onResponse
                }));
            });
        };
        $scope.stop = function () {
            $scope.controlWebApps('stop');
        };
        $scope.start = function () {
            $scope.controlWebApps('start');
        };
        $scope.uninstall = function () {
            $scope.controlWebApps('destroy');
            $scope.uninstallDialog.close();
        };
        $scope.anySelectionHasState = function (state) {
            var selected = $scope.selected || [];
            return selected.length && selected.any(function (s) {
                return Jetty.isState(s, state);
            });
        };
        $scope.everySelectionHasState = function (state) {
            var selected = $scope.selected || [];
            return selected.length && selected.every(function (s) {
                return Jetty.isState(s, state);
            });
        };
        $scope.onLastResponse = function (response) {
            $scope.onResponse(response);
            loadData();
        };
        $scope.onResponse = function (response) {
        };
        $scope.$on('jmxTreeUpdated', reloadFunction);
        $scope.$watch('workspace.tree', reloadFunction);
        $scope.jettyServerVersion = "";
        $scope.jettyServerStartupTime = "";
        var servers = jolokia.search("org.eclipse.jetty.server:type=server,*");
        if (servers && servers.length === 1) {
            $scope.jettyServerVersion = jolokia.getAttribute(servers[0], "version");
            $scope.jettyServerStartupTime = jolokia.getAttribute(servers[0], "startupTime");
        } else {
            console.log("Cannot find jetty server or there was more than one server. response is: " + servers);
        }
        function reloadFunction() {
            setTimeout(loadData, 50);
        }
        function loadData() {
            console.log("Loading Jetty webapp data...");
            jolokia.search("org.mortbay.jetty.plugin:type=jettywebappcontext,*", onSuccess(render));
            jolokia.search("org.eclipse.jetty.webapp:type=webappcontext,*", onSuccess(render));
            jolokia.search("org.eclipse.jetty.servlet:type=servletcontexthandler,*", onSuccess(render));
        }
        function render(response) {
            $scope.webapps = [];
            $scope.mbeanIndex = {};
            $scope.selected.length = 0;
            function onAttributes(response) {
                var obj = response.value;
                if (obj) {
                    obj.mbean = response.request.mbean;
                    if (!obj.state) {
                        obj.state = obj['running'] === undefined || obj['running'] ? "started" : "stopped";
                    }
                    var mbean = obj.mbean;
                    if (mbean) {
                        var idx = $scope.mbeanIndex[mbean];
                        if (angular.isDefined(idx)) {
                            $scope.webapps[mbean] = obj;
                        } else {
                            $scope.mbeanIndex[mbean] = $scope.webapps.length;
                            $scope.webapps.push(obj);
                        }
                        Core.$apply($scope);
                    }
                }
            }
            angular.forEach(response, function (value, key) {
                var mbean = value;
                jolokia.request({
                    type: "read",
                    mbean: mbean,
                    attribute: []
                }, onSuccess(onAttributes));
            });
            Core.$apply($scope);
        }
    }
    Jetty.JettyController = JettyController;
})(Jetty || (Jetty = {}));
var Jetty;
(function (Jetty) {
    function iconClass(state) {
        if (state) {
            switch(state.toString().toLowerCase()) {
                case 'started':
                    return "green icon-play-circle";
                case 'true':
                    return "green icon-play-circle";
            }
        }
        return "orange icon-off";
    }
    Jetty.iconClass = iconClass;
    function isState(item, state) {
        var value = (item.state || "").toLowerCase();
        if (angular.isArray(state)) {
            return state.any(function (stateText) {
                return value.startsWith(stateText);
            });
        } else {
            return value.startsWith(state);
        }
    }
    Jetty.isState = isState;
})(Jetty || (Jetty = {}));
var Jetty;
(function (Jetty) {
    var pluginName = 'jetty';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'ui.bootstrap.dialog', 
        'hawtioCore'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/jetty/server', {
            templateUrl: 'app/jetty/html/server.html'
        }).when('/jetty/applications', {
            templateUrl: 'app/jetty/html/applications.html'
        }).when('/jetty/connectors', {
            templateUrl: 'app/jetty/html/connectors.html'
        }).when('/jetty/mbeans', {
            templateUrl: 'app/jetty/html/mbeans.html'
        });
    }).filter('jettyIconClass', function () {
        return Jetty.iconClass;
    }).run(function ($location, workspace, viewRegistry, helpRegistry) {
        viewRegistry['jetty'] = "app/jetty/html/layoutJettyTabs.html";
        viewRegistry['jettyTree'] = "app/jetty/html/layoutJettyTree.html";
        helpRegistry.addUserDoc('jetty', 'app/jetty/doc/help.md', function () {
            return workspace.treeContainsDomainAndProperties("org.eclipse.jetty.server");
        });
        workspace.topLevelTabs.push({
            content: "Jetty",
            title: "Manage your Jetty container",
            isValid: function (workspace) {
                return workspace.treeContainsDomainAndProperties("org.eclipse.jetty.server");
            },
            href: function () {
                return "#/jetty/applications";
            },
            isActive: function (workspace) {
                return workspace.isTopTabActive("jetty");
            }
        });
    });
    hawtioPluginLoader.addModule(pluginName);
})(Jetty || (Jetty = {}));
var Jetty;
(function (Jetty) {
    function TreeController($scope, $location, workspace) {
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateSelectionFromURL, 50);
        });
        $scope.$watch('workspace.tree', function () {
            console.log("workspace tree has changed, lets reload!!");
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            var children = [];
            var tree = workspace.tree;
            if (tree) {
                var nodes = tree.children;
                angular.forEach(nodes, function (node) {
                    var nodeChildren = node.children;
                    if (node.title.startsWith("org.eclipse.jetty") && nodeChildren) {
                        children = children.concat(nodeChildren);
                    }
                });
            }
            var treeElement = $("#jettyTree");
            Jmx.enableTree($scope, $location, workspace, treeElement, children, true);
            setTimeout(updateSelectionFromURL, 50);
        });
        function updateSelectionFromURL() {
            Jmx.updateTreeSelectionFromURL($location, $("#jettyTree"), true);
        }
    }
    Jetty.TreeController = TreeController;
})(Jetty || (Jetty = {}));
var Jmx;
(function (Jmx) {
    function AreaChartController($scope, $routeParams, jolokia, $templateCache, localStorage, $element) {
        $scope.mbean = $routeParams['mbean'];
        $scope.attribute = $routeParams['attribute'];
        $scope.duration = localStorage['updateRate'];
        $scope.width = 308;
        $scope.height = 296;
        $scope.template = "";
        $scope.entries = [];
        $scope.data = {
            entries: $scope.entries
        };
        $scope.req = [
            {
                type: 'read',
                mbean: $scope.mbean,
                attribute: $scope.attribute
            }
        ];
        $scope.render = function (response) {
            $scope.entries.push({
                time: response.timestamp,
                count: response.value
            });
            $scope.entries = $scope.entries.last(15);
            if ($scope.template === "") {
                $scope.template = $templateCache.get("areaChart");
            }
            $scope.data = {
                _type: "date_histogram",
                entries: $scope.entries
            };
            Core.$apply($scope);
        };
        Core.register(jolokia, $scope, $scope.req, onSuccess($scope.render));
    }
    Jmx.AreaChartController = AreaChartController;
})(Jmx || (Jmx = {}));
var Jmx;
(function (Jmx) {
    function AttributeController($scope, jolokia) {
        $scope.init = function (mbean, attribute) {
            $scope.mbean = mbean;
            $scope.attribute = attribute;
            if (angular.isDefined($scope.mbean) && angular.isDefined($scope.attribute)) {
                Core.register(jolokia, $scope, {
                    type: 'read',
                    mbean: $scope.mbean,
                    attribute: $scope.attribute
                }, onSuccess(render));
            }
        };
        function render(response) {
            if (!Object.equal($scope.data, response.value)) {
                $scope.data = safeNull(response.value);
                Core.$apply($scope);
            }
        }
    }
    Jmx.AttributeController = AttributeController;
    function AttributeChartController($scope, jolokia, $document) {
        $scope.init = function (mbean, attribute) {
            $scope.mbean = mbean;
            $scope.attribute = attribute;
            if (angular.isDefined($scope.mbean) && angular.isDefined($scope.attribute)) {
                Core.register(jolokia, $scope, {
                    type: 'read',
                    mbean: $scope.mbean,
                    attribute: $scope.attribute
                }, onSuccess(render));
            }
        };
        function render(response) {
            if (!angular.isDefined($scope.chart)) {
                $scope.chart = $($document.find("#" + $scope.attribute)[0]);
                if ($scope.chart) {
                    $scope.width = $scope.chart.width();
                }
            }
            if (!angular.isDefined($scope.context)) {
                console.log("Got: ", response);
                $scope.context = cubism.context().serverDelay(0).clientDelay(0).step(1000).size($scope.width);
                $scope.jcontext = $scope.context.jolokia(jolokia);
                $scope.metrics = [];
                Object.extended(response.value).keys(function (key, value) {
                    $scope.metrics.push($scope.jcontext.metric({
                        type: 'read',
                        mbean: $scope.mbean,
                        attribute: $scope.attribute,
                        path: key
                    }, $scope.attribute));
                });
                d3.select("#" + $scope.attribute).call(function (div) {
                    div.append("div").data($scope.metrics).call($scope.context.horizon());
                });
                Core.unregister(jolokia, $scope);
                Core.$apply($scope);
            }
        }
    }
    Jmx.AttributeChartController = AttributeChartController;
})(Jmx || (Jmx = {}));
var Jmx;
(function (Jmx) {
    Jmx.propertiesColumnDefs = [
        {
            field: 'name',
            displayName: 'Property',
            width: "27%",
            cellTemplate: '<div class="ngCellText" title="{{row.entity.name}}" data-placement="bottom"><div ng-show="!inDashboard" class="inline" compile="getDashboardWidgets(row.entity)"></div>{{row.entity.name}}</div>'
        }, 
        {
            field: 'value',
            displayName: 'Value',
            width: "70%",
            cellTemplate: '<div class="ngCellText" ng-click="openDetailView(row.entity)" ng-bind-html-unsafe="row.entity.summary"></div>'
        }
    ];
    Jmx.foldersColumnDefs = [
        {
            displayName: 'Name',
            cellTemplate: '<div class="ngCellText"><a href="{{folderHref(row)}}"><i class="{{folderIconClass(row)}}"></i> {{row.getProperty("title")}}</a></div>'
        }
    ];
    function AttributesController($scope, $location, workspace, jolokia, jmxWidgets, jmxWidgetTypes) {
        $scope.searchText = '';
        $scope.columnDefs = [];
        $scope.selectedItems = [];
        $scope.selectCheckBox = true;
        $scope.valueDetails = new Core.Dialog();
        $scope.gridOptions = {
            selectedItems: $scope.selectedItems,
            showFilter: false,
            canSelectRows: false,
            showColumnMenu: true,
            displaySelectionCheckbox: false,
            filterOptions: {
                filterText: ''
            },
            data: 'gridData',
            columnDefs: 'columnDefs'
        };
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateTableContents, 50);
        });
        $scope.$watch('workspace.selection', function () {
            if (workspace.moveIfViewInvalid()) {
                Core.unregister(jolokia, $scope);
                return;
            }
            updateTableContents();
        });
        $scope.hasWidget = function (row) {
            console.log("Row: ", row);
            return true;
        };
        $scope.getDashboardWidgets = function (row) {
            var mbean = workspace.getSelectedMBeanName();
            if (!mbean) {
                return '';
            }
            var potentialCandidates = jmxWidgets.filter(function (widget) {
                return mbean === widget.mbean;
            });
            if (potentialCandidates.isEmpty()) {
                return '';
            }
            potentialCandidates = potentialCandidates.filter(function (widget) {
                return widget.attribute === row.key || widget.total === row.key;
            });
            if (potentialCandidates.isEmpty()) {
                return '';
            }
            var rc = [];
            potentialCandidates.forEach(function (widget) {
                var widgetType = Jmx.getWidgetType(widget);
                rc.push("<i class=\"" + widgetType.icon + " clickable\" title=\"" + widgetType.title + "\" ng-click=\"addChartToDashboard(row.entity, '" + widgetType.type + "')\"></i>");
            });
            return rc.join() + "&nbsp;";
        };
        $scope.addChartToDashboard = function (row, widgetType) {
            var mbean = workspace.getSelectedMBeanName();
            var candidates = jmxWidgets.filter(function (widget) {
                return mbean === widget.mbean;
            });
            candidates = candidates.filter(function (widget) {
                return widget.attribute === row.key || widget.total === row.key;
            });
            candidates = candidates.filter(function (widget) {
                return widget.type === widgetType;
            });
            var widget = candidates.first();
            var type = Jmx.getWidgetType(widget);
            $location.url(Jmx.createDashboardLink(type, widget));
        };
        $scope.toolBarTemplate = function () {
            var answer = Jmx.getAttributeToolBar(workspace.selection);
            return answer;
        };
        $scope.invokeSelectedMBeans = function (operationName, completeFunction) {
            if (typeof completeFunction === "undefined") { completeFunction = null; }
            var queries = [];
            angular.forEach($scope.selectedItems || [], function (item) {
                var mbean = item["_id"];
                if (mbean) {
                    var opName = operationName;
                    if (angular.isFunction(operationName)) {
                        opName = operationName(item);
                    }
                    queries.push({
                        type: "exec",
                        operation: opName,
                        mbean: mbean
                    });
                }
            });
            if (queries.length) {
                var callback = function () {
                    if (completeFunction) {
                        completeFunction();
                    } else {
                        operationComplete();
                    }
                };
                jolokia.request(queries, onSuccess(callback, {
                    error: callback
                }));
            }
        };
        $scope.folderHref = function (row) {
            var key = row.getProperty("key");
            if (key) {
                return Core.createHref($location, "#" + $location.path() + "?nid=" + key, [
                    "nid"
                ]);
            } else {
                return "";
            }
        };
        $scope.folderIconClass = function (row) {
            return row.getProperty("objectName") ? "icon-cog" : "icon-folder-close";
        };
        $scope.openDetailView = function (entity) {
            $scope.row = entity;
            if (entity.detailHtml) {
                $scope.valueDetails.open();
            }
        };
        function operationComplete() {
            updateTableContents();
        }
        function updateTableContents() {
            Core.unregister(jolokia, $scope);
            $scope.gridData = [];
            $scope.mbeanIndex = null;
            var mbean = workspace.getSelectedMBeanName();
            var request = null;
            var node = workspace.selection;
            if (mbean) {
                request = {
                    type: 'read',
                    mbean: mbean
                };
                if (node.key !== $scope.lastKey) {
                    $scope.columnDefs = Jmx.propertiesColumnDefs;
                }
            } else if (node) {
                if (node.key !== $scope.lastKey) {
                    $scope.columnDefs = [];
                }
                var children = node.children;
                if (children) {
                    var childNodes = children.map(function (child) {
                        return child.objectName;
                    });
                    var mbeans = childNodes.filter(function (mbean) {
                        return mbean;
                    });
                    if (mbeans) {
                        var typeNames = Jmx.getUniqueTypeNames(children);
                        if (typeNames.length <= 1) {
                            var query = mbeans.map(function (mbean) {
                                return {
                                    type: "READ",
                                    mbean: mbean,
                                    ignoreErrors: true
                                };
                            });
                            if (query.length > 0) {
                                request = query;
                                $scope.mbeanIndex = {};
                                $scope.mbeanRowCounter = 0;
                                $scope.mbeanCount = mbeans.length;
                            }
                        } else {
                            console.log("Too many type names " + typeNames);
                        }
                    }
                }
            }
            var callback = onSuccess(render);
            if (request) {
                $scope.request = request;
                Core.register(jolokia, $scope, request, callback);
            } else if (node) {
                if (node.key !== $scope.lastKey) {
                    $scope.columnDefs = Jmx.foldersColumnDefs;
                }
                $scope.gridData = node.children;
            }
            if (node) {
                $scope.lastKey = node.key;
            }
        }
        function render(response) {
            var data = response.value;
            var mbeanIndex = $scope.mbeanIndex;
            var mbean = response.request['mbean'];
            Jmx.log.debug("mbean: ", mbean);
            if (mbean) {
                data["_id"] = mbean;
            }
            if (mbeanIndex) {
                if (mbean) {
                    var idx = mbeanIndex[mbean];
                    if (!angular.isDefined(idx)) {
                        idx = $scope.mbeanRowCounter;
                        mbeanIndex[mbean] = idx;
                        $scope.mbeanRowCounter += 1;
                    }
                    if (idx === 0) {
                        $scope.selectedIndices = $scope.selectedItems.map(function (item) {
                            return $scope.gridData.indexOf(item);
                        });
                        $scope.gridData = [];
                        if (!$scope.columnDefs.length) {
                            var key = workspace.selectionConfigKey();
                            var defaultDefs = workspace.attributeColumnDefs[key] || [];
                            var defaultSize = defaultDefs.length;
                            var map = {};
                            angular.forEach(defaultDefs, function (value, key) {
                                var field = value.field;
                                if (field) {
                                    map[field] = value;
                                }
                            });
                            angular.forEach(data, function (value, key) {
                                if (includePropertyValue(key, value)) {
                                    if (!map[key]) {
                                        defaultDefs.push({
                                            field: key,
                                            displayName: humanizeValue(key),
                                            visible: defaultSize === 0
                                        });
                                    }
                                }
                            });
                            $scope.columnDefs = defaultDefs;
                        }
                    }
                    $scope.gridData[idx] = data;
                    var count = $scope.mbeanCount;
                    if (!count || idx + 1 >= count) {
                        var newSelections = $scope.selectedIndices.map(function (idx) {
                            return $scope.gridData[idx];
                        }).filter(function (row) {
                            return row;
                        });
                        $scope.selectedItems.splice(0, $scope.selectedItems.length);
                        $scope.selectedItems.push.apply($scope.selectedItems, newSelections);
                        Core.$apply($scope);
                    }
                } else {
                    console.log("No mbean name in request " + JSON.stringify(response.request));
                }
            } else {
                $scope.columnDefs = Jmx.propertiesColumnDefs;
                var showAllAttributes = true;
                if (angular.isObject(data)) {
                    var properties = [];
                    angular.forEach(data, function (value, key) {
                        if (showAllAttributes || includePropertyValue(key, value)) {
                            if (!key.startsWith("_")) {
                                if (key === "ObjectName") {
                                    value = unwrapObjectName(value);
                                }
                                if (angular.isArray(value)) {
                                    value = value.map(function (v) {
                                        return unwrapObjectName(v);
                                    });
                                }
                                var data = {
                                    key: key,
                                    name: humanizeValue(key),
                                    value: safeNull(value)
                                };
                                generateSummaryAndDetail(data);
                                properties.push(data);
                            }
                        }
                    });
                    if (!properties.any(function (p) {
                        return p['key'] === 'ObjectName';
                    })) {
                        var objectName = {
                            key: "ObjectName",
                            name: "Object Name",
                            value: mbean
                        };
                        generateSummaryAndDetail(objectName);
                        properties.push(objectName);
                    }
                    properties = properties.sortBy("name");
                    $scope.selectedItems = [
                        data
                    ];
                    data = properties;
                }
                $scope.gridData = data;
                Core.$apply($scope);
            }
        }
        function unwrapObjectName(value) {
            if (!angular.isObject(value)) {
                return value;
            }
            var keys = Object.keys(value);
            if (keys.length === 1 && keys[0] === "objectName") {
                return value["objectName"];
            }
            return value;
        }
        function generateSummaryAndDetail(data) {
            var value = data.value;
            if (!angular.isArray(value) && angular.isObject(value)) {
                var detailHtml = "<table class='table table-striped'>";
                var summary = "";
                var object = value;
                var keys = Object.keys(value).sort();
                angular.forEach(keys, function (key) {
                    var value = object[key];
                    detailHtml += "<tr><td>" + humanizeValue(key) + "</td><td>" + value + "</td></tr>";
                    summary += "" + humanizeValue(key) + ": " + value + "  ";
                });
                detailHtml += "</table>";
                data.summary = summary;
                data.detailHtml = detailHtml;
            } else {
                var text = value;
                data.summary = "" + text + "";
                data.detailHtml = "<pre>" + text + "</pre>";
                if (angular.isArray(value)) {
                    var html = "<ul>";
                    angular.forEach(value, function (item) {
                        html += "<li>" + item + "</li>";
                    });
                    html += "</ul>";
                    data.detailHtml = html;
                }
            }
        }
        function includePropertyValue(key, value) {
            return !angular.isObject(value);
        }
    }
    Jmx.AttributesController = AttributesController;
})(Jmx || (Jmx = {}));
var Jmx;
(function (Jmx) {
    function AttributesOldController($scope, $routeParams, workspace, $rootScope) {
        $scope.routeParams = $routeParams;
        $scope.workspace = workspace;
        $scope.isTable = function (value) {
            return value instanceof Table;
        };
        $scope.getAttributes = function (value) {
            if (angular.isArray(value) && angular.isObject(value[0])) {
                return value;
            }
            if (angular.isObject(value) && !angular.isArray(value)) {
                return [
                    value
                ];
            }
            return null;
        };
        $scope.rowValues = function (row, col) {
            return [
                row[col]
            ];
        };
        var asQuery = function (mbeanName) {
            return {
                type: "READ",
                mbean: mbeanName,
                ignoreErrors: true
            };
        };
        var tidyAttributes = function (attributes) {
            var objectName = attributes['ObjectName'];
            if (objectName) {
                var name = objectName['objectName'];
                if (name) {
                    attributes['ObjectName'] = name;
                }
            }
        };
        $scope.$watch('workspace.selection', function () {
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            var node = $scope.workspace.selection;
            closeHandle($scope, $scope.workspace.jolokia);
            var mbean = null;
            if (node) {
                mbean = node.objectName;
            }
            var query = null;
            var jolokia = workspace.jolokia;
            var updateValues = function (response) {
                var attributes = response.value;
                if (attributes) {
                    tidyAttributes(attributes);
                    $scope.attributes = attributes;
                    Core.$apply($scope);
                } else {
                    console.log("Failed to get a response! " + response);
                }
            };
            if (mbean) {
                query = asQuery(mbean);
            } else if (node) {
                var children = node.children;
                if (children) {
                    var childNodes = children.map(function (child) {
                        return child.objectName;
                    });
                    var mbeans = childNodes.filter(function (mbean) {
                        return mbean;
                    });
                    var typeNames = Jmx.getUniqueTypeNames(children);
                    if (mbeans && typeNames.length <= 1) {
                        query = mbeans.map(function (mbean) {
                            return asQuery(mbean);
                        });
                        if (query.length === 1) {
                            query = query[0];
                        } else if (query.length === 0) {
                            query = null;
                        } else {
                            $scope.attributes = new Table();
                            updateValues = function (response) {
                                var attributes = response.value;
                                if (attributes) {
                                    tidyAttributes(attributes);
                                    var mbean = attributes['ObjectName'];
                                    var request = response.request;
                                    if (!mbean && request) {
                                        mbean = request['mbean'];
                                    }
                                    if (mbean) {
                                        var table = $scope.attributes;
                                        if (!($scope.isTable(table))) {
                                            table = new Table();
                                            $scope.attributes = table;
                                        }
                                        table.setRow(mbean, attributes);
                                        Core.$apply($scope);
                                    } else {
                                        console.log("no ObjectName in attributes " + Object.keys(attributes));
                                    }
                                } else {
                                    console.log("Failed to get a response! " + JSON.stringify(response));
                                }
                            };
                        }
                    }
                }
            }
            if (query) {
                jolokia.request(query, onSuccess(updateValues));
                var callback = onSuccess(updateValues, {
                    error: function (response) {
                        updateValues(response);
                    }
                });
                if (angular.isArray(query)) {
                    if (query.length >= 1) {
                        var args = [
                            callback
                        ].concat(query);
                        var fn = jolokia.register;
                        scopeStoreJolokiaHandle($scope, jolokia, fn.apply(jolokia, args));
                    }
                } else {
                    scopeStoreJolokiaHandle($scope, jolokia, jolokia.register(callback, query));
                }
            }
        });
    }
    Jmx.AttributesOldController = AttributesOldController;
})(Jmx || (Jmx = {}));
var Table = (function () {
    function Table() {
        this.columns = {};
        this.rows = {};
    }
    Table.prototype.values = function (row, columns) {
        var answer = [];
        if (columns) {
            for(name in columns) {
                answer.push(row[name]);
            }
        }
        return answer;
    };
    Table.prototype.setRow = function (key, data) {
        var _this = this;
        this.rows[key] = data;
        Object.keys(data).forEach(function (key) {
            var columns = _this.columns;
            if (!columns[key]) {
                columns[key] = {
                    name: key
                };
            }
        });
    };
    return Table;
})();
var Jmx;
(function (Jmx) {
    function ChartEditController($scope, $location, workspace, jolokia) {
        $scope.selectedAttributes = [];
        $scope.selectedMBeans = [];
        $scope.metrics = {};
        $scope.mbeans = {};
        $scope.size = function (value) {
            if (angular.isObject(value)) {
                return Object.size(value);
            } else if (angular.isArray(value)) {
                return value.length;
            } else {
                return 1;
            }
        };
        $scope.canViewChart = function () {
            return $scope.selectedAttributes.length && $scope.selectedMBeans.length && $scope.size($scope.mbeans) > 0 && $scope.size($scope.metrics) > 0;
        };
        $scope.showAttributes = function () {
            return $scope.canViewChart() && $scope.size($scope.metrics) > 1;
        };
        $scope.showElements = function () {
            return $scope.canViewChart() && $scope.size($scope.mbeans) > 1;
        };
        $scope.viewChart = function () {
            var search = $location.search();
            if ($scope.selectedAttributes.length === $scope.size($scope.metrics)) {
                delete search["att"];
            } else {
                search["att"] = $scope.selectedAttributes;
            }
            if ($scope.selectedMBeans.length === $scope.size($scope.mbeans) && $scope.size($scope.mbeans) === 1) {
                delete search["el"];
            } else {
                search["el"] = $scope.selectedMBeans;
            }
            $location.search(search);
            $location.path("jmx/charts");
        };
        $scope.$watch('workspace.selection', render);
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(render, 50);
        });
        function render() {
            var node = workspace.selection;
            if (!angular.isDefined(node)) {
                return;
            }
            $scope.selectedAttributes = [];
            $scope.selectedMBeans = [];
            $scope.metrics = {};
            $scope.mbeans = {};
            var mbeanCounter = 0;
            var resultCounter = 0;
            var children = node.children;
            if (!children || !children.length || node.objectName) {
                children = [
                    node
                ];
            }
            if (children) {
                children.forEach(function (mbeanNode) {
                    var mbean = mbeanNode.objectName;
                    var name = mbeanNode.title;
                    if (name && mbean) {
                        mbeanCounter++;
                        $scope.mbeans[name] = name;
                        var listKey = escapeMBeanPath(mbean);
                        jolokia.list(listKey, onSuccess(function (meta) {
                            var attributes = meta.attr;
                            if (attributes) {
                                for(var key in attributes) {
                                    var value = attributes[key];
                                    if (value) {
                                        var typeName = value['type'];
                                        if (isNumberTypeName(typeName)) {
                                            if (!$scope.metrics[key]) {
                                                $scope.metrics[key] = key;
                                            }
                                        }
                                    }
                                }
                                if (++resultCounter >= mbeanCounter) {
                                    var search = $location.search();
                                    var attributeNames = toSearchArgumentArray(search["att"]);
                                    var elementNames = toSearchArgumentArray(search["el"]);
                                    if (attributeNames && attributeNames.length) {
                                        attributeNames.forEach(function (name) {
                                            if ($scope.metrics[name]) {
                                                $scope.selectedAttributes.push(name);
                                            }
                                        });
                                    }
                                    if (elementNames && elementNames.length) {
                                        elementNames.forEach(function (name) {
                                            if ($scope.mbeans[name]) {
                                                $scope.selectedMBeans.push(name);
                                            }
                                        });
                                    }
                                    if ($scope.selectedMBeans.length < 1) {
                                        $scope.selectedMBeans = Object.keys($scope.mbeans);
                                    }
                                    if ($scope.selectedAttributes.length < 1) {
                                        var attrKeys = Object.keys($scope.metrics).sort();
                                        if ($scope.selectedMBeans.length > 1) {
                                            $scope.selectedAttributes = [
                                                attrKeys.first()
                                            ];
                                        } else {
                                            $scope.selectedAttributes = attrKeys;
                                        }
                                    }
                                    $("#attributes").attr("size", Object.size($scope.metrics));
                                    $("#mbeans").attr("size", Object.size($scope.mbeans));
                                    Core.$apply($scope);
                                }
                            }
                        }));
                    }
                });
            }
        }
    }
    Jmx.ChartEditController = ChartEditController;
})(Jmx || (Jmx = {}));
var Jmx;
(function (Jmx) {
    function ChartController($scope, $element, $location, workspace, localStorage, jolokiaUrl, jolokiaParams) {
        $scope.metrics = [];
        $scope.updateRate = 1000;
        var jolokia = new Jolokia(jolokiaParams);
        jolokia.start($scope.updateRate);
        var watchRouteChange = false;
        $scope.$on('$destroy', function () {
            jolokia.stop();
            delete jolokia;
            if (watchRouteChange) {
                $scope.deregRouteChange();
            }
            $scope.dereg();
            if ($scope.context) {
                $scope.context.stop();
                $scope.context = null;
            }
            $($element).children().remove();
        });
        $scope.errorMessage = function () {
            if ($scope.updateRate === 0) {
                return "updateRate";
            }
            if ($scope.metrics.length === 0) {
                return "metrics";
            }
        };
        if (watchRouteChange) {
            $scope.deregRouteChange = $scope.$on("$routeChangeSuccess", function (event, current, previous) {
                setTimeout(render, 50);
            });
        }
        $scope.dereg = $scope.$watch('workspace.selection', function () {
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            render();
        });
        function render() {
            var node = workspace.selection;
            if (!angular.isDefined(node) || !angular.isDefined($scope.updateRate) || $scope.updateRate === 0) {
                return;
            }
            var width = 594;
            var charts = $($element);
            if (charts) {
                width = charts.width();
            } else {
                return;
            }
            var mbean = node.objectName;
            $scope.metrics = [];
            var context = cubism.context().serverDelay($scope.updateRate).clientDelay($scope.updateRate).step($scope.updateRate).size(width);
            $scope.context = context;
            $scope.jolokiaContext = context.jolokia(jolokia);
            var search = $location.search();
            var attributeNames = toSearchArgumentArray(search["att"]);
            if (mbean) {
                var listKey = encodeMBeanPath(mbean);
                var meta = jolokia.list(listKey);
                if (meta) {
                    var attributes = meta.attr;
                    if (attributes) {
                        var foundNames = [];
                        for(var key in attributes) {
                            var value = attributes[key];
                            if (value) {
                                var typeName = value['type'];
                                if (isNumberTypeName(typeName)) {
                                    foundNames.push(key);
                                }
                            }
                        }
                        if (attributeNames.length) {
                            var filtered = foundNames.filter(function (key) {
                                return attributeNames.indexOf(key) >= 0;
                            });
                            if (filtered.length) {
                                foundNames = filtered;
                            }
                        }
                        angular.forEach(foundNames, function (key) {
                            var metric = $scope.jolokiaContext.metric({
                                type: 'read',
                                mbean: mbean,
                                attribute: key
                            }, humanizeValue(key));
                            if (metric) {
                                $scope.metrics.push(metric);
                            }
                        });
                    }
                }
            } else {
                var elementNames = toSearchArgumentArray(search["el"]);
                if (attributeNames && attributeNames.length && elementNames && elementNames.length) {
                    var mbeans = {};
                    elementNames.forEach(function (elementName) {
                        var child = node.get(elementName);
                        if (!child && node.children) {
                            child = node.children.find(function (n) {
                                return elementName === n["title"];
                            });
                        }
                        if (child) {
                            var mbean = child.objectName;
                            if (mbean) {
                                mbeans[elementName] = mbean;
                            }
                        }
                    });
                    attributeNames.forEach(function (key) {
                        angular.forEach(mbeans, function (mbean, name) {
                            var attributeTitle = humanizeValue(key);
                            var title = name + ": " + attributeTitle;
                            var metric = $scope.jolokiaContext.metric({
                                type: 'read',
                                mbean: mbean,
                                attribute: key
                            }, title);
                            if (metric) {
                                $scope.metrics.push(metric);
                            }
                        });
                    });
                }
                if (node.children.length && !$scope.metrics.length) {
                    $location.path("jmx/chartEdit");
                }
            }
            var d3Selection = d3.select($element[0]);
            if ($scope.metrics.length > 0) {
                d3Selection.selectAll(".axis").data([
                    "top", 
                    "bottom"
                ]).enter().append("div").attr("class", function (d) {
                    return d + " axis";
                }).each(function (d) {
                    d3.select(this).call(context.axis().ticks(12).orient(d));
                });
                d3Selection.append("div").attr("class", "rule").call(context.rule());
                context.on("focus", function (i) {
                    d3Selection.selectAll(".value").style("right", i === null ? null : context.size() - i + "px");
                });
                $scope.metrics.forEach(function (metric) {
                    d3Selection.call(function (div) {
                        div.append("div").data([
                            metric
                        ]).attr("class", "horizon").call(context.horizon());
                    });
                });
            }
        }
        ;
    }
    Jmx.ChartController = ChartController;
})(Jmx || (Jmx = {}));
var Jmx;
(function (Jmx) {
    function DonutChartController($scope, $routeParams, jolokia, $templateCache) {
        $scope.mbean = $routeParams['mbean'];
        $scope.total = $routeParams['total'];
        $scope.attribute = $routeParams['attribute'];
        $scope.terms = $routeParams['terms'];
        $scope.remainder = $routeParams['remaining'];
        $scope.template = "";
        $scope.termsArray = $scope.terms.split(",");
        $scope.data = {
            total: 0,
            terms: []
        };
        if (!$scope.attribute) {
            $scope.reqs = [
                {
                    type: 'read',
                    mbean: $scope.mbean,
                    attribute: $scope.total
                }
            ];
            $scope.termsArray.forEach(function (term) {
                $scope.reqs.push({
                    type: 'read',
                    mbean: $scope.mbean,
                    attribute: term
                });
                $scope.data.terms.push({
                    term: term,
                    count: 0
                });
            });
        } else {
            var terms = $scope.termsArray.include($scope.total);
            $scope.reqs = [
                {
                    type: 'read',
                    mbean: $scope.mbean,
                    attribute: $scope.attribute,
                    paths: terms.join(",")
                }
            ];
            $scope.termsArray.forEach(function (term) {
                $scope.data.terms.push({
                    term: term,
                    count: 0
                });
            });
        }
        if ($scope.remainder && $scope.remainder !== "-") {
            $scope.data.terms.push({
                term: $scope.remainder,
                count: 0
            });
        }
        $scope.render = function (response) {
            var freeTerm = null;
            if ($scope.remainder && $scope.remainder !== "-") {
                freeTerm = $scope.data.terms.find(function (term) {
                    return term.term === $scope.remainder;
                });
            }
            if (!$scope.attribute) {
                if (response.request.attribute === $scope.total) {
                    $scope.data.total = response.value;
                } else {
                    var term = $scope.data.terms.find(function (term) {
                        return term.term === response.request.attribute;
                    });
                    if (term) {
                        term.count = response.value;
                    }
                    if (freeTerm) {
                        freeTerm.count = $scope.data.total;
                        $scope.data.terms.forEach(function (term) {
                            if (term.term !== $scope.remainder) {
                                freeTerm.count = freeTerm.count - term.count;
                            }
                        });
                    }
                }
            } else {
                if (response.request.attribute === $scope.attribute) {
                    $scope.data.total = response.value[$scope.total.toLowerCase()];
                    $scope.data.terms.forEach(function (term) {
                        if (term.term !== $scope.remainder) {
                            term.count = response.value[term.term.toLowerCase()];
                        }
                    });
                    if (freeTerm) {
                        freeTerm.count = $scope.data.total;
                        $scope.data.terms.forEach(function (term) {
                            if (term.term !== $scope.remainder) {
                                freeTerm.count = freeTerm.count - term.count;
                            }
                        });
                    }
                }
            }
            if ($scope.template === "") {
                $scope.template = $templateCache.get("donut");
            }
            $scope.data = Object.clone($scope.data);
            Core.$apply($scope);
        };
        Core.register(jolokia, $scope, $scope.reqs, onSuccess($scope.render));
    }
    Jmx.DonutChartController = DonutChartController;
})(Jmx || (Jmx = {}));
var Jmx;
(function (Jmx) {
    var pluginName = 'jmx';
    Jmx.currentProcessId = '';
    angular.module(pluginName, [
        'bootstrap', 
        'ui.bootstrap', 
        'ui.bootstrap.modal', 
        'ngResource', 
        'ngGrid', 
        'hawtioCore', 
        'hawtio-ui'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/jmx/attributes', {
            templateUrl: 'app/jmx/html/attributes.html'
        }).when('/jmx/operations', {
            templateUrl: 'app/jmx/html/operations.html'
        }).when('/jmx/charts', {
            templateUrl: 'app/jmx/html/charts.html'
        }).when('/jmx/chartEdit', {
            templateUrl: 'app/jmx/html/chartEdit.html'
        }).when('/jmx/help/:tabName', {
            templateUrl: 'app/core/html/help.html'
        }).when('/jmx/widget/donut', {
            templateUrl: 'app/jmx/html/donutChart.html'
        }).when('/jmx/widget/area', {
            templateUrl: 'app/jmx/html/areaChart.html'
        });
    }).factory('jmxTreeLazyLoadRegistry', function () {
        return Jmx.lazyLoaders;
    }).factory('jmxWidgetTypes', function () {
        return Jmx.jmxWidgetTypes;
    }).factory('jmxWidgets', function () {
        return Jmx.jmxWidgets;
    }).run(function ($location, workspace, viewRegistry, layoutTree, jolokia, pageTitle, helpRegistry) {
        viewRegistry['jmx'] = layoutTree;
        helpRegistry.addUserDoc('jmx', 'app/jmx/doc/help.md');
        pageTitle.addTitleElement(function () {
            if (Jmx.currentProcessId === '') {
                try  {
                    Jmx.currentProcessId = jolokia.getAttribute('java.lang:type=Runtime', 'Name');
                } catch (e) {
                }
                if (Jmx.currentProcessId && Jmx.currentProcessId.has("@")) {
                    Jmx.currentProcessId = "pid:" + Jmx.currentProcessId.split("@")[0];
                }
            }
            return Jmx.currentProcessId;
        });
        workspace.topLevelTabs.push({
            id: "jmx",
            content: "JMX",
            title: "View the JMX MBeans in this process",
            isValid: function (workspace) {
                return true;
            },
            href: function () {
                return "#/jmx/attributes";
            },
            isActive: function (workspace) {
                return workspace.isTopTabActive("jmx");
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-list"></i> Attributes',
            title: "View the attribute values on your selection",
            isValid: function (workspace) {
                return true;
            },
            href: function () {
                return "#/jmx/attributes";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-leaf"></i> Operations',
            title: "Execute operations on your selection",
            isValid: function (workspace) {
                return true;
            },
            href: function () {
                return "#/jmx/operations";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-bar-chart"></i> Chart',
            title: "View a chart of the metrics on your selection",
            isValid: function (workspace) {
                return true;
            },
            href: function () {
                return "#/jmx/charts";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-cog"></i> Edit Chart',
            title: "Edit the chart configuration",
            isValid: function (workspace) {
                return workspace.isLinkActive("jmx/chart");
            },
            href: function () {
                return "#/jmx/chartEdit";
            }
        });
    });
    hawtioPluginLoader.addModule(pluginName);
})(Jmx || (Jmx = {}));
var Jmx;
(function (Jmx) {
    function MBeansController($scope, $location, workspace) {
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateSelectionFromURL, 50);
        });
        $scope.select = function (node) {
            $scope.workspace.updateSelectionNode(node);
            Core.$apply($scope);
        };
        function updateSelectionFromURL() {
            Jmx.updateTreeSelectionFromURL($location, $("#jmxtree"));
        }
        $scope.populateTree = function () {
            var treeElement = $("#jmxtree");
            $scope.tree = workspace.tree;
            Jmx.enableTree($scope, $location, workspace, treeElement, $scope.tree.children, true);
            setTimeout(updateSelectionFromURL, 50);
        };
        $scope.$on('jmxTreeUpdated', $scope.populateTree);
        $scope.populateTree();
    }
    Jmx.MBeansController = MBeansController;
})(Jmx || (Jmx = {}));
var Jmx;
(function (Jmx) {
    function OperationController($scope, workspace, jolokia, $document) {
        $scope.title = $scope.item.humanReadable;
        $scope.desc = $scope.item.desc;
        $scope.operationResult = '';
        $scope.executeIcon = "icon-ok";
        $scope.mode = "text";
        var sanitize = function (args) {
            if (args) {
                args.forEach(function (arg) {
                    switch(arg.type) {
                        case "int":
                        case "long":
                            arg.formType = "number";
                            break;
                        default:
                            arg.formType = "text";
                    }
                });
            }
            return args;
        };
        $scope.args = sanitize($scope.item.args);
        $scope.dump = function (data) {
            console.log(data);
        };
        $scope.ok = function () {
            $scope.operationResult = '';
        };
        $scope.reset = function () {
            if ($scope.item.args) {
                $scope.item.args.forEach(function (arg) {
                    arg.value = "";
                });
            }
            $scope.ok();
        };
        $scope.handleResponse = function (response) {
            $scope.executeIcon = "icon-ok";
            $scope.operationStatus = "success";
            if (response === null || 'null' === response) {
                $scope.operationResult = "Operation Succeeded!";
            } else if (typeof response === 'string') {
                $scope.operationResult = response;
            } else {
                $scope.operationResult = angular.toJson(response, true);
            }
            $scope.mode = CodeEditor.detectTextFormat($scope.operationResult);
            Core.$apply($scope);
        };
        $scope.execute = function () {
            var node = workspace.selection;
            if (!node) {
                return;
            }
            var objectName = node.objectName;
            if (!objectName) {
                return;
            }
            var args = [
                objectName, 
                $scope.item.name
            ];
            if ($scope.item.args) {
                $scope.item.args.forEach(function (arg) {
                    args.push(arg.value);
                });
            }
            args.push(onSuccess($scope.handleResponse, {
                error: function (response) {
                    $scope.executeIcon = "icon-ok";
                    $scope.operationStatus = "error";
                    var error = response.error;
                    $scope.operationResult = error;
                    var stacktrace = response.stacktrace;
                    if (stacktrace) {
                        $scope.operationResult = stacktrace;
                    }
                    Core.$apply($scope);
                }
            }));
            $scope.executeIcon = "icon-spinner icon-spin";
            var fn = jolokia.execute;
            fn.apply(jolokia, args);
        };
    }
    Jmx.OperationController = OperationController;
    function OperationsController($scope, $routeParams, workspace, jolokia) {
        $scope.operations = {};
        $scope.methodFilter = '';
        var sanitize = function (value) {
            for(var item in value) {
                item = "" + item;
                value[item].name = item;
                value[item].humanReadable = humanizeValue(item);
            }
            return value;
        };
        var asQuery = function (node) {
            var path = escapeMBeanPath(node);
            var query = {
                type: "LIST",
                method: "post",
                path: path,
                ignoreErrors: true
            };
            return query;
        };
        $scope.isOperationsEmpty = function () {
            return $.isEmptyObject($scope.operations);
        };
        $scope.doFilter = function (item) {
            Jmx.log.debug("item: ", item);
            if (Core.isBlank($scope.methodFilter)) {
                return true;
            }
            if (item.name.toLowerCase().has($scope.methodFilter.toLowerCase()) || item.humanReadable.toLowerCase().has($scope.methodFilter.toLowerCase())) {
                return true;
            }
            return false;
        };
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(render, 50);
        });
        $scope.$watch('workspace.selection', function () {
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            render();
        });
        function render() {
            var node = workspace.selection;
            if (!node) {
                return;
            }
            var objectName = node.objectName;
            if (!objectName) {
                return;
            }
            var query = asQuery(objectName);
            var update_values = function (response) {
                var ops = response.value.op;
                var answer = {};
                var getArgs = function (args) {
                    return "(" + args.map(function (arg) {
                        return arg.type;
                    }).join() + ")";
                };
                angular.forEach(ops, function (value, key) {
                    if (angular.isArray(value)) {
                        angular.forEach(value, function (value, index) {
                            answer[key + getArgs(value.args)] = value;
                        });
                    } else {
                        answer[key + getArgs(value.args)] = value;
                    }
                });
                $scope.operations = sanitize(answer);
                Core.$apply($scope);
            };
            jolokia.request(query, onSuccess(update_values, {
                error: function (response) {
                    notification('error', 'Failed to query available operations: ' + response.error);
                }
            }));
        }
        render();
    }
    Jmx.OperationsController = OperationsController;
})(Jmx || (Jmx = {}));
var Jmx;
(function (Jmx) {
    function createDashboardLink(widgetType, widget) {
        var href = "#" + widgetType.route;
        var routeParams = angular.toJson(widget);
        var title = widget.title;
        var size = angular.toJson({
            size_x: widgetType.size_x,
            size_y: widgetType.size_y
        });
        return "/dashboard/add?tab=dashboard" + "&href=" + encodeURIComponent(href) + "&size=" + encodeURIComponent(size) + "&title=" + encodeURIComponent(title) + "&routeParams=" + encodeURIComponent(routeParams);
    }
    Jmx.createDashboardLink = createDashboardLink;
    function getWidgetType(widget) {
        return Jmx.jmxWidgetTypes.find(function (type) {
            return type.type === widget.type;
        });
    }
    Jmx.getWidgetType = getWidgetType;
    Jmx.jmxWidgetTypes = [
        {
            type: "donut",
            icon: "icon-smile",
            route: "/jmx/widget/donut",
            size_x: 2,
            size_y: 2,
            title: "Add Donut chart to Dashboard"
        }, 
        {
            type: "area",
            icon: "icon-bar-chart",
            route: "/jmx/widget/area",
            size_x: 4,
            size_y: 2,
            title: "Add Area chart to Dashboard"
        }
    ];
    Jmx.jmxWidgets = [
        {
            type: "donut",
            title: "Java Heap Memory",
            mbean: "java.lang:type=Memory",
            attribute: "HeapMemoryUsage",
            total: "Max",
            terms: "Used",
            remaining: "Free"
        }, 
        {
            type: "donut",
            title: "Java Non Heap Memory",
            mbean: "java.lang:type=Memory",
            attribute: "NonHeapMemoryUsage",
            total: "Max",
            terms: "Used",
            remaining: "Free"
        }, 
        {
            type: "donut",
            title: "File Descriptor Usage",
            mbean: "java.lang:type=OperatingSystem",
            total: "MaxFileDescriptorCount",
            terms: "OpenFileDescriptorCount",
            remaining: "Free"
        }, 
        {
            type: "donut",
            title: "Loaded Clases",
            mbean: "java.lang:type=ClassLoading",
            total: "TotalLoadedClassCount",
            terms: "LoadedClassCount,UnloadedClassCount",
            remaining: "-"
        }, 
        {
            type: "donut",
            title: "Swap Size",
            mbean: "java.lang:type=OperatingSystem",
            total: "TotalSwapSpaceSize",
            terms: "FreeSwapSpaceSize",
            remaining: "Used Swap"
        }, 
        {
            type: "area",
            title: "Process CPU Time",
            mbean: "java.lang:type=OperatingSystem",
            attribute: "ProcessCpuTime"
        }, 
        {
            type: "area",
            title: "Process CPU Load",
            mbean: "java.lang:type=OperatingSystem",
            attribute: "ProcessCpuLoad"
        }, 
        {
            type: "area",
            title: "System CPU Load",
            mbean: "java.lang:type=OperatingSystem",
            attribute: "SystemCpuLoad"
        }, 
        {
            type: "area",
            title: "System CPU Time",
            mbean: "java.lang:type=OperatingSystem",
            attribute: "SystemCpuTime"
        }
    ];
})(Jmx || (Jmx = {}));
var JUnit;
(function (JUnit) {
    JUnit.log = Logger.get("JUnit");
    function isJUnitPluginEnabled(workspace) {
        return getIntrospectorMBean(workspace) && getJUnitMBean(workspace);
    }
    JUnit.isJUnitPluginEnabled = isJUnitPluginEnabled;
    function getJUnitMBean(workspace) {
        return Core.getMBeanTypeObjectName(workspace, "hawtio", "JUnitFacade");
    }
    JUnit.getJUnitMBean = getJUnitMBean;
    function getIntrospectorMBean(workspace) {
        return Core.getMBeanTypeObjectName(workspace, "hawtio", "Introspector");
    }
    JUnit.getIntrospectorMBean = getIntrospectorMBean;
})(JUnit || (JUnit = {}));
var JUnit;
(function (JUnit) {
    var pluginName = 'junit';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'ngGrid', 
        'datatable', 
        'hawtioCore'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/junit/tests', {
            templateUrl: 'app/junit/html/tests.html',
            reloadOnSearch: false
        });
    }).factory('inProgressStatus', function () {
        return {
            jhandle: null,
            data: null,
            alertClass: "success"
        };
    }).run(function ($location, workspace, viewRegistry, layoutFull, helpRegistry) {
        viewRegistry['junit'] = 'app/junit/html/layoutJUnitTree.html';
        workspace.topLevelTabs.push({
            content: "JUnit",
            title: "View and run test cases in this process",
            isValid: function (workspace) {
                return JUnit.isJUnitPluginEnabled(workspace);
            },
            href: function () {
                return "#/junit/tests";
            }
        });
    });
    hawtioPluginLoader.addModule(pluginName);
})(JUnit || (JUnit = {}));
var JUnit;
(function (JUnit) {
    function TreeController($scope, $location, workspace, jolokia, inProgressStatus) {
        var log = Logger.get("JUnit");
        $scope.inProgressData = null;
        $scope.alertClass = "success";
        $scope.testClasses = [];
        $scope.testClassMap = {};
        $scope.gridOptions = {
            selectedItems: [],
            data: 'selectedTests',
            displayFooter: false,
            showFilter: false,
            filterOptions: {
                filterText: ''
            },
            showSelectionCheckbox: true,
            columnDefs: [
                {
                    field: 'id',
                    displayName: 'Test Class'
                }
            ]
        };
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateSelectionFromURL, 50);
        });
        $scope.$on('jmxTreeUpdated', function () {
            reloadTree();
        });
        $scope.runAllTests = function () {
            runTests($scope.testClasses);
        };
        $scope.runTests = function () {
            var tests = ($scope.gridOptions.selectedItems || []).map(function (o) {
                return o.id;
            });
            runTests(tests);
        };
        $scope.runTest = function (className) {
            if (className) {
                runTests([
                    className
                ]);
            }
        };
        $scope.clearResults = function () {
            $scope.testResults = null;
            inProgressStatus.data = null;
            inProgressStatus.alertClass = "success";
        };
        function updateSelectionFromURL() {
            Jmx.updateTreeSelectionFromURL($location, $("#junittree"), true);
        }
        reloadTree();
        function selectionChanged(data) {
            var selectionKey = data ? data.key : null;
            log.debug("Selection is now: " + selectionKey);
            var selectedTests = $scope.testClasses;
            $scope.selectionKey = selectionKey;
            if (selectionKey) {
                selectedTests = $scope.testClassMap[selectionKey] || [
                    selectionKey
                ];
            }
            $scope.selectedTests = selectedTests.map(function (t) {
                return {
                    id: t
                };
            });
            Core.$apply($scope);
        }
        function reloadTree() {
            var mbean = JUnit.getIntrospectorMBean(workspace);
            var domain = "org.unit";
            var rootFolder = new Folder("Test Cases");
            rootFolder.addClass = "testCases";
            rootFolder.typeName = "testCases";
            rootFolder.domain = domain;
            rootFolder.key = "";
            var children = [
                rootFolder
            ];
            if (mbean) {
                function render(results) {
                    $scope.testClasses = results;
                    $scope.testClassMap = {};
                    angular.forEach(results, function (className) {
                        var paths = className.split(".");
                        var last = paths.length - 1;
                        var folder = rootFolder;
                        var prefix = "";
                        for(var i = 0; i < last; i++) {
                            var path = paths[i];
                            if (prefix) {
                                prefix += ".";
                            }
                            prefix += path;
                            var list = $scope.testClassMap[prefix];
                            if (!list) {
                                list = [];
                                $scope.testClassMap[prefix] = list;
                            }
                            list.push(className);
                            folder = workspace.folderGetOrElse(folder, path);
                            folder.key = prefix;
                        }
                        var lastPath = paths[last];
                        var testClass = new Folder(lastPath);
                        testClass.addClass = "testClass";
                        testClass.domain = domain;
                        testClass.key = className;
                        folder.children.push(testClass);
                    });
                    Core.$apply($scope);
                    var treeElement = $("#junittree");
                    Jmx.enableTree($scope, $location, workspace, treeElement, children, true, function (selectedNode) {
                        var data = selectedNode.data;
                        selectionChanged(data);
                        Core.$apply($scope);
                    });
                    setTimeout(updateSelectionFromURL, 50);
                }
                jolokia.execute(mbean, "findJUnitTestClassNames", onSuccess(render));
            }
        }
        $scope.runningTests = function () {
            if (inProgressStatus.data !== null && inProgressStatus.data.running) {
                $scope.inProgressData = inProgressStatus.data;
                $scope.alertClass = inProgressStatus.alertClass;
                return true;
            } else {
                return false;
            }
        };
        function renderResults(results) {
            $scope.testResults = results;
            $scope.running = false;
            var alertClass = "error";
            if (results.successful) {
                alertClass = "success";
            } else if (!results.runCount) {
                alertClass = "warning";
            }
            $scope.alertClass = alertClass;
            Core.$apply($scope);
        }
        var renderInProgress = function (response) {
            var result = response.value;
            if (result) {
                log.info("Render inProgress: " + result);
                inProgressStatus.data = result;
                $scope.inProgressData = inProgressStatus.data;
                var alertClass = "success";
                if (result.failureCount > 0) {
                    alertClass = "error";
                }
                inProgressStatus.alertClass = alertClass;
                $scope.alertClass = inProgressStatus.alertClass;
                if (!result.running && inProgressStatus.jhandle !== null) {
                    log.info("Unit test done, unreigster jolokia handle");
                    jolokia.unregister(inProgressStatus.jhandle);
                    inProgressStatus.jhandle = null;
                }
                Core.$apply($scope);
            }
        };
        function runTests(listOfClassNames) {
            $scope.running = true;
            $scope.testResults = null;
            var mbean = JUnit.getJUnitMBean(workspace);
            if (mbean && listOfClassNames && listOfClassNames.length) {
                if (inProgressStatus.jhandle === null) {
                    log.info("Registering jolokia handle");
                    inProgressStatus.jhandle = jolokia.register(renderInProgress, {
                        type: 'exec',
                        mbean: mbean,
                        operation: 'inProgress()',
                        ignoreErrors: true,
                        arguments: []
                    });
                    jolokia.execute(mbean, "runTestClasses", listOfClassNames, onSuccess(renderResults));
                }
            }
        }
    }
    JUnit.TreeController = TreeController;
})(JUnit || (JUnit = {}));
var JVM;
(function (JVM) {
    function ConnectController($scope, $location, localStorage, workspace) {
        var log = Logger.get("JVM");
        JVM.configureScope($scope, $location, workspace);
        $scope.useProxy = true;
        var key = "jvmConnect";
        var config = {};
        var configJson = localStorage[key];
        if (configJson) {
            try  {
                config = JSON.parse(configJson);
            } catch (e) {
            }
        }
        $scope.host = config["host"] || "localhost";
        $scope.path = config["path"] || "jolokia";
        $scope.port = config["port"] || 8181;
        $scope.userName = config["userName"];
        $scope.password = config["password"];
        angular.forEach([
            "userName", 
            "password", 
            "port", 
            "path", 
            "host"
        ], function (name) {
            $scope.$watch(name, function () {
                var value = $scope[name];
                if (value) {
                    config[name] = value;
                    localStorage[key] = JSON.stringify(config);
                }
            });
        });
        $scope.gotoServer = function () {
            var options = new Core.ConnectToServerOptions();
            var host = $scope.host || 'localhost';
            var idx = host.indexOf("://");
            if (idx >= 0) {
                host = host.substring(idx + 3);
            }
            idx = host.indexOf("/");
            if (idx >= 0) {
                host = host.substring(0, idx);
            }
            log.info("using host name: " + host + " and user: " + $scope.userName + " and password: " + ($scope.password ? "********" : $scope.password));
            options.host = host;
            options.port = $scope.port;
            options.path = $scope.path;
            options.userName = $scope.userName;
            options.password = $scope.password;
            options.useProxy = $scope.useProxy;
            Core.connectToServer(localStorage, options);
        };
    }
    JVM.ConnectController = ConnectController;
})(JVM || (JVM = {}));
var JVM;
(function (JVM) {
    function configureScope($scope, $location, workspace) {
        $scope.isActive = function (href) {
            var tidy = Core.trimLeading(href, "#");
            var loc = $location.path();
            return loc === tidy;
        };
        $scope.isValid = function (link) {
            return link && link.isValid(workspace);
        };
        $scope.hasLocalMBean = function () {
            return JVM.hasLocalMBean(workspace);
        };
        $scope.breadcrumbs = [
            {
                content: '<i class=" icon-signin"></i> Remote',
                title: "Connect to a remote JVM running Jolokia",
                isValid: function (workspace) {
                    return true;
                },
                href: "#/jvm/connect"
            }, 
            {
                content: '<i class="icon-list-ul"></i> Local',
                title: "View a diagram of the route",
                isValid: function (workspace) {
                    return hasLocalMBean(workspace);
                },
                href: "#/jvm/local"
            }
        ];
    }
    JVM.configureScope = configureScope;
    function hasLocalMBean(workspace) {
        return workspace.treeContainsDomainAndProperties('hawtio', {
            type: 'JVMList'
        });
    }
    JVM.hasLocalMBean = hasLocalMBean;
})(JVM || (JVM = {}));
var Jvm;
(function (Jvm) {
    var pluginName = 'jvm';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'datatable', 
        'hawtioCore'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/jvm/connect', {
            templateUrl: 'app/jvm/html/connect.html'
        }).when('/jvm/local', {
            templateUrl: 'app/jvm/html/local.html'
        });
    }).constant('mbeanName', 'hawtio:type=JVMList').run(function ($location, workspace, viewRegistry, layoutFull, helpRegistry) {
        viewRegistry[pluginName] = layoutFull;
        helpRegistry.addUserDoc('jvm', 'app/jvm/doc/help.md');
        workspace.topLevelTabs.push({
            content: "Connect",
            title: "Connect to other JVMs",
            isValid: function (workspace) {
                return true;
            },
            href: function () {
                return '#/jvm/connect';
            },
            isActive: function (workspace) {
                return workspace.isLinkActive("jvm");
            }
        });
    });
    hawtioPluginLoader.addModule(pluginName);
})(Jvm || (Jvm = {}));
var JVM;
(function (JVM) {
    function JVMsController($scope, $window, $location, workspace, jolokia, mbeanName) {
        JVM.configureScope($scope, $location, workspace);
        $scope.data = [];
        $scope.deploying = false;
        $scope.status = '';
        $scope.fetch = function () {
            notification('info', 'Discovering local JVM processes, please wait...');
            jolokia.request({
                type: 'exec',
                mbean: mbeanName,
                operation: 'listLocalJVMs()',
                arguments: []
            }, {
                success: render,
                error: function (response) {
                    $scope.data = [];
                    $scope.status = 'Could not discover local JVM processes: ' + response.error;
                    Core.$apply($scope);
                }
            });
        };
        $scope.stopAgent = function (pid) {
            notification('info', "Attempting to detach agent from PID " + pid);
            jolokia.request({
                type: 'exec',
                mbean: mbeanName,
                operation: 'stopAgent(java.lang.String)',
                arguments: [
                    pid
                ]
            }, onSuccess(function () {
                notification('success', "Detached agent from PID " + pid);
                $scope.fetch();
            }));
        };
        $scope.startAgent = function (pid) {
            notification('info', "Attempting to attach agent to PID " + pid);
            jolokia.request({
                type: 'exec',
                mbean: mbeanName,
                operation: 'startAgent(java.lang.String)',
                arguments: [
                    pid
                ]
            }, onSuccess(function () {
                notification('success', "Attached agent to PID " + pid);
                $scope.fetch();
            }));
        };
        $scope.connectTo = function (url) {
            $window.open("?url=" + encodeURIComponent(url));
        };
        function render(response) {
            $scope.data = response.value;
            if ($scope.data.length === 0) {
                $scope.status = 'Could not discover local JVM processes';
            }
            Core.$apply($scope);
        }
        $scope.fetch();
    }
    JVM.JVMsController = JVMsController;
})(JVM || (JVM = {}));
var Karaf;
(function (Karaf) {
    function FeatureController($scope, jolokia, workspace, $routeParams) {
        $scope.hasFabric = Fabric.hasFabric(workspace);
        $scope.name = $routeParams.name;
        $scope.version = $routeParams.version;
        $scope.bundlesByLocation = {};
        $scope.props = "properties";
        updateTableContents();
        $scope.install = function () {
            Karaf.installFeature(workspace, jolokia, $scope.name, $scope.version, function () {
                notification('success', 'Installed feature ' + $scope.name);
            }, function (response) {
                notification('error', 'Failed to install feature ' + $scope.name + ' due to ' + response.error);
            });
        };
        $scope.uninstall = function () {
            Karaf.uninstallFeature(workspace, jolokia, $scope.name, $scope.version, function () {
                notification('success', 'Uninstalled feature ' + $scope.name);
            }, function (response) {
                notification('error', 'Failed to uninstall feature ' + $scope.name + ' due to ' + response.error);
            });
        };
        $scope.toProperties = function (elements) {
            var answer = '';
            angular.forEach(elements, function (value, name) {
                answer += value['Key'] + " = " + value['Value'] + "\n";
            });
            return answer.trim();
        };
        function populateTable(response) {
            $scope.row = Karaf.extractFeature(response.value, $scope.name, $scope.version);
            if ($scope.row) {
                addBundleDetails($scope.row);
                var dependencies = [];
                angular.forEach($scope.row.Dependencies, function (version, name) {
                    angular.forEach(version, function (data, version) {
                        dependencies.push({
                            Name: name,
                            Version: version
                        });
                    });
                });
                $scope.row.Dependencies = dependencies;
            }
            Core.$apply($scope);
        }
        function setBundles(response) {
            var bundleMap = {};
            Osgi.defaultBundleValues(workspace, $scope, response.values);
            angular.forEach(response.value, function (bundle) {
                var location = bundle["Location"];
                $scope.bundlesByLocation[location] = bundle;
            });
        }
        ;
        function updateTableContents() {
            var featureMbean = Karaf.getSelectionFeaturesMBean(workspace);
            var bundleMbean = Osgi.getSelectionBundleMBean(workspace);
            var jolokia = workspace.jolokia;
            if (bundleMbean) {
                setBundles(jolokia.request({
                    type: 'exec',
                    mbean: bundleMbean,
                    operation: 'listBundles()'
                }));
            }
            if (featureMbean) {
                jolokia.request({
                    type: 'read',
                    mbean: featureMbean
                }, onSuccess(populateTable));
            }
        }
        function addBundleDetails(feature) {
            var bundleDetails = [];
            angular.forEach(feature["Bundles"], function (bundleLocation) {
                var bundle = $scope.bundlesByLocation[bundleLocation];
                if (bundle) {
                    bundle["Installed"] = true;
                    bundleDetails.push(bundle);
                } else {
                    bundleDetails.push({
                        "Location": bundleLocation,
                        "Installed": false
                    });
                }
            });
            feature["BundleDetails"] = bundleDetails;
        }
    }
    Karaf.FeatureController = FeatureController;
})(Karaf || (Karaf = {}));
var Karaf;
(function (Karaf) {
    function FeaturesController($scope, $location, workspace, jolokia) {
        $scope.hasFabric = Fabric.hasFabric(workspace);
        $scope.responseJson = '';
        $scope.filter = '';
        $scope.installedFeatures = [];
        $scope.features = [];
        $scope.repositories = [];
        $scope.selectedRepositoryId = '';
        $scope.selectedRepository = {};
        $scope.init = function () {
            var selectedRepositoryId = $location.search()['repositoryId'];
            if (selectedRepositoryId) {
                $scope.selectedRepositoryId = selectedRepositoryId;
            }
            var filter = $location.search()['filter'];
            if (filter) {
                $scope.filter = filter;
            }
        };
        $scope.init();
        $scope.$watch('selectedRepository', function (newValue, oldValue) {
            console.log("selectedRepository: ", $scope.selectedRepository);
            if (newValue !== oldValue) {
                if (!newValue) {
                    $scope.selectedRepositoryId = '';
                } else {
                    $scope.selectedRepositoryId = newValue['repository'];
                }
                $location.search('repositoryId', $scope.selectedRepositoryId);
            }
        }, true);
        $scope.$watch('filter', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $location.search('filter', newValue);
            }
        });
        var featuresMBean = Karaf.getSelectionFeaturesMBean(workspace);
        Karaf.log.debug("Features mbean: ", featuresMBean);
        if (featuresMBean) {
            Core.register(jolokia, $scope, {
                type: 'read',
                mbean: featuresMBean
            }, onSuccess(render));
        }
        $scope.triggerRefresh = function () {
            jolokia.request({
                type: 'read',
                method: 'POST',
                mbean: featuresMBean
            }, onSuccess(render));
        };
        $scope.install = function (feature) {
            notification('info', 'Installing feature ' + feature.Name);
            Karaf.installFeature(workspace, jolokia, feature.Name, feature.Version, function () {
                notification('success', 'Installed feature ' + feature.Name);
                $scope.installedFeatures.add(feature);
                $scope.triggerRefresh();
                Core.$apply($scope);
            }, function (response) {
                Karaf.log.error('Failed to install feature ', feature.Name, ' due to ', response.error);
                Karaf.log.info('stack trace: ', response.stacktrace);
                Core.$apply($scope);
            });
        };
        $scope.uninstall = function (feature) {
            notification('info', 'Uninstalling feature ' + feature.Name);
            Karaf.uninstallFeature(workspace, jolokia, feature.Name, feature.Version, function () {
                notification('success', 'Uninstalled feature ' + feature.Name);
                $scope.installedFeatures.remove(feature);
                $scope.triggerRefresh();
                Core.$apply($scope);
            }, function (response) {
                Karaf.log.error('Failed to uninstall feature ', feature.Name, ' due to ', response.error);
                Karaf.log.info('stack trace: ', response.stacktrace);
                Core.$apply($scope);
            });
        };
        $scope.filteredRows = [
            'Bundles', 
            'Configurations', 
            'Configuration Files', 
            'Dependencies'
        ];
        $scope.showRow = function (key, value) {
            if ($scope.filteredRows.any(key)) {
                return false;
            }
            if (angular.isArray(value)) {
                if (value.length === 0) {
                    return false;
                }
            }
            if (angular.isString(value)) {
                if (Core.isBlank(value)) {
                    return false;
                }
            }
            if (angular.isObject(value)) {
                if (!value || Object.equal(value, {})) {
                    return false;
                }
            }
            return true;
        };
        $scope.installed = function (installed) {
            var answer = Core.parseBooleanValue(installed);
            if ($scope.hasFabric) {
                return !answer;
            }
            return answer;
        };
        $scope.showValue = function (value) {
            if (angular.isArray(value)) {
                var answer = [
                    '<ul class="zebra-list">'
                ];
                value.forEach(function (v) {
                    answer.push('<li>' + v + '</li>');
                });
                answer.push('</ul>');
                return answer.join('\n');
            }
            if (angular.isObject(value)) {
                var answer = [
                    '<table class="table">', 
                    '<tbody>'
                ];
                angular.forEach(value, function (value, key) {
                    answer.push('<tr>');
                    answer.push('<td>' + key + '</td>');
                    answer.push('<td>' + value + '</td>');
                    answer.push('</tr>');
                });
                answer.push('</tbody>');
                answer.push('</table>');
                return answer.join('\n');
            }
            return "" + value;
        };
        $scope.getStateStyle = function (feature) {
            if (Core.parseBooleanValue(feature.Installed)) {
                return "badge badge-success";
            }
            return "badge";
        };
        $scope.filterFeature = function (feature) {
            if (Core.isBlank($scope.filter)) {
                return true;
            }
            if (feature.Id.has($scope.filter)) {
                return true;
            }
            return false;
        };
        function render(response) {
            var responseJson = angular.toJson(response.value);
            if ($scope.responseJson !== responseJson) {
                $scope.responseJson = responseJson;
                var features = [];
                var repositories = [];
                Karaf.populateFeaturesAndRepos(response.value, features, repositories);
                var installedFeatures = features.filter(function (f) {
                    return Core.parseBooleanValue(f.Installed);
                });
                var uninstalledFeatures = features.filter(function (f) {
                    return !Core.parseBooleanValue(f.Installed);
                });
                $scope.installedFeatures = installedFeatures.sortBy(function (f) {
                    return f['Name'];
                });
                uninstalledFeatures = uninstalledFeatures.sortBy(function (f) {
                    return f['Name'];
                });
                repositories.sortBy('id').map(function (r) {
                    return r['id'];
                }).forEach(function (repo) {
                    $scope.repositories.push({
                        repository: repo,
                        features: uninstalledFeatures.filter(function (f) {
                            return f['RepositoryName'] === repo;
                        })
                    });
                });
                if (Core.isBlank($scope.selectedRepositoryId)) {
                    $scope.selectedRepository = $scope.repositories.first();
                } else {
                    $scope.selectedRepository = $scope.repositories.find(function (r) {
                        return r.repository === $scope.selectedRepositoryId;
                    });
                }
                Core.$apply($scope);
            }
        }
    }
    Karaf.FeaturesController = FeaturesController;
})(Karaf || (Karaf = {}));
var Karaf;
(function (Karaf) {
    Karaf.log = Logger.get("Karaf");
    function setSelect(selection, group) {
        if (!angular.isDefined(selection)) {
            return group[0];
        }
        var answer = group.findIndex(function (item) {
            return item.id === selection.id;
        });
        if (answer !== -1) {
            return group[answer];
        } else {
            return group[0];
        }
    }
    Karaf.setSelect = setSelect;
    function installFeature(workspace, jolokia, feature, version, success, error) {
        jolokia.request({
            type: 'exec',
            mbean: getSelectionFeaturesMBean(workspace),
            operation: 'installFeature(java.lang.String, java.lang.String)',
            arguments: [
                feature, 
                version
            ]
        }, onSuccess(success, {
            error: error
        }));
    }
    Karaf.installFeature = installFeature;
    function uninstallFeature(workspace, jolokia, feature, version, success, error) {
        jolokia.request({
            type: 'exec',
            mbean: getSelectionFeaturesMBean(workspace),
            operation: 'uninstallFeature(java.lang.String, java.lang.String)',
            arguments: [
                feature, 
                version
            ]
        }, onSuccess(success, {
            error: error
        }));
    }
    Karaf.uninstallFeature = uninstallFeature;
    function toCollection(values) {
        var collection = values;
        if (!angular.isArray(values)) {
            collection = [
                values
            ];
        }
        return collection;
    }
    Karaf.toCollection = toCollection;
    function featureLinks(workspace, name, version) {
        return "<a href='" + url("#/karaf/feature/" + name + "/" + version + workspace.hash()) + "'>" + version + "</a>";
    }
    Karaf.featureLinks = featureLinks;
    function extractFeature(attributes, name, version) {
        var features = [];
        var repos = [];
        populateFeaturesAndRepos(attributes, features, repos);
        return features.find(function (feature) {
            return feature.Name == name && feature.Version == version;
        });
    }
    Karaf.extractFeature = extractFeature;
    function populateFeaturesAndRepos(attributes, features, repositories) {
        var fullFeatures = attributes["Features"];
        angular.forEach(attributes["Repositories"], function (repo) {
            repositories.push({
                id: repo["Name"],
                uri: repo["Uri"]
            });
            angular.forEach(repo["Features"], function (feature) {
                angular.forEach(feature, function (entry) {
                    var f = Object.extended(fullFeatures[entry['Name']][entry['Version']]).clone();
                    f["Id"] = entry["Name"] + "/" + entry["Version"];
                    f["RepositoryName"] = repo["Name"];
                    f["RepositoryURI"] = repo["Uri"];
                    features.push(f);
                });
            });
        });
    }
    Karaf.populateFeaturesAndRepos = populateFeaturesAndRepos;
    function createScrComponentsView(workspace, jolokia, components) {
        var result = [];
        angular.forEach(components, function (component) {
            result.push({
                Name: component,
                State: getComponentStateDescription(getComponentState(workspace, jolokia, component))
            });
        });
        return result;
    }
    Karaf.createScrComponentsView = createScrComponentsView;
    function getComponentStateDescription(state) {
        switch(state) {
            case 2:
                return "Enabled";
            case 4:
                return "Unsatisfied";
            case 8:
                return "Activating";
            case 16:
                return "Active";
            case 32:
                return "Registered";
            case 64:
                return "Factory";
            case 128:
                return "Deactivating";
            case 256:
                return "Destroying";
            case 1024:
                return "Disabling";
            case 2048:
                return "Disposing";
        }
        return "Unknown";
    }
    Karaf.getComponentStateDescription = getComponentStateDescription;
    ;
    function getAllComponents(workspace, jolokia) {
        var scrMBean = getSelectionScrMBean(workspace);
        var response = jolokia.request({
            type: 'read',
            mbean: scrMBean,
            arguments: []
        });
        if (!('Components' in response.value)) {
            response = jolokia.request({
                type: 'exec',
                mbean: scrMBean,
                operation: 'listComponents()'
            });
            return createScrComponentsView(workspace, jolokia, response.value);
        }
        return response.value['Components'].values;
    }
    Karaf.getAllComponents = getAllComponents;
    function getComponentByName(workspace, jolokia, componentName) {
        var components = getAllComponents(workspace, jolokia);
        return components.find(function (c) {
            return c.Name == componentName;
        });
    }
    Karaf.getComponentByName = getComponentByName;
    function isComponentActive(workspace, jolokia, component) {
        var response = jolokia.request({
            type: 'exec',
            mbean: getSelectionScrMBean(workspace),
            operation: 'isComponentActive(java.lang.String)',
            arguments: [
                component
            ]
        });
        return response.value;
    }
    Karaf.isComponentActive = isComponentActive;
    function getComponentState(workspace, jolokia, component) {
        var response = jolokia.request({
            type: 'exec',
            mbean: getSelectionScrMBean(workspace),
            operation: 'componentState(java.lang.String)',
            arguments: [
                component
            ]
        });
        return response.value;
    }
    Karaf.getComponentState = getComponentState;
    function activateComponent(workspace, jolokia, component, success, error) {
        jolokia.request({
            type: 'exec',
            mbean: getSelectionScrMBean(workspace),
            operation: 'activateComponent(java.lang.String)',
            arguments: [
                component
            ]
        }, onSuccess(success, {
            error: error
        }));
    }
    Karaf.activateComponent = activateComponent;
    function deactivateComponent(workspace, jolokia, component, success, error) {
        jolokia.request({
            type: 'exec',
            mbean: getSelectionScrMBean(workspace),
            operation: 'deactiveateComponent(java.lang.String)',
            arguments: [
                component
            ]
        }, onSuccess(success, {
            error: error
        }));
    }
    Karaf.deactivateComponent = deactivateComponent;
    function populateDependencies(attributes, dependencies, features) {
        angular.forEach(dependencies, function (feature) {
            angular.forEach(feature, function (entry) {
                var enhancedFeature = extractFeature(attributes, entry["Name"], entry["Version"]);
                enhancedFeature["id"] = entry["Name"] + "/" + entry["Version"];
                features.push(enhancedFeature);
            });
        });
    }
    Karaf.populateDependencies = populateDependencies;
    function getSelectionFeaturesMBean(workspace) {
        if (workspace) {
            var featuresStuff = workspace.mbeanTypesToDomain["features"] || {};
            var karaf = featuresStuff["org.apache.karaf"] || {};
            var mbean = karaf.objectName;
            if (mbean) {
                return mbean;
            }
            var folder = workspace.tree.navigate("org.apache.karaf", "features");
            if (!folder) {
                folder = workspace.tree.navigate("org.apache.karaf");
                if (folder) {
                    var children = folder.children;
                    folder = null;
                    angular.forEach(children, function (child) {
                        if (!folder) {
                            folder = child.navigate("features");
                        }
                    });
                }
            }
            if (folder) {
                var children = folder.children;
                if (children) {
                    var node = children[0];
                    if (node) {
                        return node.objectName;
                    }
                }
                return folder.objectName;
            }
        }
        return null;
    }
    Karaf.getSelectionFeaturesMBean = getSelectionFeaturesMBean;
    function getSelectionScrMBean(workspace) {
        if (workspace) {
            var scrStuff = workspace.mbeanTypesToDomain["scr"] || {};
            var karaf = scrStuff["org.apache.karaf"] || {};
            var mbean = karaf.objectName;
            if (mbean) {
                return mbean;
            }
            var folder = workspace.tree.navigate("org.apache.karaf", "scr");
            if (!folder) {
                folder = workspace.tree.navigate("org.apache.karaf");
                if (folder) {
                    var children = folder.children;
                    folder = null;
                    angular.forEach(children, function (child) {
                        if (!folder) {
                            folder = child.navigate("scr");
                        }
                    });
                }
            }
            if (folder) {
                var children = folder.children;
                if (children) {
                    var node = children[0];
                    if (node) {
                        return node.objectName;
                    }
                }
                return folder.objectName;
            }
        }
        return null;
    }
    Karaf.getSelectionScrMBean = getSelectionScrMBean;
})(Karaf || (Karaf = {}));
var Karaf;
(function (Karaf) {
    var pluginName = 'karaf';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'hawtioCore'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/osgi/server', {
            templateUrl: 'app/karaf/html/server.html'
        }).when('/osgi/features', {
            templateUrl: 'app/karaf/html/features.html',
            reloadOnSearch: false
        }).when('/osgi/scr-components', {
            templateUrl: 'app/karaf/html/scr-components.html'
        }).when('/osgi/scr-component/:name', {
            templateUrl: 'app/karaf/html/scr-component.html'
        }).when('/osgi/feature/:name/:version', {
            templateUrl: 'app/karaf/html/feature.html'
        });
    }).run(function (workspace, viewRegistry, helpRegistry) {
        helpRegistry.addUserDoc('karaf', 'app/karaf/doc/help.md', function () {
            return workspace.treeContainsDomainAndProperties('org.apache.karaf');
        });
    });
    hawtioPluginLoader.addModule(pluginName);
})(Karaf || (Karaf = {}));
var Karaf;
(function (Karaf) {
    function NavBarController($scope, workspace) {
        $scope.hash = workspace.hash();
        $scope.isKarafEnabled = workspace.treeContainsDomainAndProperties("org.apache.karaf");
        $scope.isFeaturesEnabled = Karaf.getSelectionFeaturesMBean(workspace);
        $scope.isScrEnabled = Karaf.getSelectionScrMBean(workspace);
        $scope.$on('$routeChangeSuccess', function () {
            $scope.hash = workspace.hash();
        });
        $scope.isActive = function (nav) {
            return workspace.isLinkActive(nav);
        };
    }
    Karaf.NavBarController = NavBarController;
})(Karaf || (Karaf = {}));
var Karaf;
(function (Karaf) {
    function ScrComponentController($scope, $location, workspace, jolokia, $routeParams) {
        $scope.name = $routeParams.name;
        populateTable();
        function populateTable() {
            $scope.row = Karaf.getComponentByName(workspace, jolokia, $scope.name);
            Core.$apply($scope);
        }
        $scope.activate = function () {
            Karaf.activateComponent(workspace, jolokia, $scope.row['Name'], function () {
                console.log("Activated!");
            }, function () {
                console.log("Failed to activate!");
            });
        };
        $scope.deactivate = function () {
            Karaf.deactivateComponent(workspace, jolokia, $scope.row['Name'], function () {
                console.log("Deactivated!");
            }, function () {
                console.log("Failed to deactivate!");
            });
        };
    }
    Karaf.ScrComponentController = ScrComponentController;
})(Karaf || (Karaf = {}));
var Karaf;
(function (Karaf) {
    function ScrComponentsController($scope, $location, workspace, jolokia) {
        $scope.component = empty();
        $scope.result = [];
        $scope.components = [];
        $scope.selectedComponents = [];
        $scope.scrOptions = {
            data: 'components',
            showFilter: false,
            showColumnMenu: false,
            filterOptions: {
                useExternalFilter: false
            },
            selectedItems: $scope.selectedComponents,
            rowHeight: 32,
            selectWithCheckboxOnly: true,
            columnDefs: [
                {
                    field: 'Name',
                    displayName: 'Name',
                    cellTemplate: '<div class="ngCellText"><a href="#/osgi/scr-component/{{row.entity.Name}}?p=container">{{row.getProperty(col.field)}}</a></div>',
                    width: 400
                }, 
                {
                    field: 'State',
                    displayName: 'State',
                    cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>',
                    width: 200
                }
            ]
        };
        var scrMBean = Karaf.getSelectionScrMBean(workspace);
        if (scrMBean) {
            render(Karaf.getAllComponents(workspace, jolokia));
        }
        $scope.activate = function () {
            $scope.selectedComponents.forEach(function (component) {
                Karaf.activateComponent(workspace, jolokia, component.Name, function () {
                    console.log("Activated!");
                }, function () {
                    console.log("Failed to activate!");
                });
            });
        };
        $scope.deactivate = function () {
            $scope.selectedComponents.forEach(function (component) {
                Karaf.deactivateComponent(workspace, jolokia, component.Name, function () {
                    console.log("Deactivated!");
                }, function () {
                    console.log("Failed to deactivate!");
                });
            });
        };
        function empty() {
            return [
                {
                    Name: "",
                    Status: false
                }
            ];
        }
        function render(components) {
            if (!Object.equal($scope.result, components)) {
                $scope.components = components;
                $scope.result = $scope.components;
                Core.$apply($scope);
            }
        }
    }
    Karaf.ScrComponentsController = ScrComponentsController;
})(Karaf || (Karaf = {}));
var Karaf;
(function (Karaf) {
    function ServerController($scope, $location, workspace, jolokia) {
        $scope.data = {
            name: "",
            version: "",
            state: "",
            root: "",
            startLevel: "",
            framework: "",
            frameworkVersion: "",
            location: "",
            sshPort: "",
            rmiRegistryPort: "",
            rmiServerPort: "",
            pid: ""
        };
        $scope.$on('jmxTreeUpdated', reloadFunction);
        $scope.$watch('workspace.tree', reloadFunction);
        function reloadFunction() {
            setTimeout(loadData, 50);
        }
        function loadData() {
            console.log("Loading Karaf data...");
            jolokia.search("org.apache.karaf:type=admin,*", onSuccess(render));
        }
        function render(response) {
            if (angular.isArray(response)) {
                var mbean = response[0];
                if (mbean) {
                    jolokia.getAttribute(mbean, "Instances", onSuccess(function (response) {
                        onInstances(response, mbean);
                    }));
                }
            }
        }
        function onInstances(instances, mbean) {
            if (instances) {
                var parsedMBean = Core.parseMBean(mbean);
                var instanceName = 'root';
                if ('attributes' in parsedMBean) {
                    if ('name' in parsedMBean['attributes']) {
                        instanceName = parsedMBean['attributes']['name'];
                    }
                }
                var rootInstance = instances[instanceName];
                $scope.data.name = rootInstance.Name;
                $scope.data.state = rootInstance.State;
                $scope.data.root = rootInstance["Is Root"];
                $scope.data.location = rootInstance.Location;
                $scope.data.sshPort = rootInstance["SSH Port"];
                $scope.data.rmiRegistryPort = rootInstance["RMI Registry Port"];
                $scope.data.rmiServerPort = rootInstance["RMI Server Port"];
                $scope.data.pid = rootInstance.Pid;
                $scope.data.version = "?";
                $scope.data.startLevel = "?";
                $scope.data.framework = "?";
                $scope.data.frameworkVersion = "?";
                var systemMbean = "org.apache.karaf:type=system,name=" + rootInstance.Name;
                var response = jolokia.request({
                    type: "read",
                    mbean: systemMbean,
                    attribute: [
                        "StartLevel", 
                        "Framework", 
                        "Version"
                    ]
                }, onSuccess(null));
                var obj = response.value;
                if (obj) {
                    $scope.data.version = obj.Version;
                    $scope.data.startLevel = obj.StartLevel;
                    $scope.data.framework = obj.Framework;
                }
                var response2 = jolokia.search("osgi.core:type=bundleState,*", onSuccess(null));
                if (angular.isArray(response2)) {
                    var mbean = response2[0];
                    if (mbean) {
                        var response3 = jolokia.request({
                            type: 'exec',
                            mbean: mbean,
                            operation: 'getVersion(long)',
                            arguments: [
                                0
                            ]
                        }, onSuccess(null));
                        var obj3 = response3.value;
                        if (obj3) {
                            $scope.data.frameworkVersion = obj3;
                        }
                    }
                }
            }
            Core.$apply($scope);
        }
    }
    Karaf.ServerController = ServerController;
})(Karaf || (Karaf = {}));
var Log;
(function (Log) {
    function logSourceHref(row) {
        if (!row) {
            return "";
        }
        var log = row.entity;
        if (log) {
            return logSourceHrefEntity(log);
        } else {
            return logSourceHrefEntity(row);
        }
    }
    Log.logSourceHref = logSourceHref;
    function logSourceHrefEntity(log) {
        var fileName = Log.removeQuestion(log.fileName);
        var className = Log.removeQuestion(log.className);
        var properties = log.properties;
        var mavenCoords = "";
        if (properties) {
            mavenCoords = properties["maven.coordinates"];
        }
        if (mavenCoords && fileName) {
            var link = "#/source/view/" + mavenCoords + "/class/" + className + "/" + fileName;
            var line = log.lineNumber;
            if (line) {
                link += "?line=" + line;
            }
            return link;
        } else {
            return "";
        }
    }
    Log.logSourceHrefEntity = logSourceHrefEntity;
    function hasLogSourceHref(log) {
        var properties = log.properties;
        if (!properties) {
            return false;
        }
        var mavenCoords = "";
        if (properties) {
            mavenCoords = properties["maven.coordinates"];
        }
        return angular.isDefined(mavenCoords) && mavenCoords !== "";
    }
    Log.hasLogSourceHref = hasLogSourceHref;
    function removeQuestion(text) {
        return (!text || text === "?") ? null : text;
    }
    Log.removeQuestion = removeQuestion;
    var _stackRegex = /\s*at\s+([\w\.$_]+(\.([\w$_]+))*)\((.*)?:(\d+)\).*\[(.*)\]/;
    function formatStackTrace(exception) {
        if (!exception) {
            return '';
        }
        if (!angular.isArray(exception) && angular.isString(exception)) {
            exception = exception.split('\n');
        } else {
            return '';
        }
        var answer = '<ul class="unstyled">\n';
        exception.each(function (line) {
            answer += "<li>" + Log.formatStackLine(line) + "</li>\n";
        });
        answer += "</ul>\n";
        return answer;
    }
    Log.formatStackTrace = formatStackTrace;
    function formatStackLine(line) {
        var match = _stackRegex.exec(line);
        if (match && match.length > 6) {
            var classAndMethod = match[1];
            var fileName = match[4];
            var line = match[5];
            var mvnCoords = match[6];
            if (classAndMethod && fileName && mvnCoords) {
                var className = classAndMethod;
                var idx = classAndMethod.lastIndexOf('.');
                if (idx > 0) {
                    className = classAndMethod.substring(0, idx);
                }
                var link = "#/source/view/" + mvnCoords + "/class/" + className + "/" + fileName;
                if (angular.isDefined(line)) {
                    link += "?line=" + line;
                }
                return "<div class='stack-line'>  at <a href='" + link + "'>" + classAndMethod + "</a>(<span class='fileName'>" + fileName + "</span>:<span class='lineNumber'>" + line + "</span>)[<span class='mavenCoords'>" + mvnCoords + "</span>]</div>";
            }
        }
        return '<pre class="stack-line">' + line + '</pre>';
    }
    Log.formatStackLine = formatStackLine;
    function getLogCacheSize(localStorage) {
        var text = localStorage['logCacheSize'];
        if (text) {
            return parseInt(text);
        }
        return 1000;
    }
    Log.getLogCacheSize = getLogCacheSize;
})(Log || (Log = {}));
var Log;
(function (Log) {
    var pluginName = 'log';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'ngGrid', 
        'datatable', 
        'hawtioCore'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/logs', {
            templateUrl: 'app/log/html/logs.html',
            reloadOnSearch: false
        });
    }).run(function ($location, workspace, viewRegistry, layoutFull, helpRegistry) {
        viewRegistry['log'] = layoutFull;
        helpRegistry.addUserDoc('log', 'app/log/doc/help.md', function () {
            return workspace.treeContainsDomainAndProperties('org.fusesource.insight', {
                type: 'LogQuery'
            });
        });
        workspace.topLevelTabs.push({
            content: "Logs",
            title: "View and search the logs of this container",
            isValid: function (workspace) {
                return workspace.treeContainsDomainAndProperties('org.fusesource.insight', {
                    type: 'LogQuery'
                });
            },
            href: function () {
                return "#/logs";
            }
        });
        workspace.subLevelTabs.push({
            content: '<i class="icon-list-alt"></i> Log',
            title: "View the logs in this process",
            isValid: function (workspace) {
                return workspace.hasDomainAndProperties('org.fusesource.insight', {
                    type: 'LogQuery'
                });
            },
            href: function () {
                return "#/logs";
            }
        });
    }).filter('logDateFilter', function ($filter) {
        var standardDateFilter = $filter('date');
        return function (dateToFormat) {
            return standardDateFilter(dateToFormat, 'yyyy-MM-dd HH:mm:ss');
        };
    });
    hawtioPluginLoader.addModule(pluginName);
})(Log || (Log = {}));
var Log;
(function (Log) {
    function LogController($scope, $routeParams, $location, localStorage, workspace, $window, $document) {
        $scope.logs = [];
        $scope.branding = Branding.enabled;
        $scope.init = function () {
            $scope.searchText = $routeParams['s'];
            if (!angular.isDefined($scope.searchText)) {
                $scope.searchText = '';
            }
            $scope.filter = {
                logLevelQuery: $routeParams['l'],
                logLevelExactMatch: Core.parseBooleanValue($routeParams['e'])
            };
            if (!angular.isDefined($scope.filter.logLevelQuery)) {
                $scope.filter.logLevelQuery = '';
            }
            if (!angular.isDefined($scope.filter.logLevelExactMatch)) {
                $scope.filter.logLevelExactMatch = false;
            }
        };
        $scope.$on('$routeUpdate', $scope.init);
        $scope.$watch('searchText', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $location.search('s', newValue);
            }
        });
        $scope.$watch('filter.logLevelQuery', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $location.search('l', newValue);
            }
        });
        $scope.$watch('filter.logLevelExactMatch', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $location.search('e', newValue);
            }
        });
        $scope.init();
        $scope.toTime = 0;
        $scope.queryJSON = {
            type: "EXEC",
            mbean: logQueryMBean,
            operation: "logResultsSince",
            arguments: [
                $scope.toTime
            ],
            ignoreErrors: true
        };
        $scope.logLevels = [
            "TRACE", 
            "DEBUG", 
            "INFO", 
            "WARN", 
            "ERROR"
        ];
        $scope.logLevelMap = {};
        angular.forEach($scope.logLevels, function (name, idx) {
            $scope.logLevelMap[name] = idx;
            $scope.logLevelMap[name.toLowerCase()] = idx;
        });
        $scope.logClass = function (log) {
            return logLevelClass(log['level']);
        };
        $scope.logIcon = function (log) {
            var style = $scope.logClass(log);
            if (style === "error") {
                return "red icon-warning-sign";
            }
            if (style === "warning") {
                return "orange icon-exclamation-sign";
            }
            if (style === "info") {
                return "icon-info-sign";
            }
            return "icon-cog";
        };
        $scope.logSourceHref = Log.logSourceHref;
        $scope.hasLogSourceHref = function (row) {
            return Log.hasLogSourceHref(row);
        };
        $scope.dateFormat = 'yyyy-MM-dd HH:mm:ss';
        $scope.formatException = function (line) {
            return Log.formatStackLine(line);
        };
        $scope.getSupport = function () {
            var uri = "https://access.redhat.com/knowledge/solutions";
            var expanded = $scope.logs.filter(function (log) {
                return log.expanded;
            });
            if (expanded.length > 0) {
                var last = expanded.last();
                var text = last.message;
                var logger = last.logger;
                uri = uri + "?logger=" + logger + "&text=" + text;
            }
            window.location.href = uri;
        };
        $scope.addToDashboardLink = function () {
            var href = "#/logs";
            var routeParams = angular.toJson($routeParams);
            var size = angular.toJson({
                size_x: 8,
                size_y: 1
            });
            var title = "Logs";
            if ($scope.filter.logLevelQuery !== "") {
                title = title + " LogLevel: " + $scope.filter.logLevelQuery;
            }
            if ($scope.filter.logLevelExactMatch) {
                title = title + " Exact Match";
            }
            if ($scope.searchText !== "") {
                title = title + " Filter: " + $scope.searchText;
            }
            return "#/dashboard/add?tab=dashboard" + "&href=" + encodeURIComponent(href) + "&routeParams=" + encodeURIComponent(routeParams) + "&title=" + encodeURIComponent(title) + "&size=" + encodeURIComponent(size);
        };
        $scope.isInDashboardClass = function () {
            if (angular.isDefined($scope.inDashboard && $scope.inDashboard)) {
                return "log-table-dashboard";
            }
            return "";
        };
        $scope.filterLogMessage = function (log) {
            if ($scope.filter.logLevelQuery !== "") {
                var logLevelExactMatch = $scope.filter.logLevelExactMatch;
                var logLevelQuery = $scope.filter.logLevelQuery;
                var logLevelQueryOrdinal = (logLevelExactMatch) ? 0 : $scope.logLevelMap[logLevelQuery];
                if (logLevelExactMatch) {
                    if (log.level !== logLevelQuery) {
                        return false;
                    }
                } else {
                    var idx = $scope.logLevelMap[log.level];
                    if (!(idx >= logLevelQueryOrdinal || idx < 0)) {
                        return false;
                    }
                }
            }
            if ($scope.searchText.startsWith("l=")) {
                return log.logger.has($scope.searchText.last($scope.searchText.length - 2));
            }
            if ($scope.searchText.startsWith("m=")) {
                return log.message.has($scope.searchText.last($scope.searchText.length - 2));
            }
            return log.logger.has($scope.searchText) || log.message.has($scope.searchText);
        };
        $scope.formatStackTrace = function (exception) {
            if (!exception) {
                return "";
            }
            var answer = '<ul class="unstyled">\n';
            exception.forEach(function (line) {
                answer = answer + '<li>' + $scope.formatException(line) + '</li>';
            });
            answer += '\n</ul>';
            return answer;
        };
        var updateValues = function (response) {
            var scrollToBottom = false;
            if (!$scope.inDashboard) {
                var window = $($window);
                if ($scope.logs.length === 0) {
                    scrollToBottom = true;
                }
                if ((window.scrollTop() + window.height()) > (Core.getDocHeight() - 100)) {
                    scrollToBottom = true;
                }
            }
            var logs = response.events;
            var toTime = response.toTimestamp;
            if (toTime && angular.isNumber(toTime)) {
                if (toTime < 0) {
                    console.log("ignoring dodgy value of toTime: " + toTime);
                } else {
                    $scope.toTime = toTime;
                    $scope.queryJSON.arguments = [
                        toTime
                    ];
                }
            }
            if (logs) {
                var maxSize = Log.getLogCacheSize(localStorage);
                if ($scope.inDashboard) {
                    maxSize = 10;
                }
                var counter = 0;
                logs.forEach(function (log) {
                    if (log) {
                        if (!$scope.logs.any(function (key, item) {
                            return item.message === log.message && item.seq === log.message && item.timestamp === log.timestamp;
                        })) {
                            counter += 1;
                            $scope.logs.push(log);
                        }
                    }
                });
                if (maxSize > 0) {
                    var size = $scope.logs.length;
                    if (size > maxSize) {
                        var count = size - maxSize;
                        $scope.logs.splice(0, count);
                    }
                }
                if (counter) {
                    if (scrollToBottom) {
                        setTimeout(function () {
                            $document.scrollTop($document.height() - window.height());
                        }, 20);
                    }
                    Core.$apply($scope);
                }
            }
        };
        var jolokia = workspace.jolokia;
        jolokia.execute(logQueryMBean, "allLogResults", onSuccess(updateValues));
        var asyncUpdateValues = function (response) {
            var value = response.value;
            if (value) {
                updateValues(value);
            } else {
                notification("error", "Failed to get a response! " + JSON.stringify(response, null, 4));
            }
        };
        var callback = onSuccess(asyncUpdateValues, {
            error: function (response) {
                asyncUpdateValues(response);
            }
        });
        scopeStoreJolokiaHandle($scope, jolokia, jolokia.register(callback, $scope.queryJSON));
    }
    Log.LogController = LogController;
})(Log || (Log = {}));
var Maven;
(function (Maven) {
    function ArtifactController($scope, $routeParams, workspace, jolokia) {
        $scope.row = {
            groupId: $routeParams["group"] || "",
            artifactId: $routeParams["artifact"] || "",
            version: $routeParams["version"] || "",
            classifier: $routeParams["classifier"] || "",
            packaging: $routeParams["packaging"] || ""
        };
        var row = $scope.row;
        $scope.id = Maven.getName(row);
        Maven.addMavenFunctions($scope, workspace);
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateTableContents, 50);
        });
        $scope.$watch('workspace.selection', function () {
            updateTableContents();
        });
        function updateTableContents() {
            var mbean = Maven.getMavenIndexerMBean(workspace);
            if (mbean) {
                jolokia.execute(mbean, "search", row.groupId, row.artifactId, row.version, row.packaging, row.classifier, "", onSuccess(render));
            } else {
                console.log("No MavenIndexerMBean!");
            }
        }
        function render(response) {
            if (response && response.length) {
                var first = response[0];
                row.name = first.name;
                row.description = first.description;
            }
            Core.$apply($scope);
        }
    }
    Maven.ArtifactController = ArtifactController;
})(Maven || (Maven = {}));
var Maven;
(function (Maven) {
    function DependenciesController($scope, $routeParams, $location, workspace, jolokia) {
        $scope.artifacts = [];
        $scope.group = $routeParams["group"] || "";
        $scope.artifact = $routeParams["artifact"] || "";
        $scope.version = $routeParams["version"] || "";
        $scope.classifier = $routeParams["classifier"] || "";
        $scope.packaging = $routeParams["packaging"] || "";
        $scope.dependencyTree = null;
        Maven.addMavenFunctions($scope, workspace);
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateTableContents, 50);
        });
        $scope.$watch('workspace.selection', function () {
            updateTableContents();
        });
        $scope.onSelectNode = function (node) {
            $scope.selected = node;
        };
        $scope.onRootNode = function (rootNode) {
        };
        $scope.validSelection = function () {
            return $scope.selected && $scope.selected !== $scope.rootDependency;
        };
        $scope.viewDetails = function () {
            var dependency = Core.pathGet($scope.selected, [
                "dependency"
            ]);
            var link = $scope.detailLink(dependency);
            if (link) {
                var path = Core.trimLeading(link, "#");
                console.log("going to view " + path);
                $location.path(path);
            }
        };
        function updateTableContents() {
            var mbean = Maven.getAetherMBean(workspace);
            if (mbean) {
                jolokia.execute(mbean, "resolveJson(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)", $scope.group, $scope.artifact, $scope.version, $scope.packaging, $scope.classifier, onSuccess(render));
            } else {
                console.log("No AetherMBean!");
            }
        }
        function render(response) {
            if (response) {
                var json = JSON.parse(response);
                if (json) {
                    $scope.dependencyTree = new Folder("Dependencies");
                    $scope.dependencyActivations = [];
                    addChildren($scope.dependencyTree, json);
                    $scope.dependencyActivations.reverse();
                    $scope.rootDependency = $scope.dependencyTree.children[0];
                }
            }
            Core.$apply($scope);
        }
        function addChildren(folder, dependency) {
            var name = Maven.getName(dependency);
            var node = new Folder(name);
            node.key = name.replace(/\//g, '_');
            node["dependency"] = dependency;
            $scope.dependencyActivations.push(node.key);
            folder.children.push(node);
            var children = dependency["children"];
            angular.forEach(children, function (child) {
                addChildren(node, child);
            });
        }
    }
    Maven.DependenciesController = DependenciesController;
})(Maven || (Maven = {}));
var Maven;
(function (Maven) {
    Maven.log = Logger.get("Maven");
    function getMavenIndexerMBean(workspace) {
        if (workspace) {
            var mavenStuff = workspace.mbeanTypesToDomain["Indexer"] || {};
            var object = mavenStuff["hawtio"] || {};
            return object.objectName;
        } else {
            return null;
        }
    }
    Maven.getMavenIndexerMBean = getMavenIndexerMBean;
    function getAetherMBean(workspace) {
        if (workspace) {
            var mavenStuff = workspace.mbeanTypesToDomain["AetherFacade"] || {};
            var object = mavenStuff["hawtio"] || {};
            return object.objectName;
        } else {
            return null;
        }
    }
    Maven.getAetherMBean = getAetherMBean;
    function mavenLink(url) {
        var path = null;
        if (url) {
            if (url.startsWith("mvn:")) {
                path = url.substring(4);
            } else {
                var idx = url.indexOf(":mvn:");
                if (idx > 0) {
                    path = url.substring(idx + 5);
                }
            }
        }
        return path ? "#/maven/artifact/" + path : null;
    }
    Maven.mavenLink = mavenLink;
    function getName(row) {
        var id = (row.group || row.groupId) + "/" + (row.artifact || row.artifactId);
        if (row.version) {
            id += "/" + row.version;
        }
        if (row.classifier) {
            id += "/" + row.classifier;
        }
        if (row.packaging) {
            id += "/" + row.packaging;
        }
        return id;
    }
    Maven.getName = getName;
    function completeMavenUri($q, $scope, workspace, jolokia, query) {
        var mbean = getMavenIndexerMBean(workspace);
        if (!angular.isDefined(mbean)) {
            return $q.when([]);
        }
        var parts = query.split('/');
        if (parts.length === 1) {
            return Maven.completeGroupId(mbean, $q, $scope, workspace, jolokia, query, null, null);
        }
        if (parts.length === 2) {
            return Maven.completeArtifactId(mbean, $q, $scope, workspace, jolokia, parts[0], parts[1], null, null);
        }
        if (parts.length === 3) {
            return Maven.completeVersion(mbean, $q, $scope, workspace, jolokia, parts[0], parts[1], parts[2], null, null);
        }
        return $q.when([]);
    }
    Maven.completeMavenUri = completeMavenUri;
    function completeVersion(mbean, $q, $scope, workspace, jolokia, groupId, artifactId, partial, packaging, classifier) {
        var deferred = $q.defer();
        jolokia.request({
            type: 'exec',
            mbean: mbean,
            operation: 'versionComplete(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)',
            arguments: [
                groupId, 
                artifactId, 
                partial, 
                packaging, 
                classifier
            ]
        }, {
            method: 'POST',
            success: function (response) {
                $scope.$apply(function () {
                    deferred.resolve(response.value.sortBy().first(15));
                });
            },
            error: function (response) {
                $scope.$apply(function () {
                    console.log("got back an error: ", response);
                    deferred.reject();
                });
            }
        });
        return deferred.promise;
    }
    Maven.completeVersion = completeVersion;
    function completeArtifactId(mbean, $q, $scope, workspace, jolokia, groupId, partial, packaging, classifier) {
        var deferred = $q.defer();
        jolokia.request({
            type: 'exec',
            mbean: mbean,
            operation: 'artifactIdComplete(java.lang.String, java.lang.String, java.lang.String, java.lang.String)',
            arguments: [
                groupId, 
                partial, 
                packaging, 
                classifier
            ]
        }, {
            method: 'POST',
            success: function (response) {
                $scope.$apply(function () {
                    deferred.resolve(response.value.sortBy().first(15));
                });
            },
            error: function (response) {
                $scope.$apply(function () {
                    console.log("got back an error: ", response);
                    deferred.reject();
                });
            }
        });
        return deferred.promise;
    }
    Maven.completeArtifactId = completeArtifactId;
    function completeGroupId(mbean, $q, $scope, workspace, jolokia, partial, packaging, classifier) {
        if (partial.length < 5) {
            return $q.when([]);
        }
        var deferred = $q.defer();
        jolokia.request({
            type: 'exec',
            mbean: mbean,
            operation: 'groupIdComplete(java.lang.String, java.lang.String, java.lang.String)',
            arguments: [
                partial, 
                packaging, 
                classifier
            ]
        }, {
            method: 'POST',
            success: function (response) {
                $scope.$apply(function () {
                    deferred.resolve(response.value.sortBy().first(15));
                });
            },
            error: function (response) {
                console.log("got back an error: ", response);
                $scope.$apply(function () {
                    deferred.reject();
                });
            }
        });
        return deferred.promise;
    }
    Maven.completeGroupId = completeGroupId;
    function addMavenFunctions($scope, workspace) {
        $scope.detailLink = function (row) {
            var group = row.groupId;
            var artifact = row.artifactId;
            var version = row.version || "";
            var classifier = row.classifier || "";
            var packaging = row.packaging || "";
            if (group && artifact) {
                return "#/maven/artifact/" + group + "/" + artifact + "/" + version + "/" + classifier + "/" + packaging;
            }
            return "";
        };
        $scope.javadocLink = function (row) {
            var group = row.groupId;
            var artifact = row.artifactId;
            var version = row.version;
            if (group && artifact && version) {
                return "javadoc/" + group + ":" + artifact + ":" + version + "/";
            }
            return "";
        };
        $scope.versionsLink = function (row) {
            var group = row.groupId;
            var artifact = row.artifactId;
            var classifier = row.classifier || "";
            var packaging = row.packaging || "";
            if (group && artifact) {
                return "#/maven/versions/" + group + "/" + artifact + "/" + classifier + "/" + packaging;
            }
            return "";
        };
        $scope.dependenciesLink = function (row) {
            var group = row.groupId;
            var artifact = row.artifactId;
            var classifier = row.classifier || "";
            var packaging = row.packaging || "";
            var version = row.version;
            if (group && artifact) {
                return "#/maven/dependencies/" + group + "/" + artifact + "/" + version + "/" + classifier + "/" + packaging;
            }
            return "";
        };
        $scope.hasDependencyMBean = function () {
            var mbean = Maven.getAetherMBean(workspace);
            return angular.isDefined(mbean);
        };
        $scope.sourceLink = function (row) {
            var group = row.groupId;
            var artifact = row.artifactId;
            var version = row.version;
            if (group && artifact && version) {
                return "#/source/index/" + group + ":" + artifact + ":" + version + "/";
            }
            return "";
        };
    }
    Maven.addMavenFunctions = addMavenFunctions;
})(Maven || (Maven = {}));
var Maven;
(function (Maven) {
    var pluginName = 'maven';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'datatable', 
        'tree', 
        'hawtioCore', 
        'hawtio-ui'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/maven/search', {
            templateUrl: 'app/maven/html/search.html'
        }).when('/maven/advancedSearch', {
            templateUrl: 'app/maven/html/advancedSearch.html'
        }).when('/maven/artifact/:group/:artifact/:version/:classifier/:packaging', {
            templateUrl: 'app/maven/html/artifact.html'
        }).when('/maven/artifact/:group/:artifact/:version/:classifier', {
            templateUrl: 'app/maven/html/artifact.html'
        }).when('/maven/artifact/:group/:artifact/:version', {
            templateUrl: 'app/maven/html/artifact.html'
        }).when('/maven/dependencies/:group/:artifact/:version/:classifier/:packaging', {
            templateUrl: 'app/maven/html/dependencies.html'
        }).when('/maven/dependencies/:group/:artifact/:version/:classifier', {
            templateUrl: 'app/maven/html/dependencies.html'
        }).when('/maven/dependencies/:group/:artifact/:version', {
            templateUrl: 'app/maven/html/dependencies.html'
        }).when('/maven/versions/:group/:artifact/:classifier/:packaging', {
            templateUrl: 'app/maven/html/versions.html'
        }).when('/maven/view/:group/:artifact/:version/:classifier/:packaging', {
            templateUrl: 'app/maven/html/view.html'
        }).when('/maven/test', {
            templateUrl: 'app/maven/html/test.html'
        });
    }).run(function ($location, workspace, viewRegistry, helpRegistry) {
        viewRegistry['maven'] = "app/maven/html/layoutMaven.html";
        workspace.topLevelTabs.push({
            content: "Maven",
            title: "Search maven repositories for artifacts",
            isValid: function (workspace) {
                return Maven.getMavenIndexerMBean(workspace);
            },
            href: function () {
                return "#/maven/search";
            },
            isActive: function (workspace) {
                return workspace.isLinkActive("/maven");
            }
        });
        helpRegistry.addUserDoc('maven', 'app/maven/doc/help.md', function () {
            return Maven.getMavenIndexerMBean(workspace) !== null;
        });
        helpRegistry.addDevDoc("maven", 'app/maven/doc/developer.md');
    });
    hawtioPluginLoader.addModule(pluginName);
})(Maven || (Maven = {}));
var Maven;
(function (Maven) {
    function PomXmlController($scope) {
        $scope.mavenPomXml = "\n" + "  <dependency>\n" + "    <groupId>" + orBlank($scope.row.groupId) + "</groupId>\n" + "    <artifactId>" + orBlank($scope.row.artifactId) + "</artifactId>\n" + "    <version>" + orBlank($scope.row.version) + "</version>\n" + "  </dependency>\n";
        function orBlank(text) {
            return text || "";
        }
    }
    Maven.PomXmlController = PomXmlController;
})(Maven || (Maven = {}));
var Maven;
(function (Maven) {
    function SearchController($scope, $location, workspace, jolokia) {
        $scope.artifacts = [];
        $scope.selected = [];
        $scope.done = false;
        $scope.form = {
            searchText: ""
        };
        $scope.search = "";
        $scope.searchForm = 'app/maven/html/searchForm.html';
        Maven.addMavenFunctions($scope, workspace);
        var columnDefs = [
            {
                field: 'groupId',
                displayName: 'Group'
            }, 
            {
                field: 'artifactId',
                displayName: 'Artifact',
                cellTemplate: '<div class="ngCellText" title="Name: {{row.entity.name}}">{{row.entity.artifactId}}</div>'
            }, 
            {
                field: 'version',
                displayName: 'Version',
                cellTemplate: '<div class="ngCellText" title="Name: {{row.entity.name}}"><a ng-href="{{detailLink(row.entity)}}">{{row.entity.version}}</a</div>'
            }
        ];
        $scope.gridOptions = {
            data: 'artifacts',
            displayFooter: true,
            selectedItems: $scope.selected,
            selectWithCheckboxOnly: true,
            columnDefs: columnDefs,
            rowDetailTemplateId: "artifactDetailTemplate",
            filterOptions: {
                filterText: 'search'
            }
        };
        $scope.hasAdvancedSearch = function (form) {
            return form.searchGroup || form.searchArtifact || form.searchVersion || form.searchPackaging || form.searchClassifier || form.searchClassName;
        };
        $scope.doSearch = function () {
            $scope.done = false;
            var mbean = Maven.getMavenIndexerMBean(workspace);
            var form = $scope.form;
            if (mbean) {
                var searchText = form.searchText;
                var kind = form.artifactType;
                if (kind) {
                    if (kind === "className") {
                        jolokia.execute(mbean, "searchClasses", searchText, onSuccess(render));
                    } else {
                        var paths = kind.split('/');
                        var packaging = paths[0];
                        var classifier = paths[1];
                        console.log("Search for: " + form.searchText + " packaging " + packaging + " classifier " + classifier);
                        jolokia.execute(mbean, "searchTextAndPackaging", searchText, packaging, classifier, onSuccess(render));
                    }
                } else if (searchText) {
                    console.log("Search text is: " + form.searchText);
                    jolokia.execute(mbean, "searchText", form.searchText, onSuccess(render));
                } else if ($scope.hasAdvancedSearch(form)) {
                    console.log("Searching for " + form.searchGroup + "/" + form.searchArtifact + "/" + form.searchVersion + "/" + form.searchPackaging + "/" + form.searchClassifier + "/" + form.searchClassName);
                    jolokia.execute(mbean, "search", form.searchGroup || "", form.searchArtifact || "", form.searchVersion || "", form.searchPackaging || "", form.searchClassifier || "", form.searchClassName || "", onSuccess(render));
                }
            } else {
                notification("error", "Could not find the Maven Indexer MBean!");
            }
        };
        function render(response) {
            $scope.done = true;
            $scope.artifacts = response;
            Core.$apply($scope);
        }
    }
    Maven.SearchController = SearchController;
})(Maven || (Maven = {}));
var Maven;
(function (Maven) {
    function TestController($scope, workspace, jolokia, $q, $templateCache) {
        $scope.html = "text/html";
        $scope.someUri = '';
        $scope.uriParts = [];
        $scope.mavenCompletion = $templateCache.get("mavenCompletionTemplate");
        $scope.$watch('someUri', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $scope.uriParts = newValue.split("/");
            }
        });
        $scope.$watch('uriParts', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                if (newValue.length === 1 && newValue.length < oldValue.length) {
                    if (oldValue.last() !== '' && newValue.first().has(oldValue.last())) {
                        var merged = oldValue.first(oldValue.length - 1).include(newValue.first());
                        $scope.someUri = merged.join('/');
                    }
                }
            }
        }, true);
        $scope.doCompletionMaven = function (something) {
            return Maven.completeMavenUri($q, $scope, workspace, jolokia, something);
        };
    }
    Maven.TestController = TestController;
})(Maven || (Maven = {}));
var Maven;
(function (Maven) {
    function VersionsController($scope, $routeParams, workspace, jolokia) {
        $scope.artifacts = [];
        $scope.group = $routeParams["group"] || "";
        $scope.artifact = $routeParams["artifact"] || "";
        $scope.version = "";
        $scope.classifier = $routeParams["classifier"] || "";
        $scope.packaging = $routeParams["packaging"] || "";
        var id = $scope.group + "/" + $scope.artifact;
        if ($scope.classifier) {
            id += "/" + $scope.classifier;
        }
        if ($scope.packaging) {
            id += "/" + $scope.packaging;
        }
        var columnTitle = id + " versions";
        var columnDefs = [
            {
                field: 'versionNumber',
                displayName: columnTitle,
                cellTemplate: '<div class="ngCellText"><a href="#/maven/artifact/{{row.entity.groupId}}/{{row.entity.artifactId}}/{{row.entity.version}}">{{row.entity.version}}</a></div>'
            }
        ];
        $scope.gridOptions = {
            data: 'artifacts',
            displayFooter: true,
            selectedItems: $scope.selected,
            selectWithCheckboxOnly: true,
            columnDefs: columnDefs,
            rowDetailTemplateId: "artifactDetailTemplate",
            sortInfo: {
                field: 'versionNumber',
                direction: 'DESC'
            },
            filterOptions: {
                filterText: 'search'
            }
        };
        Maven.addMavenFunctions($scope, workspace);
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateTableContents, 50);
        });
        $scope.$watch('workspace.selection', function () {
            updateTableContents();
        });
        function updateTableContents() {
            var mbean = Maven.getMavenIndexerMBean(workspace);
            if (mbean) {
                jolokia.execute(mbean, "versionComplete", $scope.group, $scope.artifact, $scope.version, $scope.packaging, $scope.classifier, onSuccess(render));
            } else {
                console.log("No MavenIndexerMBean!");
            }
        }
        function render(response) {
            $scope.artifacts = [];
            angular.forEach(response, function (version) {
                var versionNumberArray = Core.parseVersionNumbers(version);
                var versionNumber = 0;
                for(var i = 0; i <= 4; i++) {
                    var num = (i >= versionNumberArray.length) ? 0 : versionNumberArray[i];
                    versionNumber *= 1000;
                    versionNumber += num;
                }
                $scope.artifacts.push({
                    groupId: $scope.group,
                    artifactId: $scope.artifact,
                    packaging: $scope.packaging,
                    classifier: $scope.classifier,
                    version: version,
                    versionNumber: versionNumber
                });
            });
            Core.$apply($scope);
        }
    }
    Maven.VersionsController = VersionsController;
})(Maven || (Maven = {}));
var Maven;
(function (Maven) {
    function ViewController($scope, $location, workspace, jolokia) {
        $scope.$watch('workspace.tree', function () {
            setTimeout(loadData, 50);
        });
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(loadData, 50);
        });
        function loadData() {
        }
    }
    Maven.ViewController = ViewController;
})(Maven || (Maven = {}));
var OpenEJB;
(function (OpenEJB) {
    var pluginName = 'openejb';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'hawtioCore'
    ]).config(function ($routeProvider) {
    }).run(function ($location, workspace, viewRegistry, helpRegistry) {
        viewRegistry['openojb'] = "app/openejb/html/layoutOpenEJBTree.html";
        helpRegistry.addUserDoc('openejb', 'app/openejb/doc/help.md', function () {
            return workspace.treeContainsDomainAndProperties("openejb");
        });
        workspace.topLevelTabs.push({
            content: "OpenEJB",
            title: "Manage your OpenEJB resources",
            isValid: function (workspace) {
                return workspace.treeContainsDomainAndProperties("openejb");
            },
            href: function () {
                return "#/jmx/attributes?tab=openejb";
            },
            isActive: function (workspace) {
                return workspace.isTopTabActive("openejb");
            }
        });
    });
    hawtioPluginLoader.addModule(pluginName);
})(OpenEJB || (OpenEJB = {}));
var OpenEJB;
(function (OpenEJB) {
    function TreeController($scope, $location, workspace) {
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateSelectionFromURL, 50);
        });
        $scope.$watch('workspace.tree', function () {
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            var children = [];
            var tree = workspace.tree;
            if (tree) {
                var nodes = tree.children;
                angular.forEach(nodes, function (node) {
                    var nodeChildren = node.children;
                    if (node.title.startsWith("openejb") && nodeChildren) {
                        children = children.concat(nodeChildren);
                    }
                });
            }
            var treeElement = $("#openejbTree");
            Jmx.enableTree($scope, $location, workspace, treeElement, children, true);
            setTimeout(updateSelectionFromURL, 50);
        });
        function updateSelectionFromURL() {
            Jmx.updateTreeSelectionFromURL($location, $("#openejbTree"), true);
        }
    }
    OpenEJB.TreeController = TreeController;
})(OpenEJB || (OpenEJB = {}));
var Osgi;
(function (Osgi) {
    function BundleListController($scope, workspace, jolokia) {
        $scope.result = {};
        $scope.bundles = [];
        $scope.bundleUrl = "";
        $scope.display = {
            bundleField: "Name",
            sortField: "Identifier",
            bundleFilter: "",
            startLevelFilter: 0
        };
        $scope.installDisabled = function () {
            return $scope.bundleUrl === "";
        };
        $scope.install = function () {
            jolokia.request({
                type: 'exec',
                mbean: Osgi.getSelectionFrameworkMBean(workspace),
                operation: "installBundle(java.lang.String)",
                arguments: [
                    $scope.bundleUrl
                ]
            }, {
                success: function (response) {
                    var bundleID = response.value;
                    jolokia.request({
                        type: 'exec',
                        mbean: Osgi.getSelectionBundleMBean(workspace),
                        operation: "isFragment(long)",
                        arguments: [
                            bundleID
                        ]
                    }, {
                        success: function (response) {
                            var isFragment = response.value;
                            if (isFragment) {
                                notification("success", "Fragment installed succesfully.");
                                $scope.bundleUrl = "";
                                Core.$apply($scope);
                            } else {
                                jolokia.request({
                                    type: 'exec',
                                    mbean: Osgi.getSelectionFrameworkMBean(workspace),
                                    operation: "startBundle(long)",
                                    arguments: [
                                        bundleID
                                    ]
                                }, {
                                    success: function (response) {
                                        notification("success", "Bundle installed and started successfully.");
                                        $scope.bundleUrl = "";
                                        Core.$apply($scope);
                                    },
                                    error: function (response) {
                                        notification("error", response.error);
                                    }
                                });
                            }
                        },
                        error: function (response) {
                            notification("error", response.error);
                        }
                    });
                },
                error: function (response) {
                    notification("error", response.error);
                }
            });
        };
        $scope.getStateStyle = function (state) {
            return Osgi.getStateStyle("badge", state);
        };
        $scope.getLabel = function (bundleObject) {
            var labelText;
            if ($scope.display.bundleField === "Name") {
                labelText = bundleObject.Name;
                if (labelText === "") {
                    labelText = bundleObject.SymbolicName;
                }
            } else {
                labelText = bundleObject.SymbolicName;
            }
            return labelText;
        };
        $scope.filterBundle = function (bundle) {
            if ($scope.display.startLevelFilter > 0 && bundle.StartLevel < $scope.display.startLevelFilter) {
                return false;
            }
            var labelText = $scope.getLabel(bundle);
            if ($scope.display.bundleFilter && !labelText.toLowerCase().has($scope.display.bundleFilter.toLowerCase())) {
                return false;
            }
            return true;
        };
        function processResponse(response) {
            var value = response['value'];
            var responseJson = angular.toJson(value);
            if ($scope.responseJson !== responseJson) {
                $scope.responseJson = responseJson;
                $scope.bundles = [];
                angular.forEach(value, function (value, key) {
                    var obj = {
                        Identifier: value.Identifier,
                        Name: "",
                        SymbolicName: value.SymbolicName,
                        Fragment: value.Fragment,
                        State: value.State,
                        Version: value.Version,
                        LastModified: new Date(Number(value.LastModified)),
                        Location: value.Location,
                        StartLevel: undefined
                    };
                    if (value.Headers['Bundle-Name']) {
                        obj.Name = value.Headers['Bundle-Name']['Value'];
                    }
                    $scope.bundles.push(obj);
                });
                Core.$apply($scope);
                setTimeout(function () {
                    var requests = [];
                    for(var i = 0; i < $scope.bundles.length; i++) {
                        var b = $scope.bundles[i];
                        requests.push({
                            type: 'exec',
                            mbean: Osgi.getSelectionBundleMBean(workspace),
                            operation: 'getStartLevel(long)',
                            arguments: [
                                b.Identifier
                            ]
                        });
                    }
                    var outstanding = requests.length;
                    jolokia.request(requests, onSuccess(function (response) {
                        var id = response['request']['arguments'].first();
                        if (angular.isDefined(id)) {
                            var bundle = $scope.bundles[id];
                            if (bundle) {
                                Osgi.log.debug("Setting bundle: ", bundle['Identifier'], " start level to: ", response['value']);
                                bundle['StartLevel'] = response['value'];
                            }
                        }
                        outstanding = outstanding - 1;
                        Osgi.log.debug("oustanding responses: ", outstanding);
                        if (outstanding === 0) {
                            Osgi.log.debug("Updating page...");
                            Core.$apply($scope);
                        }
                    }));
                }, 500);
            }
        }
        Core.register(jolokia, $scope, {
            type: 'exec',
            mbean: Osgi.getSelectionBundleMBean(workspace),
            operation: 'listBundles()'
        }, onSuccess(processResponse));
    }
    Osgi.BundleListController = BundleListController;
})(Osgi || (Osgi = {}));
var Osgi;
(function (Osgi) {
    function BundleController($scope, $location, workspace, $routeParams, jolokia) {
        $scope.bundleId = $routeParams.bundleId;
        updateTableContents();
        $scope.showValue = function (key) {
            switch(key) {
                case "Bundle-Name":
                case "Bundle-SymbolicName":
                case "Bundle-Version":
                case "Export-Package":
                case "Import-Package":
                    return false;
                default:
                    return true;
            }
        };
        $scope.executeLoadClass = function (clazz) {
            var mbean = Osgi.getHawtioOSGiToolsMBean(workspace);
            if (mbean) {
                jolokia.request({
                    type: 'exec',
                    mbean: mbean,
                    operation: 'getLoadClassOrigin',
                    arguments: [
                        $scope.bundleId, 
                        clazz
                    ]
                }, {
                    success: function (response) {
                        var divEl = document.getElementById("loadClassResult");
                        var resultBundle = response.value;
                        var style;
                        var resultTxt;
                        if (resultBundle === -1) {
                            style = "";
                            resultTxt = "Class can not be loaded from this bundle.";
                        } else {
                            style = "alert-success";
                            resultTxt = "Class is served from Bundle " + Osgi.bundleLinks(workspace, resultBundle);
                        }
                        divEl.innerHTML += "<div class='alert " + style + "'>" + "<button type='button' class='close' data-dismiss='alert'>&times;</button>" + "Loading class <strong>" + clazz + "</strong> in Bundle " + $scope.bundleId + ". " + resultTxt + "</div>";
                    },
                    error: function (response) {
                        inspectReportError(response);
                    }
                });
            } else {
                inspectReportNoMBeanFound();
            }
        };
        $scope.executeFindResource = function (resource) {
            var mbean = Osgi.getHawtioOSGiToolsMBean(workspace);
            if (mbean) {
                jolokia.request({
                    type: 'exec',
                    mbean: mbean,
                    operation: 'getResourceURL',
                    arguments: [
                        $scope.bundleId, 
                        resource
                    ]
                }, {
                    success: function (response) {
                        var divEl = document.getElementById("loadClassResult");
                        var resultURL = response.value;
                        var style;
                        var resultTxt;
                        if (resultURL === null) {
                            style = "";
                            resultTxt = "Resource can not be found from this bundle.";
                        } else {
                            style = "alert-success";
                            resultTxt = "Resource is available from: " + resultURL;
                        }
                        divEl.innerHTML += "<div class='alert " + style + "'>" + "<button type='button' class='close' data-dismiss='alert'>&times;</button>" + "Finding resource <strong>" + resource + "</strong> in Bundle " + $scope.bundleId + ". " + resultTxt + "</div>";
                    },
                    error: function (response) {
                        inspectReportError(response);
                    }
                });
            } else {
                inspectReportNoMBeanFound();
            }
        };
        $scope.mavenLink = function (row) {
            if (angular.isObject(row)) {
                return Maven.mavenLink(row.Location);
            }
            return "";
        };
        $scope.startBundle = function (bundleId) {
            jolokia.request([
                {
                    type: 'exec',
                    mbean: Osgi.getSelectionFrameworkMBean(workspace),
                    operation: 'startBundle',
                    arguments: [
                        bundleId
                    ]
                }
            ], onSuccess(updateTableContents));
        };
        $scope.stopBundle = function (bundleId) {
            jolokia.request([
                {
                    type: 'exec',
                    mbean: Osgi.getSelectionFrameworkMBean(workspace),
                    operation: 'stopBundle',
                    arguments: [
                        bundleId
                    ]
                }
            ], onSuccess(updateTableContents));
        };
        $scope.updatehBundle = function (bundleId) {
            jolokia.request([
                {
                    type: 'exec',
                    mbean: Osgi.getSelectionFrameworkMBean(workspace),
                    operation: 'updateBundle',
                    arguments: [
                        bundleId
                    ]
                }
            ], onSuccess(updateTableContents));
        };
        $scope.refreshBundle = function (bundleId) {
            jolokia.request([
                {
                    type: 'exec',
                    mbean: Osgi.getSelectionFrameworkMBean(workspace),
                    operation: 'refreshBundle',
                    arguments: [
                        bundleId
                    ]
                }
            ], onSuccess(updateTableContents));
        };
        $scope.uninstallBundle = function (bundleId) {
            jolokia.request([
                {
                    type: 'exec',
                    mbean: Osgi.getSelectionFrameworkMBean(workspace),
                    operation: 'uninstallBundle',
                    arguments: [
                        bundleId
                    ]
                }
            ], onSuccess($location.path("/osgi/bundle-list")));
        };
        function inspectReportNoMBeanFound() {
            var divEl = document.getElementById("loadClassResult");
            divEl.innerHTML += "<div class='alert alert-error'>" + "<button type='button' class='close' data-dismiss='alert'>&times;</button>" + "The hawtio.OSGiTools MBean is not available. Please contact technical support." + "</div>";
        }
        function inspectReportError(response) {
            var divEl = document.getElementById("loadClassResult");
            divEl.innerHTML += "<div class='alert alert-error'>" + "<button type='button' class='close' data-dismiss='alert'>&times;</button>" + "Problem invoking hawtio.OSGiTools MBean. " + response + "</div>";
        }
        function populateTable(response) {
            var values = response.value;
            $scope.bundles = values;
            Osgi.defaultBundleValues(workspace, $scope, values);
            $scope.row = Osgi.findBundle($scope.bundleId, values);
            Core.$apply($scope);
            $('.accordion-body.collapse').hover(function () {
                $(this).css('overflow', 'visible');
            }, function () {
                $(this).css('overflow', 'hidden');
            });
            $("#bsn").tooltip({
                title: readBSNHeaderData($scope.row.Headers["Bundle-SymbolicName"].Value),
                placement: "right"
            });
            createImportPackageSection();
            createExportPackageSection();
            populateServicesSection();
        }
        function createImportPackageSection() {
            var importPackageHeaders = Osgi.parseManifestHeader($scope.row.Headers, "Import-Package");
            for(var pkg in $scope.row.ImportData) {
                var data = importPackageHeaders[pkg];
                var po = "<small><table>" + "<tr><td><strong>Imported Version=</strong>" + $scope.row.ImportData[pkg].ReportedVersion + "</td></tr>";
                if (data !== undefined) {
                    po += formatAttributesAndDirectivesForPopover(data, false);
                    if (importPackageHeaders[pkg]["Dresolution"] !== "optional") {
                        $(document.getElementById("import." + pkg)).addClass("badge-info");
                    }
                } else {
                    $(document.getElementById("import." + pkg)).addClass("badge-important");
                    var reason = $scope.row.Headers["DynamicImport-Package"];
                    if (reason !== undefined) {
                        reason = reason.Value;
                        po += "<tr><td>Dynamic Import. Imported due to:</td></tr>";
                        po += "<tr><td><strong>DynamicImport-Package=</strong>" + reason + "</td></tr>";
                    }
                }
                po += "</table></small>";
                $(document.getElementById("import." + pkg)).popover({
                    title: "attributes and directives",
                    content: po,
                    trigger: "hover",
                    html: true
                });
                importPackageHeaders[pkg] = undefined;
            }
            var unsatisfied = "";
            for(var pkg in importPackageHeaders) {
                if (importPackageHeaders[pkg] === undefined) {
                    continue;
                }
                if ($scope.row.ExportData[pkg] !== undefined) {
                    continue;
                }
                unsatisfied += "<tr><td><div class='less-big badge badge-warning' id='unsatisfied." + pkg + "'>" + pkg + "</div></td></tr>";
            }
            if (unsatisfied !== "") {
                unsatisfied = "<p/><p class='text-warning'>The following optional imports were not satisfied:<table>" + unsatisfied + "</table></p>";
                document.getElementById("unsatisfiedOptionalImports").innerHTML = unsatisfied;
            }
            for(var pkg in importPackageHeaders) {
                if (importPackageHeaders[pkg] === undefined) {
                    continue;
                }
                var po = "<small><table>";
                po += formatAttributesAndDirectivesForPopover(importPackageHeaders[pkg], false);
                po += "</table></small>";
                $(document.getElementById("unsatisfied." + pkg)).popover({
                    title: "attributes and directives",
                    content: po,
                    trigger: "hover",
                    html: true
                });
            }
        }
        function createExportPackageSection() {
            var exportPackageHeaders = Osgi.parseManifestHeader($scope.row.Headers, "Export-Package");
            for(var pkg in $scope.row.ExportData) {
                var po = "<small><table>" + "<tr><td><strong>Exported Version=</strong>" + $scope.row.ExportData[pkg].ReportedVersion + "</td></tr>";
                po += formatAttributesAndDirectivesForPopover(exportPackageHeaders[pkg], true);
                po += "</table></small>";
                $(document.getElementById("export." + pkg)).popover({
                    title: "attributes and directives",
                    content: po,
                    trigger: "hover",
                    html: true
                });
            }
        }
        function populateServicesSection() {
            if (($scope.row.RegisteredServices === undefined || $scope.row.RegisteredServices.length === 0) && ($scope.row.ServicesInUse === undefined || $scope.row.ServicesInUse === 0)) {
                return;
            }
            var mbean = Osgi.getSelectionServiceMBean(workspace);
            if (mbean) {
                jolokia.request({
                    type: 'exec',
                    mbean: mbean,
                    operation: 'listServices()'
                }, onSuccess(updateServices));
            }
        }
        function updateServices(result) {
            var data = result.value;
            for(var id in data) {
                var reg = document.getElementById("registers.service." + id);
                var uses = document.getElementById("uses.service." + id);
                if ((reg === undefined || reg === null) && (uses === undefined || uses === null)) {
                    continue;
                }
                jolokia.request({
                    type: 'exec',
                    mbean: Osgi.getSelectionServiceMBean(workspace),
                    operation: 'getProperties',
                    arguments: [
                        id
                    ]
                }, onSuccess((function (svcId, regEl, usesEl) {
                    return function (resp) {
                        var props = resp.value;
                        var sortedKeys = Object.keys(props).sort();
                        var po = "<small><table>";
                        for(var i = 0; i < sortedKeys.length; i++) {
                            var value = props[sortedKeys[i]];
                            if (value !== undefined) {
                                var fval = value.Value;
                                if (fval.length > 15) {
                                    fval = fval.replace(/[,]/g, ",<br/>&nbsp;&nbsp;");
                                }
                                po += "<tr><td valign='top'>" + sortedKeys[i] + "</td><td>" + fval + "</td></tr>";
                            }
                        }
                        var regBID = data[svcId].BundleIdentifier;
                        po += "<tr><td>Registered&nbsp;by</td><td>Bundle " + regBID + " <div class='less-big label'>" + $scope.bundles[regBID].SymbolicName + "</div></td></tr>";
                        po += "</table></small>";
                        if (regEl !== undefined && regEl !== null) {
                            regEl.innerText = " " + formatServiceName(data[svcId].objectClass);
                            $(regEl).popover({
                                title: "service properties",
                                content: po,
                                trigger: "hover",
                                html: true
                            });
                        }
                        if (usesEl !== undefined && usesEl !== null) {
                            usesEl.innerText = " " + formatServiceName(data[svcId].objectClass);
                            $(usesEl).popover({
                                title: "service properties",
                                content: po,
                                trigger: "hover",
                                html: true
                            });
                        }
                    };
                })(id, reg, uses)));
            }
        }
        function updateTableContents() {
            var mbean = Osgi.getSelectionBundleMBean(workspace);
            if (mbean) {
                jolokia.request({
                    type: 'exec',
                    mbean: mbean,
                    operation: 'listBundles()'
                }, onSuccess(populateTable));
            }
        }
    }
    Osgi.BundleController = BundleController;
    function readBSNHeaderData(header) {
        var idx = header.indexOf(";");
        if (idx <= 0) {
            return "";
        }
        return header.substring(idx + 1).trim();
    }
    Osgi.readBSNHeaderData = readBSNHeaderData;
    function formatAttributesAndDirectivesForPopover(data, skipVersion) {
        var str = "";
        var sortedKeys = Object.keys(data).sort();
        for(var i = 0; i < sortedKeys.length; i++) {
            var da = sortedKeys[i];
            var type = da.charAt(0);
            var separator = "";
            var txtClass;
            if (type === "A") {
                separator = "=";
                txtClass = "text-info";
            }
            if (type === "D") {
                separator = ":=";
                txtClass = "muted";
            }
            if (separator !== "") {
                if (skipVersion) {
                    if (da === "Aversion") {
                        continue;
                    }
                }
                var value = data[da];
                if (value.length > 15) {
                    value = value.replace(/[,]/g, ",<br/>&nbsp;&nbsp;");
                }
                str += "<tr><td><strong class='" + txtClass + "'>" + da.substring(1) + "</strong>" + separator + value + "</td></tr>";
            }
        }
        return str;
    }
    Osgi.formatAttributesAndDirectivesForPopover = formatAttributesAndDirectivesForPopover;
    function formatServiceName(objClass) {
        if (Object.isArray(objClass)) {
            return formatServiceNameArray(objClass);
        }
        var name = objClass.toString();
        var idx = name.lastIndexOf('.');
        return name.substring(idx + 1);
    }
    Osgi.formatServiceName = formatServiceName;
    function formatServiceNameArray(objClass) {
        var rv = [];
        for(var i = 0; i < objClass.length; i++) {
            rv.add(formatServiceName(objClass[i]));
        }
        rv = rv.filter(function (elem, pos, self) {
            return self.indexOf(elem) === pos;
        });
        rv.sort();
        return rv.toString();
    }
})(Osgi || (Osgi = {}));
var Osgi;
(function (Osgi) {
    function BundlesController($scope, workspace, jolokia) {
        $scope.result = {};
        $scope.bundles = [];
        $scope.selected = [];
        $scope.loading = true;
        $scope.bundleUrl = "";
        $scope.installDisabled = function () {
            return $scope.bundleUrl === "";
        };
        var columnDefs = [
            {
                field: 'Identifier',
                displayName: 'Identifier',
                width: "48",
                headerCellTemplate: '<div ng-click="col.sort()" class="ngHeaderSortColumn {{col.headerClass}}" ng-style="{\'cursor\': col.cursor}" ng-class="{ \'ngSorted\': !noSortVisible }"><div class="ngHeaderText colt{{$index}} pagination-centered" title="Identifier"><i class="icon-tag"></i></div><div class="ngSortButtonDown" ng-show="col.showSortButtonDown()"></div><div class="ngSortButtonUp" ng-show="col.showSortButtonUp()"></div></div>'
            }, 
            {
                field: 'State',
                displayName: 'Bundle State',
                width: "24",
                headerCellTemplate: '<div ng-click="col.sort()" class="ngHeaderSortColumn {{col.headerClass}}" ng-style="{\'cursor\': col.cursor}" ng-class="{ \'ngSorted\': !noSortVisible }"><div class="ngHeaderText colt{{$index}} pagination-centered" title="State"><i class="icon-tasks"></i></div><div class="ngSortButtonDown" ng-show="col.showSortButtonDown()"></div><div class="ngSortButtonUp" ng-show="col.showSortButtonUp()"></div></div>',
                cellTemplate: '<div class="ngCellText" title="{{row.getProperty(col.field)}}"><i class="{{row.getProperty(col.field)}}"></i></div>'
            }, 
            {
                field: 'Name',
                displayName: 'Name',
                width: "***",
                cellTemplate: '<div class="ngCellText"><a href="#/osgi/bundle/{{row.entity.Identifier}}?p=container">{{row.getProperty(col.field)}}</a></div>'
            }, 
            {
                field: 'SymbolicName',
                displayName: 'Symbolic Name',
                width: "***",
                cellTemplate: '<div class="ngCellText"><a href="#/osgi/bundle/{{row.entity.Identifier}}?p=container">{{row.getProperty(col.field)}}</a></div>'
            }, 
            {
                field: 'Version',
                displayName: 'Version',
                width: "**"
            }, 
            {
                field: 'Location',
                displayName: 'Update Location',
                width: "***"
            }
        ];
        $scope.gridOptions = {
            data: 'bundles',
            showFilter: false,
            selectedItems: $scope.selected,
            selectWithCheckboxOnly: true,
            columnDefs: columnDefs,
            filterOptions: {
                filterText: ''
            }
        };
        $scope.onResponse = function () {
            jolokia.request({
                type: 'exec',
                mbean: Osgi.getSelectionBundleMBean(workspace),
                operation: 'listBundles()'
            }, {
                success: render,
                error: render
            });
        };
        $scope.controlBundles = function (op) {
            var startBundle = function (response) {
            };
            var ids = $scope.selected.map(function (b) {
                return b.Identifier;
            });
            if (!angular.isArray(ids)) {
                ids = [
                    ids
                ];
            }
            jolokia.request({
                type: 'exec',
                mbean: Osgi.getSelectionFrameworkMBean(workspace),
                operation: op,
                arguments: [
                    ids
                ]
            }, {
                success: $scope.onResponse,
                error: $scope.onResponse
            });
        };
        $scope.stop = function () {
            $scope.controlBundles('stopBundles([J)');
        };
        $scope.start = function () {
            $scope.controlBundles('startBundles([J)');
        };
        $scope.update = function () {
            $scope.controlBundles('updateBundles([J)');
        };
        $scope.refresh = function () {
            $scope.controlBundles('refreshBundles([J)');
        };
        $scope.uninstall = function () {
            $scope.controlBundles('uninstallBundles([J)');
        };
        $scope.install = function () {
            jolokia.request({
                type: 'exec',
                mbean: Osgi.getSelectionFrameworkMBean(workspace),
                operation: "installBundle(java.lang.String)",
                arguments: [
                    $scope.bundleUrl
                ]
            }, {
                success: function (response) {
                    console.log("Got: ", response);
                    $scope.bundleUrl = "";
                    jolokia.request({
                        type: 'exec',
                        mbean: Osgi.getSelectionFrameworkMBean(workspace),
                        operation: "startBundle(long)",
                        arguments: [
                            response.value
                        ]
                    }, {
                        success: $scope.onResponse,
                        error: $scope.onResponse
                    });
                },
                error: function (response) {
                    $scope.bundleUrl = "";
                    $scope.onResponse();
                }
            });
        };
        function render(response) {
            if (!Object.equal($scope.result, response.value)) {
                $scope.selected.length = 0;
                $scope.result = response.value;
                $scope.bundles = [];
                angular.forEach($scope.result, function (value, key) {
                    var obj = {
                        Identifier: value.Identifier,
                        Name: "",
                        SymbolicName: value.SymbolicName,
                        State: value.State,
                        Version: value.Version,
                        LastModified: value.LastModified,
                        Location: value.Location
                    };
                    if (value.Headers['Bundle-Name']) {
                        obj.Name = value.Headers['Bundle-Name']['Value'];
                    }
                    $scope.bundles.push(obj);
                });
                $scope.loading = false;
                Core.$apply($scope);
            }
        }
        Core.register(jolokia, $scope, {
            type: 'exec',
            mbean: Osgi.getSelectionBundleMBean(workspace),
            operation: 'listBundles()'
        }, onSuccess(render));
    }
    Osgi.BundlesController = BundlesController;
})(Osgi || (Osgi = {}));
var Osgi;
(function (Osgi) {
    function ConfigurationsController($scope, $filter, workspace, $templateCache, $compile) {
        var dateFilter = $filter('date');
        $scope.addPidDialog = new Core.Dialog();
        $scope.widget = new TableWidget($scope, workspace, [
            {
                "mDataProp": "PidLink"
            }
        ], {
            rowDetailTemplateId: 'configAdminPidTemplate',
            disableAddColumns: true
        });
        $scope.addPid = function (newPid) {
            $scope.addPidDialog.close();
            var mbean = Osgi.getHawtioConfigAdminMBean(workspace);
            if (mbean) {
                var jolokia = workspace.jolokia;
                jolokia.request({
                    type: "exec",
                    mbean: mbean,
                    operation: "configAdminUpdate",
                    arguments: [
                        newPid, 
                        JSON.stringify({})
                    ]
                }, {
                    error: function (response) {
                        notification("error", response.error);
                    },
                    success: function (response) {
                        notification("success", "Successfully created pid: " + newPid);
                        updateTableContents();
                    }
                });
            }
        };
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateTableContents, 50);
        });
        $scope.$watch('workspace.selection', function () {
            updateTableContents();
        });
        function populateTable(response) {
            var configurations = Osgi.defaultConfigurationValues(workspace, $scope, response.value);
            $scope.widget.populateTable(configurations);
            Core.$apply($scope);
        }
        function updateTableContents() {
            var mbean = Osgi.getSelectionConfigAdminMBean(workspace);
            if (mbean) {
                var jolokia = workspace.jolokia;
                jolokia.request({
                    type: 'exec',
                    mbean: mbean,
                    operation: 'getConfigurations',
                    arguments: [
                        '(service.pid=*)'
                    ]
                }, onSuccess(populateTable));
            }
        }
    }
    Osgi.ConfigurationsController = ConfigurationsController;
})(Osgi || (Osgi = {}));
var Osgi;
(function (Osgi) {
    function FrameworkController($scope, $dialog, workspace) {
        $scope.editDialog = new Core.Dialog();
        updateContents();
        $scope.edit = function (attr, displayName) {
            $scope.editAttr = attr;
            $scope.editDisplayName = displayName;
            $scope.editDialog.open();
        };
        $scope.edited = function (name, displayName, res) {
            $scope.editDialog.close();
            var mbean = Osgi.getSelectionFrameworkMBean(workspace);
            if (mbean) {
                var jolokia = workspace.jolokia;
                jolokia.request({
                    type: 'write',
                    mbean: mbean,
                    attribute: name,
                    value: res
                }, {
                    error: function (response) {
                        editWritten("error", response.error);
                    },
                    success: function (response) {
                        editWritten("success", displayName + " changed to " + res);
                    }
                });
            }
        };
        function editWritten(status, message) {
            notification(status, message);
            updateContents();
        }
        function populatePage(response) {
            $scope.startLevel = response.value.FrameworkStartLevel;
            $scope.initialBundleStartLevel = response.value.InitialBundleStartLevel;
            Core.$apply($scope);
        }
        function updateContents() {
            var mbean = Osgi.getSelectionFrameworkMBean(workspace);
            if (mbean) {
                var jolokia = workspace.jolokia;
                jolokia.request({
                    type: 'read',
                    mbean: mbean
                }, onSuccess(populatePage));
            }
        }
    }
    Osgi.FrameworkController = FrameworkController;
})(Osgi || (Osgi = {}));
var Osgi;
(function (Osgi) {
    var OsgiDataService = (function () {
        function OsgiDataService(workspace, jolokia) {
            this.jolokia = jolokia;
            this.workspace = workspace;
        }
        OsgiDataService.prototype.getBundles = function () {
            var bundles = {};
            var response = this.jolokia.request({
                type: 'exec',
                mbean: Osgi.getSelectionBundleMBean(this.workspace),
                operation: 'listBundles()'
            }, onSuccess(null));
            angular.forEach(response.value, function (value, key) {
                var obj = {
                    Identifier: value.Identifier,
                    Name: "",
                    SymbolicName: value.SymbolicName,
                    Fragment: value.Fragment,
                    State: value.State,
                    Version: value.Version,
                    LastModified: new Date(Number(value.LastModified)),
                    Location: value.Location,
                    StartLevel: undefined,
                    RegisteredServices: value.RegisteredServices,
                    ServicesInUse: value.ServicesInUse
                };
                if (value.Headers['Bundle-Name']) {
                    obj.Name = value.Headers['Bundle-Name']['Value'];
                }
                bundles[value.Identifier] = obj;
            });
            return bundles;
        };
        OsgiDataService.prototype.getServices = function () {
            var services = {};
            var response = this.jolokia.request({
                type: 'exec',
                mbean: Osgi.getSelectionServiceMBean(this.workspace),
                operation: 'listServices()'
            }, onSuccess(null));
            var answer = response.value;
            angular.forEach(answer, function (value, key) {
                services[value.Identifier] = value;
            });
            return services;
        };
        OsgiDataService.prototype.getPackages = function () {
            var packages = {};
            var response = this.jolokia.request({
                type: 'exec',
                mbean: Osgi.getSelectionPackageMBean(this.workspace),
                operation: 'listPackages()'
            }, onSuccess(null));
            var answer = response.value.values;
            answer.forEach(function (value) {
                packages[value.Name + "-" + value.Version] = value;
            });
            return packages;
        };
        return OsgiDataService;
    })();
    Osgi.OsgiDataService = OsgiDataService;    
})(Osgi || (Osgi = {}));
var Osgi;
(function (Osgi) {
    var OsgiGraphBuilder = (function () {
        function OsgiGraphBuilder(osgiDataService, bundleFilter, packageFilter, showServices, showPackages, hideUnused) {
            this.filteredBundles = {};
            this.bundles = null;
            this.services = null;
            this.packages = null;
            this.PREFIX_BUNDLE = "Bundle-";
            this.PREFIX_SVC = "Service-";
            this.PREFIX_PKG = "Package-";
            this.osgiDataService = osgiDataService;
            this.bundleFilter = bundleFilter;
            this.packageFilter = packageFilter;
            this.showServices = showServices;
            this.showPackages = showPackages;
            this.hideUnused = hideUnused;
            this.graphBuilder = new ForceGraph.GraphBuilder();
        }
        OsgiGraphBuilder.prototype.getBundles = function () {
            if (this.bundles == null) {
                this.bundles = this.osgiDataService.getBundles();
            }
            return this.bundles;
        };
        OsgiGraphBuilder.prototype.getServices = function () {
            if (this.services == null) {
                this.services = this.osgiDataService.getServices();
            }
            return this.services;
        };
        OsgiGraphBuilder.prototype.getPackages = function () {
            if (this.packages == null) {
                this.packages = this.osgiDataService.getPackages();
            }
            return this.packages;
        };
        OsgiGraphBuilder.prototype.bundleNodeId = function (bundle) {
            return this.PREFIX_BUNDLE + bundle.Identifier;
        };
        OsgiGraphBuilder.prototype.serviceNodeId = function (service) {
            return this.PREFIX_SVC + service.Identifier;
        };
        OsgiGraphBuilder.prototype.pkgNodeId = function (pkg) {
            return this.PREFIX_PKG + pkg.Name + "-" + pkg.Version;
        };
        OsgiGraphBuilder.prototype.buildSvcNode = function (service) {
            return {
                id: this.serviceNodeId(service),
                name: "" + service.Identifier,
                type: "service",
                used: false,
                popup: {
                    title: "Service [" + service.Identifier + "]",
                    content: (function () {
                        var result = "";
                        if (service != null) {
                            service.objectClass.forEach(function (clazz) {
                                if (result.length > 0) {
                                    result = result + "<br/>";
                                }
                                result = result + clazz;
                            });
                        }
                        return result;
                    })
                }
            };
        };
        OsgiGraphBuilder.prototype.buildBundleNode = function (bundle) {
            return {
                id: this.bundleNodeId(bundle),
                name: bundle.SymbolicName,
                type: "bundle",
                used: false,
                navUrl: "#/osgi/bundle/" + bundle.Identifier,
                popup: {
                    title: "Bundle [" + bundle.Identifier + "]",
                    content: "<p>" + bundle.SymbolicName + "<br/>Version " + bundle.Version + "</p>"
                }
            };
        };
        OsgiGraphBuilder.prototype.buildPackageNode = function (pkg) {
            return {
                id: this.pkgNodeId(pkg),
                name: pkg.Name,
                type: "package",
                used: false,
                popup: {
                    title: "Package [" + pkg.Name + "]",
                    content: "<p>" + pkg.Version + "</p>"
                }
            };
        };
        OsgiGraphBuilder.prototype.exportingBundle = function (pkg) {
            var _this = this;
            var result = null;
            pkg.ExportingBundles.forEach(function (bundleId) {
                if (_this.filteredBundles[_this.PREFIX_BUNDLE + bundleId] != null) {
                    result = bundleId;
                }
            });
            return result;
        };
        OsgiGraphBuilder.prototype.addFilteredBundles = function () {
            var _this = this;
            d3.values(this.getBundles()).forEach(function (bundle) {
                if (_this.bundleFilter == null || _this.bundleFilter == "" || bundle.SymbolicName.startsWith(_this.bundleFilter)) {
                    var bundleNode = _this.buildBundleNode(bundle);
                    _this.filteredBundles[bundleNode.id] = bundle;
                    bundleNode.used = true;
                    _this.graphBuilder.addNode(bundleNode);
                    if (_this.showServices) {
                        var services = _this.getServices();
                        bundle.RegisteredServices.forEach(function (sid) {
                            var svcNode = _this.buildSvcNode(services[sid]);
                            _this.graphBuilder.addNode(svcNode);
                            _this.graphBuilder.addLink(bundleNode.id, svcNode.id, "registered");
                        });
                    }
                }
            });
        };
        OsgiGraphBuilder.prototype.addFilteredServices = function () {
            var _this = this;
            if (this.showServices) {
                d3.values(this.getBundles()).forEach(function (bundle) {
                    bundle.ServicesInUse.forEach(function (sid) {
                        var svcNodeId = _this.PREFIX_SVC + sid;
                        if (_this.graphBuilder.getNode(svcNodeId) != null) {
                            _this.graphBuilder.getNode(svcNodeId).used = true;
                            var bundleNode = _this.graphBuilder.getNode(_this.bundleNodeId(bundle)) || _this.buildBundleNode(bundle);
                            bundleNode.used = true;
                            _this.graphBuilder.addNode(bundleNode);
                            _this.graphBuilder.addLink(svcNodeId, bundleNode.id, "inuse");
                        }
                    });
                });
            }
        };
        OsgiGraphBuilder.prototype.addFilteredPackages = function () {
            var _this = this;
            if (this.showPackages) {
                d3.values(this.getPackages()).forEach(function (pkg) {
                    if (_this.packageFilter == null || _this.packageFilter == "" || pkg.Name.startsWith(_this.packageFilter)) {
                        var exportingId = _this.exportingBundle(pkg);
                        if (exportingId != null) {
                            var bundleNode = _this.graphBuilder.getNode(_this.PREFIX_BUNDLE + exportingId);
                            bundleNode.used = true;
                            var pkgNode = _this.buildPackageNode(pkg);
                            _this.graphBuilder.addNode(pkgNode);
                            _this.graphBuilder.addLink(bundleNode.id, pkgNode.id, "registered");
                            pkg.ImportingBundles.forEach(function (bundleId) {
                                var bundleNode = _this.graphBuilder.getNode(_this.PREFIX_BUNDLE + bundleId) || _this.buildBundleNode(_this.getBundles()[bundleId]);
                                bundleNode.used = true;
                                pkgNode.used = true;
                                _this.graphBuilder.addNode(bundleNode);
                                _this.graphBuilder.addLink(bundleNode.id, pkgNode.id, "inuse");
                            });
                        }
                    }
                });
            }
        };
        OsgiGraphBuilder.prototype.buildGraph = function () {
            var _this = this;
            this.addFilteredBundles();
            this.addFilteredServices();
            this.addFilteredPackages();
            if (this.hideUnused) {
                this.graphBuilder.filterNodes(function (node) {
                    return node.used;
                });
                this.graphBuilder.filterNodes(function (node) {
                    return _this.graphBuilder.hasLinks(node.id);
                });
            }
            return this.graphBuilder.buildGraph();
        };
        return OsgiGraphBuilder;
    })();
    Osgi.OsgiGraphBuilder = OsgiGraphBuilder;    
})(Osgi || (Osgi = {}));
var Osgi;
(function (Osgi) {
    Osgi.log = Logger.get("OSGi");
    function defaultBundleValues(workspace, $scope, values) {
        var allValues = values;
        angular.forEach(values, function (row) {
            row["ImportData"] = parseActualPackages(row["ImportedPackages"]);
            row["ExportData"] = parseActualPackages(row["ExportedPackages"]);
            row["IdentifierLink"] = bundleLinks(workspace, row["Identifier"]);
            row["Hosts"] = labelBundleLinks(workspace, row["Hosts"], allValues);
            row["Fragments"] = labelBundleLinks(workspace, row["Fragments"], allValues);
            row["ImportedPackages"] = row["ImportedPackages"].union([]);
            row["StateStyle"] = getStateStyle("label", row["State"]);
            row["RequiringBundles"] = labelBundleLinks(workspace, row["RequiringBundles"], allValues);
        });
        return values;
    }
    Osgi.defaultBundleValues = defaultBundleValues;
    function getStateStyle(prefix, state) {
        switch(state) {
            case "INSTALLED":
                return prefix + "-important";
            case "RESOLVED":
                return prefix + "-inverse";
            case "STARTING":
                return prefix + "-warning";
            case "ACTIVE":
                return prefix + "-success";
            case "STOPPING":
                return prefix + "-info";
            case "UNINSTALLED":
                return "";
            default:
                return prefix + "-important";
        }
    }
    Osgi.getStateStyle = getStateStyle;
    function defaultServiceValues(workspace, $scope, values) {
        angular.forEach(values, function (row) {
            row["BundleIdentifier"] = bundleLinks(workspace, row["BundleIdentifier"]);
        });
        return values;
    }
    Osgi.defaultServiceValues = defaultServiceValues;
    function defaultPackageValues(workspace, $scope, values) {
        var packages = [];
        function onPackageEntry(packageEntry, row) {
            if (!row) {
                row = packageEntry;
            }
            var name = packageEntry["Name"];
            var version = packageEntry["Version"];
            if (name && !name.startsWith("#")) {
                packageEntry["VersionLink"] = "<a href='" + url("#/osgi/package/" + name + "/" + version + workspace.hash()) + "'>" + version + "</a>";
                var importingBundles = row["ImportingBundles"] || packageEntry["ImportingBundles"];
                var exportingBundles = row["ExportingBundles"] || packageEntry["ExportingBundles"];
                packageEntry["ImportingBundleLinks"] = bundleLinks(workspace, importingBundles);
                packageEntry["ImportingBundleLinks"] = bundleLinks(workspace, importingBundles);
                packageEntry["ExportingBundleLinks"] = bundleLinks(workspace, exportingBundles);
                packages.push(packageEntry);
            }
        }
        var childValues = values.values;
        if (childValues) {
            angular.forEach(childValues, onPackageEntry);
        }
        angular.forEach(values, function (row) {
            angular.forEach(row, function (version) {
                angular.forEach(version, function (packageEntry) {
                    onPackageEntry(packageEntry, row);
                });
            });
        });
        return packages;
    }
    Osgi.defaultPackageValues = defaultPackageValues;
    function defaultConfigurationValues(workspace, $scope, values) {
        var array = [];
        angular.forEach(values, function (row) {
            var map = {};
            map["Pid"] = row[0];
            map["PidLink"] = "<a href='" + url("#/osgi/pid/" + row[0] + workspace.hash()) + "'>" + row[0] + "</a>";
            map["Bundle"] = row[1];
            array.push(map);
        });
        return array;
    }
    Osgi.defaultConfigurationValues = defaultConfigurationValues;
    function parseActualPackages(packages) {
        var result = {};
        for(var i = 0; i < packages.length; i++) {
            var pkg = packages[i];
            var idx = pkg.indexOf(";");
            if (idx > 0) {
                var name = pkg.substring(0, idx);
                var ver = pkg.substring(idx + 1);
                var data = result[name];
                if (data === undefined) {
                    data = {};
                    result[name] = data;
                }
                data["ReportedVersion"] = ver;
            }
        }
        return result;
    }
    Osgi.parseActualPackages = parseActualPackages;
    function parseManifestHeader(headers, name) {
        var result = {};
        var data = {};
        var hdr = headers[name];
        if (hdr === undefined) {
            return result;
        }
        var ephdr = hdr.Value;
        var inPkg = true;
        var inQuotes = false;
        var pkgName = "";
        var daDecl = "";
        for(var i = 0; i < ephdr.length; i++) {
            var c = ephdr[i];
            if (c === '"') {
                inQuotes = !inQuotes;
                continue;
            }
            if (inQuotes) {
                daDecl += c;
                continue;
            }
            if (c === ';') {
                if (inPkg) {
                    inPkg = false;
                } else {
                    handleDADecl(data, daDecl);
                    daDecl = "";
                }
                continue;
            }
            if (c === ',') {
                handleDADecl(data, daDecl);
                result[pkgName] = data;
                data = {};
                pkgName = "";
                daDecl = "";
                inPkg = true;
                continue;
            }
            if (inPkg) {
                pkgName += c;
            } else {
                daDecl += c;
            }
        }
        handleDADecl(data, daDecl);
        result[pkgName] = data;
        return result;
    }
    Osgi.parseManifestHeader = parseManifestHeader;
    function handleDADecl(data, daDecl) {
        var didx = daDecl.indexOf(":=");
        if (didx > 0) {
            data["D" + daDecl.substring(0, didx)] = daDecl.substring(didx + 2);
            return;
        }
        var aidx = daDecl.indexOf("=");
        if (aidx > 0) {
            data["A" + daDecl.substring(0, aidx)] = daDecl.substring(aidx + 1);
            return;
        }
    }
    function toCollection(values) {
        var collection = values;
        if (!angular.isArray(values)) {
            collection = [
                values
            ];
        }
        return collection;
    }
    Osgi.toCollection = toCollection;
    function labelBundleLinks(workspace, values, allValues) {
        var answer = "";
        var sorted = toCollection(values).sort(function (a, b) {
            return a - b;
        });
        angular.forEach(sorted, function (value, key) {
            var prefix = "";
            if (answer.length > 0) {
                prefix = " ";
            }
            var info = allValues[value] || {};
            var labelText = info.SymbolicName;
            answer += prefix + "<a class='label' href='" + url("#/osgi/bundle/" + value + workspace.hash()) + "'>" + labelText + "</a>";
        });
        return answer;
    }
    Osgi.labelBundleLinks = labelBundleLinks;
    function bundleLinks(workspace, values) {
        var answer = "";
        var sorted = toCollection(values).sort(function (a, b) {
            return a - b;
        });
        angular.forEach(sorted, function (value, key) {
            var prefix = "";
            if (answer.length > 0) {
                prefix = " ";
            }
            answer += prefix + "<a class='label' href='" + url("#/osgi/bundle/" + value + workspace.hash()) + "'>" + value + "</a>";
        });
        return answer;
    }
    Osgi.bundleLinks = bundleLinks;
    function pidLinks(workspace, values) {
        var answer = "";
        angular.forEach(toCollection(values), function (value, key) {
            var prefix = "";
            if (answer.length > 0) {
                prefix = " ";
            }
            answer += prefix + "<a href='" + url("#/osgi/bundle/" + value + workspace.hash()) + "'>" + value + "</a>";
        });
        return answer;
    }
    Osgi.pidLinks = pidLinks;
    function findBundle(bundleId, values) {
        var answer = "";
        angular.forEach(values, function (row) {
            var id = row["Identifier"];
            if (bundleId === id.toString()) {
                answer = row;
                return answer;
            }
        });
        return answer;
    }
    Osgi.findBundle = findBundle;
    function getSelectionBundleMBean(workspace) {
        if (workspace) {
            var folder = workspace.tree.navigate("osgi.core", "bundleState");
            return Osgi.findFirstObjectName(folder);
        }
        return null;
    }
    Osgi.getSelectionBundleMBean = getSelectionBundleMBean;
    function findFirstObjectName(node) {
        if (node) {
            var answer = node.objectName;
            if (answer) {
                return answer;
            } else {
                var children = node.children;
                if (children && children.length) {
                    return findFirstObjectName(children[0]);
                }
            }
        }
        return null;
    }
    Osgi.findFirstObjectName = findFirstObjectName;
    function getSelectionFrameworkMBean(workspace) {
        if (workspace) {
            var folder = workspace.tree.navigate("osgi.core", "framework");
            return Osgi.findFirstObjectName(folder);
        }
        return null;
    }
    Osgi.getSelectionFrameworkMBean = getSelectionFrameworkMBean;
    function getSelectionServiceMBean(workspace) {
        if (workspace) {
            var folder = workspace.tree.navigate("osgi.core", "serviceState");
            return Osgi.findFirstObjectName(folder);
        }
        return null;
    }
    Osgi.getSelectionServiceMBean = getSelectionServiceMBean;
    function getSelectionPackageMBean(workspace) {
        if (workspace) {
            var folder = workspace.tree.navigate("osgi.core", "packageState");
            return Osgi.findFirstObjectName(folder);
        }
        return null;
    }
    Osgi.getSelectionPackageMBean = getSelectionPackageMBean;
    function getSelectionConfigAdminMBean(workspace) {
        if (workspace) {
            var folder = workspace.tree.navigate("osgi.compendium", "cm");
            return Osgi.findFirstObjectName(folder);
        }
        return null;
    }
    Osgi.getSelectionConfigAdminMBean = getSelectionConfigAdminMBean;
    function getHawtioOSGiToolsMBean(workspace) {
        if (workspace) {
            var mbeanTypesToDomain = workspace.mbeanTypesToDomain;
            var toolsFacades = mbeanTypesToDomain["OSGiTools"];
            var hawtioFolder = toolsFacades["hawtio"];
            return hawtioFolder["objectName"];
        }
        return null;
    }
    Osgi.getHawtioOSGiToolsMBean = getHawtioOSGiToolsMBean;
    function getHawtioConfigAdminMBean(workspace) {
        if (workspace) {
            var mbeanTypesToDomain = workspace.mbeanTypesToDomain;
            var configAdminFacades = mbeanTypesToDomain["ConfigAdmin"];
            var hawtioFolder = configAdminFacades["hawtio"];
            return hawtioFolder["objectName"];
        }
        return null;
    }
    Osgi.getHawtioConfigAdminMBean = getHawtioConfigAdminMBean;
})(Osgi || (Osgi = {}));
var Osgi;
(function (Osgi) {
    var pluginName = 'osgi';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'ngGrid', 
        'hawtioCore', 
        'hawtio-ui'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/osgi/bundle-list', {
            templateUrl: 'app/osgi/html/bundle-list.html'
        }).when('/osgi/bundles', {
            templateUrl: 'app/osgi/html/bundles.html'
        }).when('/osgi/bundle/:bundleId', {
            templateUrl: 'app/osgi/html/bundle.html'
        }).when('/osgi/services', {
            templateUrl: 'app/osgi/html/services.html'
        }).when('/osgi/packages', {
            templateUrl: 'app/osgi/html/packages.html'
        }).when('/osgi/package/:package/:version', {
            templateUrl: 'app/osgi/html/package.html'
        }).when('/osgi/configurations', {
            templateUrl: 'app/osgi/html/configurations.html'
        }).when('/osgi/pid/:pid', {
            templateUrl: 'app/osgi/html/pid.html'
        }).when('/osgi/fwk', {
            templateUrl: 'app/osgi/html/framework.html'
        }).when('/osgi/dependencies', {
            templateUrl: 'app/osgi/html/svc-dependencies.html',
            reloadOnSearch: false
        });
    }).run(function (workspace, viewRegistry, helpRegistry) {
        viewRegistry['osgi'] = "app/osgi/html/layoutOsgi.html";
        helpRegistry.addUserDoc('osgi', 'app/osgi/doc/help.md', function () {
            return workspace.treeContainsDomainAndProperties("osgi.core");
        });
        workspace.topLevelTabs.push({
            content: "OSGi",
            title: "Visualise and manage the bundles and services in this OSGi container",
            isValid: function (workspace) {
                return workspace.treeContainsDomainAndProperties("osgi.core");
            },
            href: function () {
                return "#/osgi/bundle-list";
            },
            isActive: function (workspace) {
                return workspace.isLinkActive("osgi");
            }
        });
    }).factory('osgiDataService', function (workspace, jolokia) {
        return new Osgi.OsgiDataService(workspace, jolokia);
    });
    hawtioPluginLoader.addModule(pluginName);
})(Osgi || (Osgi = {}));
var Osgi;
(function (Osgi) {
    function PackageController($scope, $filter, workspace, $routeParams) {
        $scope.package = $routeParams.package;
        $scope.version = $routeParams.version;
        updateTableContents();
        function populateTable(response) {
            var packages = Osgi.defaultPackageValues(workspace, $scope, response.value);
            $scope.row = packages.filter({
                "Name": $scope.package,
                "Version": $scope.version
            })[0];
            Core.$apply($scope);
        }
        ;
        function updateTableContents() {
            var mbean = Osgi.getSelectionPackageMBean(workspace);
            if (mbean) {
                var jolokia = workspace.jolokia;
                jolokia.request({
                    type: 'exec',
                    mbean: mbean,
                    operation: 'listPackages'
                }, onSuccess(populateTable));
            }
        }
    }
    Osgi.PackageController = PackageController;
})(Osgi || (Osgi = {}));
var Osgi;
(function (Osgi) {
    function PackagesController($scope, $filter, workspace, $templateCache, $compile) {
        var dateFilter = $filter('date');
        $scope.widget = new TableWidget($scope, workspace, [
            {
                "mDataProp": null,
                "sClass": "control center",
                "sDefaultContent": '<i class="icon-plus"></i>'
            }, 
            {
                "mDataProp": "Name"
            }, 
            {
                "mDataProp": "VersionLink"
            }, 
            {
                "mDataProp": "RemovalPending"
            }
        ], {
            rowDetailTemplateId: 'packageBundlesTemplate',
            disableAddColumns: true
        });
        $scope.$watch('workspace.selection', function () {
            updateTableContents();
        });
        function populateTable(response) {
            var packages = Osgi.defaultPackageValues(workspace, $scope, response.value);
            $scope.widget.populateTable(packages);
            Core.$apply($scope);
        }
        function updateTableContents() {
            var mbean = Osgi.getSelectionPackageMBean(workspace);
            if (mbean) {
                var jolokia = workspace.jolokia;
                jolokia.request({
                    type: 'exec',
                    mbean: mbean,
                    operation: 'listPackages'
                }, onSuccess(populateTable));
            }
        }
    }
    Osgi.PackagesController = PackagesController;
})(Osgi || (Osgi = {}));
var Osgi;
(function (Osgi) {
    function PidController($scope, $filter, workspace, $routeParams) {
        $scope.deletePropDialog = new Core.Dialog();
        $scope.deletePidDialog = new Core.Dialog();
        $scope.addPropertyDialog = new Core.Dialog();
        $scope.pid = $routeParams.pid;
        updateTableContents();
        $scope.pidSave = function () {
            var table = document.getElementById("configValues");
            var els = table.getElementsByClassName("pid-value");
            var props = "";
            var td = {};
            for(var i = 0; i < els.length; i++) {
                props += "\n " + els[i].previousElementSibling.textContent + " " + els[i].textContent;
                td[els[i].previousElementSibling.textContent] = els[i].textContent;
            }
            var mbean = Osgi.getHawtioConfigAdminMBean(workspace);
            if (mbean) {
                var jolokia = workspace.jolokia;
                jolokia.request({
                    type: "exec",
                    mbean: mbean,
                    operation: "configAdminUpdate",
                    arguments: [
                        $scope.pid, 
                        JSON.stringify(td)
                    ]
                }, {
                    error: function (response) {
                        notification("error", response.error);
                    },
                    success: function (response) {
                        enableSave(false);
                        notification("success", "Successfully updated pid: " + $scope.pid);
                    }
                });
            }
        };
        $scope.addPropertyConfirmed = function (key, value) {
            $scope.addPropertyDialog.close();
            $scope.row[key] = {
                Key: key,
                Value: value,
                Type: "String"
            };
            enableSave(true);
        };
        $scope.deletePidProp = function (e) {
            $scope.deleteKey = e.Key;
            $scope.deletePropDialog.open();
        };
        $scope.deletePidPropConfirmed = function () {
            $scope.deletePropDialog.close();
            var cell = document.getElementById("pid." + $scope.deleteKey);
            cell.parentElement.remove();
            enableSave(true);
        };
        $scope.deletePidConfirmed = function () {
            $scope.deletePidDialog.close();
            var mbean = Osgi.getSelectionConfigAdminMBean(workspace);
            if (mbean) {
                var jolokia = workspace.jolokia;
                jolokia.request({
                    type: "exec",
                    mbean: mbean,
                    operation: 'delete',
                    arguments: [
                        $scope.pid
                    ]
                }, {
                    error: function (response) {
                        notification("error", response.error);
                    },
                    success: function (response) {
                        notification("success", "Successfully deleted pid: " + $scope.pid);
                        window.location.href = "#/osgi/configurations";
                    }
                });
            }
        };
        function jmxError(response) {
            notification("error", "Oops: " + response);
        }
        function populateTable(response) {
            $scope.row = response.value;
            Core.$apply($scope);
        }
        ;
        function updateTableContents() {
            var mbean = Osgi.getSelectionConfigAdminMBean(workspace);
            if (mbean) {
                var jolokia = workspace.jolokia;
                jolokia.request({
                    type: 'exec',
                    mbean: mbean,
                    operation: 'getProperties',
                    arguments: [
                        $scope.pid
                    ]
                }, onSuccess(populateTable));
            }
        }
    }
    Osgi.PidController = PidController;
    ;
    function editPidValueCell(e) {
        e.contentEditable = true;
        enableSave(true);
    }
    Osgi.editPidValueCell = editPidValueCell;
    function enableSave(enablement) {
        var saveBtn = document.getElementById("saveButton");
        saveBtn.disabled = !enablement;
    }
})(Osgi || (Osgi = {}));
var Osgi;
(function (Osgi) {
    function ServiceController($scope, $filter, workspace, $templateCache, $compile) {
        var dateFilter = $filter('date');
        $scope.widget = new TableWidget($scope, workspace, [
            {
                "mDataProp": null,
                "sClass": "control center",
                "sDefaultContent": '<i class="icon-plus"></i>'
            }, 
            {
                "mDataProp": "Identifier"
            }, 
            {
                "mDataProp": "BundleIdentifier"
            }, 
            {
                "mDataProp": "objectClass"
            }
        ], {
            rowDetailTemplateId: 'osgiServiceTemplate',
            disableAddColumns: true
        });
        $scope.$watch('workspace.selection', function () {
            var mbean = Osgi.getSelectionServiceMBean(workspace);
            if (mbean) {
                var jolokia = workspace.jolokia;
                jolokia.request({
                    type: 'exec',
                    mbean: mbean,
                    operation: 'listServices()'
                }, onSuccess(populateTable));
            }
        });
        var populateTable = function (response) {
            Osgi.defaultServiceValues(workspace, $scope, response.value);
            $scope.widget.populateTable(response.value);
            Core.$apply($scope);
        };
    }
    Osgi.ServiceController = ServiceController;
})(Osgi || (Osgi = {}));
;
var Osgi;
(function (Osgi) {
    function ServiceDependencyController($scope, $location, $routeParams, workspace, osgiDataService) {
        $scope.init = function () {
            if ($routeParams["bundleFilter"]) {
                $scope.bundleFilter = $routeParams["bundleFilter"];
            } else {
                $scope.bundleFilter = "";
            }
            if ($routeParams["pkgFilter"]) {
                $scope.packageFilter = $routeParams["pkgFilter"];
            } else {
                $scope.packageFilter = "";
            }
            if ($routeParams["view"] == "packages") {
                $scope.selectView = "packages";
            } else {
                $scope.selectView = "services";
            }
            if ($routeParams['hideUnused']) {
                $scope.hideUnused = $routeParams['hideUnused'] == "true";
            } else {
                $scope.hideUnused = true;
            }
        };
        $scope.updateLink = function () {
            var search = $location.search;
            if ($scope.bundleFilter && $scope.bundleFilter != "") {
                search["bundleFilter"] = $scope.bundleFilter;
            } else {
                delete search["bundleFilter"];
            }
            if ($scope.packageFilter && $scope.packageFilter != "") {
                search["pkgFilter"] = $scope.packageFilter;
            } else {
                delete search["pkgFilter"];
            }
            search["view"] = $scope.selectView;
            if ($scope.hideUnused) {
                search["hideUnused"] = "true";
            } else {
                search["hideUnused"] = "false";
            }
            $location.search(search);
        };
        $scope.addToDashboardLink = function () {
            var routeParams = angular.toJson($routeParams);
            var href = "#/osgi/dependencies";
            var title = "OSGi Dependencies";
            var size = angular.toJson({
                size_x: 2,
                size_y: 2
            });
            var addLink = "#/dashboard/add?tab=dashboard" + "&href=" + encodeURIComponent(href) + "&routeParams=" + encodeURIComponent(routeParams) + "&size=" + encodeURIComponent(size) + "&title=" + encodeURIComponent(title);
            return addLink;
        };
        $scope.$on('$routeUpdate', function () {
            var search = $location.search;
            if (search["bundleFilter"]) {
                $scope.bundleFilter = $routeParams["bundleFilter"];
            } else {
                $scope.bundleFilter = "";
            }
            if (search["pkgFilter"]) {
                $scope.packageFilter = $routeParams["pkgFilter"];
            } else {
                $scope.packageFilter = "";
            }
            if (search["view"] == "packages") {
                $scope.selectView = "packages";
            } else {
                $scope.selectView = "services";
            }
            if (search['hideUnused']) {
                $scope.hideUnused = $routeParams['hideUnused'] == "true";
            } else {
                $scope.hideUnused = true;
            }
            $scope.updateLink();
            $scope.updateGraph();
        });
        $scope.updateGraph = function () {
            $scope.updateLink();
            $scope.updatePkgFilter();
            var graphBuilder = new Osgi.OsgiGraphBuilder(osgiDataService, $scope.bundleFilter, $scope.packageFilter, $scope.selectView == "services", $scope.selectView == "packages", $scope.hideUnused);
            $scope.graph = graphBuilder.buildGraph();
            Core.$apply($scope);
        };
        $scope.updatePkgFilter = function () {
            if ($scope.packageFilter == null || $scope.packageFilter == "") {
                $scope.selectView = "services";
                $scope.disablePkg = true;
            } else {
                $scope.disablePkg = false;
            }
        };
        $scope.init();
        $scope.updateGraph();
    }
    Osgi.ServiceDependencyController = ServiceDependencyController;
})(Osgi || (Osgi = {}));
var Perspective;
(function (Perspective) {
    function DefaultPageController($scope, $location, localStorage, workspace, jolokia) {
        var url = Perspective.defaultPage($location, workspace, jolokia, localStorage);
        var path = Core.trimLeading(url, "#");
        if (path) {
            console.log("redirecting to default page: " + path);
            $location.url(path);
        } else {
            console.log("No default page could be chosen!");
        }
    }
    Perspective.DefaultPageController = DefaultPageController;
})(Perspective || (Perspective = {}));
var Perspective;
(function (Perspective) {
    Perspective.metadata = {
        fabric: {
            label: "Fabric",
            isValid: function (workspace) {
                return Fabric.isFMCContainer(workspace);
            },
            lastPage: "#/fabric/containers",
            topLevelTabs: {
                includes: [
                    {
                        href: "#/fabric"
                    }, 
                    {
                        href: "#/wiki/branch/"
                    }, 
                    {
                        href: "#/wiki/profile"
                    }, 
                    {
                        href: "#/dashboard"
                    }, 
                    {
                        href: "#/health"
                    }, 
                    {
                        id: "fabric.insight"
                    }
                ]
            }
        },
        insight: {
            label: "Insight",
            isValid: function (workspace) {
                return Insight.hasInsight(workspace);
            },
            topLevelTabs: {
                includes: [
                    {
                        href: "#/kibanalogs"
                    }, 
                    {
                        href: "#/insight"
                    }, 
                    {
                        href: "#/kibanacamel"
                    }, 
                    {
                        href: "#/camin"
                    }, 
                    {
                        href: "#/eshead"
                    }
                ]
            }
        },
        container: {
            label: "Container",
            lastPage: "#/logs",
            topLevelTabs: {
                excludes: [
                    {
                        href: "#/fabric"
                    }, 
                    {
                        href: "#/insight"
                    }, 
                    {
                        href: "#/camin"
                    }, 
                    {
                        href: "#/kibanalogs"
                    }, 
                    {
                        href: "#/kibanacamel"
                    }, 
                    {
                        href: "#/eshead"
                    }
                ]
            }
        },
        website: {
            label: "WebSite",
            isValid: function (workspace) {
                return Site.sitePluginEnabled && Site.isSiteNavBarValid();
            },
            lastPage: "#/site/doc/index.md",
            topLevelTabs: {
                includes: [
                    {
                        content: "Getting Started",
                        title: "How to get started using hawtio",
                        href: function () {
                            return "#/site/doc/GetStarted.md";
                        },
                        isValid: function () {
                            return Site.isSiteNavBarValid();
                        }
                    }, 
                    {
                        content: "FAQ",
                        title: "Frequently Asked Questions",
                        href: function () {
                            return "#/site/FAQ.md";
                        },
                        isValid: function () {
                            return Site.isSiteNavBarValid();
                        }
                    }, 
                    {
                        content: "User Guide",
                        title: "All the docs on using hawtio",
                        href: function () {
                            return "#/site/doc/index.md";
                        },
                        isValid: function () {
                            return Site.isSiteNavBarValid();
                        }
                    }, 
                    {
                        content: "Community",
                        title: "Come on in and join our community!",
                        href: function () {
                            return "#/site/doc/Community.html";
                        },
                        isValid: function () {
                            return Site.isSiteNavBarValid();
                        }
                    }, 
                    {
                        content: "Developers",
                        title: "Resources for developers if you want to hack on hawtio or provide your own plugins",
                        href: function () {
                            return "#/site/doc/developers/index.md";
                        },
                        isValid: function () {
                            return Site.isSiteNavBarValid();
                        }
                    }, 
                    {
                        content: "github",
                        title: "Hawtio's source code and issue tracker",
                        href: function () {
                            return "https://github.com/hawtio/hawtio";
                        },
                        isValid: function () {
                            return Site.isSiteNavBarValid();
                        }
                    }
                ]
            }
        }
    };
})(Perspective || (Perspective = {}));
var Perspective;
(function (Perspective) {
    Perspective.log = Logger.get("Perspective");
    Perspective.perspectiveSearchId = "p";
    Perspective.defaultPerspective = null;
    Perspective.defaultPageLocation = null;
    function currentPerspectiveId($location, workspace, jolokia, localStorage) {
        var perspective = $location.search()[Perspective.perspectiveSearchId];
        if (!perspective) {
            perspective = Perspective.choosePerspective($location, workspace, jolokia, localStorage);
        }
        return perspective;
    }
    Perspective.currentPerspectiveId = currentPerspectiveId;
    function getPerspectives($location, workspace, jolokia, localStorage) {
        var perspectives = [];
        angular.forEach(Perspective.metadata, function (perspective, key) {
            if (isValidFunction(workspace, perspective.isValid)) {
                if (!perspective.label) {
                    perspective.label = key;
                }
                if (!perspective.title) {
                    perspective.title = perspective.label;
                }
                perspective.id = key;
                perspectives.push(perspective);
            }
        });
        return perspectives;
    }
    Perspective.getPerspectives = getPerspectives;
    function topLevelTabsForPerspectiveId(workspace, perspective) {
        var data = perspective ? Perspective.metadata[perspective] : null;
        var answer = [];
        if (!data) {
            answer = workspace.topLevelTabs;
        } else {
            var topLevelTabs = data.topLevelTabs;
            var list = topLevelTabs.includes || topLevelTabs.excludes;
            angular.forEach(list, function (tabSpec) {
                var href = tabSpec.href;
                var id = tabSpec.id;
                var rhref = tabSpec.rhref;
                if (href) {
                    var hrefValue = href;
                    if (angular.isFunction(href)) {
                        hrefValue = href();
                    }
                    var tab = workspace.topLevelTabs.find(function (t) {
                        var thref = t.href();
                        return thref && thref.startsWith(hrefValue);
                    });
                    if (!tab && !id && tabSpec.content) {
                        tab = tabSpec;
                    }
                    if (tab) {
                        answer.push(tab);
                    }
                } else if (id) {
                    var tab = workspace.topLevelTabs.find(function (t) {
                        var tid = t.id;
                        return tid && tid === id;
                    });
                    if (tab) {
                        answer.push(tab);
                    }
                } else if (rhref) {
                    var tab = workspace.topLevelTabs.find(function (t) {
                        var thref = t.href();
                        return thref && thref.match(rhref);
                    });
                    if (tab) {
                        answer.push(tab);
                    }
                }
            });
            if (!topLevelTabs.includes) {
                answer = workspace.topLevelTabs.subtract(answer);
            }
        }
        return answer;
    }
    function topLevelTabs($location, workspace, jolokia, localStorage) {
        var perspective = currentPerspectiveId($location, workspace, jolokia, localStorage);
        return topLevelTabsForPerspectiveId(workspace, perspective);
    }
    Perspective.topLevelTabs = topLevelTabs;
    function choosePerspective($location, workspace, jolokia, localStorage) {
        var inFMC = Fabric.isFMCContainer(workspace);
        if (inFMC) {
            var url = $location.url();
            Perspective.log.debug("Checking url: ", url);
            if (url.startsWith("/fabric") || url.startsWith("/dashboard") || (url.startsWith("/wiki") && url.has("/fabric/profiles")) || (url.startsWith("/wiki") && url.has("/editFeatures"))) {
                return "fabric";
            }
        }
        return Perspective.defaultPerspective || "container";
    }
    Perspective.choosePerspective = choosePerspective;
    function defaultPage($location, workspace, jolokia, localStorage) {
        var answer = Perspective.defaultPageLocation;
        if (!answer && $location && workspace) {
            var topLevelTabs = Perspective.topLevelTabs($location, workspace, jolokia, localStorage);
            angular.forEach(topLevelTabs, function (tab) {
                var href = tab.href();
                if (href && !answer) {
                    if (isValidFunction(workspace, tab.isValid)) {
                        answer = Core.trimLeading(href, "#");
                    }
                }
            });
        }
        return answer || '/help/index';
    }
    Perspective.defaultPage = defaultPage;
    function isValidFunction(workspace, validFn) {
        return !validFn || validFn(workspace);
    }
})(Perspective || (Perspective = {}));
var Perspective;
(function (Perspective) {
    var pluginName = 'perspective';
    angular.module(pluginName, [
        'hawtioCore'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/perspective/defaultPage', {
            templateUrl: 'app/perspective/html/defaultPage.html',
            controller: Perspective.DefaultPageController
        });
    }).run(function ($location, workspace, viewRegistry, layoutFull) {
        viewRegistry['perspective'] = layoutFull;
    });
    hawtioPluginLoader.addModule(pluginName);
})(Perspective || (Perspective = {}));
var Site;
(function (Site) {
    function BookController($scope, $routeParams, $location, $compile, $http, fileExtensionTypeRegistry) {
        var log = Logger.get("Site");
        var pageId = $routeParams["page"];
        if (!pageId) {
            pageId = "README.md";
        }
        if (!pageId.startsWith("/") && pageId.indexOf(":/") < 0 && pageId.indexOf("app/site/") < 0) {
            pageId = "app/site/" + pageId;
        }
        $scope.pageId = pageId;
        log.info("Loading page '" + $scope.pageId + "'");
        $http.get($scope.pageId).success(onResults);
        function onResults(contents, status, headers, config) {
            $scope.contents = contents;
            $scope.html = contents;
            var format = Wiki.fileFormat($scope.pageId, fileExtensionTypeRegistry) || "markdown";
            if ("markdown" === format) {
                $scope.html = contents ? marked(contents) : "";
            } else if (format && format.startsWith("html")) {
                $scope.html = contents;
            } else {
            }
            $compile($scope.html)($scope);
            Core.$apply($scope);
        }
    }
    Site.BookController = BookController;
})(Site || (Site = {}));
var Site;
(function (Site) {
    function IndexController($scope, $location) {
        $scope.slideInterval = 5000;
    }
    Site.IndexController = IndexController;
})(Site || (Site = {}));
var Site;
(function (Site) {
    Site.sitePluginEnabled = false;
    function isSiteNavBarValid() {
        return Site.sitePluginEnabled;
    }
    Site.isSiteNavBarValid = isSiteNavBarValid;
})(Site || (Site = {}));
var Site;
(function (Site) {
    var pluginName = 'site';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'ngGrid', 
        'datatable', 
        'hawtioCore'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/site', {
            templateUrl: 'app/site/html/index.html'
        }).when('/site/', {
            templateUrl: 'app/site/html/index.html'
        }).when('/site/*page', {
            templateUrl: 'app/site/html/book.html'
        });
    }).run(function ($location, workspace, viewRegistry, layoutFull, helpRegistry) {
        viewRegistry[pluginName] = layoutFull;
        workspace.topLevelTabs.push({
            content: "Site",
            title: "View the documentation for Hawtio",
            isValid: function (workspace) {
                return false;
            },
            href: function () {
                return "#/site";
            }
        });
    });
    hawtioPluginLoader.addModule(pluginName);
})(Site || (Site = {}));
var Source;
(function (Source) {
    function IndexController($scope, $location, $routeParams, workspace, jolokia) {
        $scope.pageId = Wiki.pageId($routeParams, $location);
        $scope.mavenCoords = $routeParams["mavenCoords"];
        var fileName = $scope.pageId;
        if (fileName === '/') {
            fileName = undefined;
        }
        $scope.loadingMessage = "Loading source code from artifacts <b>" + $scope.mavenCoords + "</b>";
        createBreadcrumbs();
        $scope.setFileName = function (breadcrumb) {
            fileName = Core.trimLeading(breadcrumb.fileName, "/");
            fileName = Core.trimLeading(fileName, "/");
            console.log("selected fileName '" + fileName + "'");
            createBreadcrumbs();
            filterFileNames();
        };
        $scope.$watch('workspace.tree', function (newValue, oldValue) {
            if (!$scope.git && Git.getGitMBean(workspace)) {
                setTimeout(maybeUpdateView, 50);
            }
        });
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(maybeUpdateView, 50);
        });
        function filterFileNames() {
            if (fileName) {
                $scope.sourceFiles = $scope.allSourceFiles.filter(function (n) {
                    return n && n.startsWith(fileName);
                }).map(function (n) {
                    return n.substring(fileName.length + 1);
                }).filter(function (n) {
                    return n;
                });
            } else {
                $scope.sourceFiles = $scope.allSourceFiles;
            }
        }
        $scope.sourceLinks = function (aFile) {
            var name = aFile;
            var paths = null;
            var idx = aFile.lastIndexOf('/');
            if (idx > 0) {
                name = aFile.substring(idx + 1);
                paths = aFile.substring(0, idx);
            }
            var answer = "";
            var fullName = fileName || "";
            if (paths) {
                angular.forEach(paths.split("/"), function (path) {
                    if (fullName) {
                        fullName += "/";
                    }
                    fullName += path;
                    answer += "<a href='#/source/index/" + $scope.mavenCoords + "/" + fullName + "'>" + path + "</a>/";
                });
            }
            answer += "<a href='#/source/view/" + $scope.mavenCoords + "/" + fullName + "/" + name + "'>" + name + "</a>";
            return answer;
        };
        function createBreadcrumbs() {
            $scope.breadcrumbs = Source.createBreadcrumbLinks($scope.mavenCoords, fileName);
            angular.forEach($scope.breadcrumbs, function (breadcrumb) {
                breadcrumb.active = false;
            });
            $scope.breadcrumbs.last().active = true;
        }
        function viewContents(response) {
            if (response) {
                $scope.allSourceFiles = response.split("\n").map(function (n) {
                    return n.trim();
                }).filter(function (n) {
                    return n;
                });
            } else {
                $scope.allSourceFiles = [];
            }
            filterFileNames();
            $scope.loadingMessage = null;
            Core.$apply($scope);
        }
        function updateView() {
            if (!$scope.mavenCoords) {
                return;
            }
            var mbean = Source.getInsightMBean(workspace);
            Source.log.debug("In update view, mbean: ", mbean);
            if (mbean) {
                jolokia.execute(mbean, "getSource", $scope.mavenCoords, null, "/", {
                    success: viewContents,
                    error: function (response) {
                        Source.log.error("Failed to download the source code for the maven artifact: ", $scope.mavenCoords);
                        Source.log.info("Stack trace: ", response.stacktrace);
                        $scope.loadingMessage = "Could not download index, please see console for details";
                        Core.$apply($scope);
                    }
                });
            }
        }
        var maybeUpdateView = Core.throttled(updateView, 1000);
        setTimeout(maybeUpdateView, 50);
    }
    Source.IndexController = IndexController;
})(Source || (Source = {}));
var Source;
(function (Source) {
    function JavaDocController($scope, $location, $routeParams, workspace, fileExtensionTypeRegistry, jolokia) {
        $scope.pageId = Wiki.pageId($routeParams, $location);
        var mavenCoords = $routeParams["mavenCoords"];
        var fileName = $scope.pageId;
        $scope.loadingMessage = "Loading javadoc code for file <b>" + fileName + "</b> from artifacts <b>" + mavenCoords + "</b>";
        $scope.breadcrumbs = [];
        $scope.$watch('workspace.tree', function () {
            if (!$scope.git && Git.getGitMBean(workspace)) {
                setTimeout(updateView, 50);
            }
        });
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateView, 50);
        });
        function viewContents(response) {
            $scope.source = response;
            $scope.loadingMessage = null;
            if (!response) {
                var time = new Date().getTime();
                if (!$scope.lastErrorTime || time - $scope.lastErrorTime > 3000) {
                    $scope.lastErrorTime = time;
                    notification("error", "Could not download the source code for the maven artifacts: " + mavenCoords);
                }
            }
            Core.$apply($scope);
        }
        function updateView() {
            var mbean = Source.getInsightMBean(workspace);
            if (mbean) {
                jolokia.execute(mbean, "getJavaDoc", mavenCoords, fileName, onSuccess(viewContents));
            }
        }
    }
    Source.JavaDocController = JavaDocController;
})(Source || (Source = {}));
var Source;
(function (Source) {
    function SourceController($scope, $location, $routeParams, workspace, fileExtensionTypeRegistry, jolokia) {
        $scope.pageId = Wiki.pageId($routeParams, $location);
        $scope.format = Wiki.fileFormat($scope.pageId, fileExtensionTypeRegistry);
        var lineNumber = $location.search()["line"] || 1;
        var mavenCoords = $routeParams["mavenCoords"];
        var className = $routeParams["className"] || "";
        var fileName = $scope.pageId || "/";
        var classNamePath = className.replace(/\./g, '/');
        $scope.loadingMessage = "Loading source code for class <b>" + className + "</b> from artifacts <b>" + mavenCoords + "</b>";
        $scope.breadcrumbs = [];
        var idx = fileName.lastIndexOf('/');
        var path = "/";
        var name = fileName;
        if (idx > 0) {
            path = fileName.substring(0, idx);
            name = fileName.substring(idx + 1);
        } else if (className && className.indexOf('.') > 0) {
            path = classNamePath;
            idx = path.lastIndexOf('/');
            if (idx > 0) {
                name = path.substring(idx + 1);
                path = path.substring(0, idx);
            }
        }
        $scope.breadcrumbs = Source.createBreadcrumbLinks(mavenCoords, path);
        $scope.breadcrumbs.push({
            href: $location.url(),
            name: name,
            active: true
        });
        $scope.javaDocLink = function () {
            var path = classNamePath;
            if (!path && fileName && fileName.endsWith(".java")) {
                path = fileName.substring(0, fileName.length - 5);
            }
            if (path) {
                return "javadoc/" + mavenCoords + "/" + path + ".html";
            }
            return null;
        };
        var options = {
            readOnly: true,
            mode: $scope.format,
            lineNumbers: true,
            onChange: function (codeMirror) {
                if (codeMirror) {
                    if (!$scope.codeMirror) {
                        lineNumber -= 1;
                        var lineText = codeMirror.getLine(lineNumber);
                        var endChar = (lineText) ? lineText.length : 1000;
                        var start = {
                            line: lineNumber,
                            ch: 0
                        };
                        var end = {
                            line: lineNumber,
                            ch: endChar
                        };
                        codeMirror.scrollIntoView(start);
                        codeMirror.setCursor(start);
                        codeMirror.setSelection(start, end);
                        codeMirror.refresh();
                        codeMirror.focus();
                    }
                    $scope.codeMirror = codeMirror;
                }
            }
        };
        $scope.codeMirrorOptions = CodeEditor.createEditorSettings(options);
        $scope.onChange = function (codeMirror) {
            Source.log.debug("codeMirror: ", codeMirror);
            if (codeMirror) {
                lineNumber -= 1;
                var lineText = codeMirror.getLine(lineNumber);
                var endChar = (lineText) ? lineText.length : 1000;
                var start = {
                    line: lineNumber,
                    ch: 0
                };
                var end = {
                    line: lineNumber,
                    ch: endChar
                };
                codeMirror.scrollIntoView(start);
                codeMirror.setCursor(start);
                codeMirror.setSelection(start, end);
                codeMirror.refresh();
                codeMirror.focus();
            }
        };
        $scope.$watch('workspace.tree', function (oldValue, newValue) {
            if (!$scope.git && Git.getGitMBean(workspace)) {
                setTimeout(maybeUpdateView, 50);
            }
        });
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(maybeUpdateView, 50);
        });
        function viewContents(response) {
            $scope.source = response;
            $scope.loadingMessage = null;
            Core.$apply($scope);
        }
        function updateView() {
            var mbean = Source.getInsightMBean(workspace);
            if (mbean) {
                jolokia.execute(mbean, "getSource", mavenCoords, className, fileName, {
                    success: viewContents,
                    error: function (response) {
                        Source.log.error("Failed to download the source code for the maven artifact: ", mavenCoords);
                        Source.log.info("Stack trace: ", response.stacktrace);
                        $scope.loadingMessage = "Could not download file, please see console for details";
                        Core.$apply($scope);
                    }
                });
            }
        }
        var maybeUpdateView = Core.throttled(updateView, 1000);
        setTimeout(maybeUpdateView, 50);
    }
    Source.SourceController = SourceController;
})(Source || (Source = {}));
var Source;
(function (Source) {
    Source.log = Logger.get("Source");
    function getInsightMBean(workspace) {
        var mavenStuff = workspace.mbeanTypesToDomain["LogQuery"] || {};
        var insight = mavenStuff["org.fusesource.insight"] || {};
        var mbean = insight.objectName;
        return mbean;
    }
    Source.getInsightMBean = getInsightMBean;
    function createBreadcrumbLinks(mavenCoords, pathName) {
        var linkPrefix = "#/source/index/" + mavenCoords;
        var answer = [
            {
                href: linkPrefix,
                name: "root"
            }
        ];
        if (pathName) {
            var pathNames = pathName.split("/");
            var fullPath = "";
            angular.forEach(pathNames, function (path) {
                fullPath += "/" + path;
                var href = linkPrefix + fullPath;
                if (!path.isBlank()) {
                    answer.push({
                        href: href,
                        name: path || "/",
                        fileName: "/" + fullPath
                    });
                }
            });
        }
        return answer;
    }
    Source.createBreadcrumbLinks = createBreadcrumbLinks;
})(Source || (Source = {}));
var Source;
(function (Source) {
    var pluginName = 'source';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'hawtioCore', 
        'wiki'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/source/index/:mavenCoords', {
            templateUrl: 'app/source/html/index.html'
        }).when('/source/index/:mavenCoords/*page', {
            templateUrl: 'app/source/html/index.html'
        }).when('/source/view/:mavenCoords/class/:className/*page', {
            templateUrl: 'app/source/html/source.html'
        }).when('/source/view/:mavenCoords/*page', {
            templateUrl: 'app/source/html/source.html'
        }).when('/source/javadoc/:mavenCoords/*page', {
            templateUrl: 'app/source/html/javadoc.html'
        });
    }).run(function ($location, workspace, viewRegistry, jolokia, localStorage, layoutFull, helpRegistry) {
        viewRegistry['source'] = layoutFull;
        helpRegistry.addUserDoc('source', 'app/source/html/help.md');
    });
    hawtioPluginLoader.addModule(pluginName);
})(Source || (Source = {}));
var Tomcat;
(function (Tomcat) {
    function ConnectorsController($scope, $location, workspace, jolokia) {
        var stateTemplate = '<div class="ngCellText pagination-centered" title="{{row.getProperty(col.field)}}"><i class="{{row.getProperty(col.field) | tomcatIconClass}}"></i></div>';
        $scope.connectors = [];
        $scope.selected = [];
        var columnDefs = [
            {
                field: 'stateName',
                displayName: 'State',
                cellTemplate: stateTemplate,
                width: 56,
                minWidth: 56,
                maxWidth: 56,
                resizable: false
            }, 
            {
                field: 'port',
                displayName: 'Port',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'scheme',
                displayName: 'Scheme',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'protocol',
                displayName: 'Protocol',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'secure',
                displayName: 'Secure',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'connectionLinger',
                displayName: 'Connection Linger',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'connectionTimeout',
                displayName: 'Connection Timeout',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'keepAliveTimeout',
                displayName: 'Keep Alive Timeout',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'minSpareThreads',
                displayName: 'Minimum Threads',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'maxThreads',
                displayName: 'Maximum Threads',
                cellFilter: null,
                width: "*",
                resizable: true
            }
        ];
        $scope.gridOptions = {
            data: 'connectors',
            displayFooter: true,
            selectedItems: $scope.selected,
            selectWithCheckboxOnly: true,
            columnDefs: columnDefs,
            filterOptions: {
                filterText: ''
            }
        };
        function render(response) {
            response = Tomcat.filerTomcatOrCatalina(response);
            $scope.connectors = [];
            $scope.selected.length = 0;
            function onAttributes(response) {
                var obj = response.value;
                if (obj) {
                    obj.mbean = response.request.mbean;
                    $scope.connectors.push(obj);
                    Core.$apply($scope);
                }
            }
            angular.forEach(response, function (value, key) {
                var mbean = value;
                jolokia.request({
                    type: "read",
                    mbean: mbean,
                    attribute: [
                        "scheme", 
                        "port", 
                        "protocol", 
                        "secure", 
                        "connectionLinger", 
                        "connectionTimeout", 
                        "keepAliveTimeout", 
                        "minSpareThreads", 
                        "maxThreads", 
                        "stateName"
                    ]
                }, onSuccess(onAttributes));
            });
            Core.$apply($scope);
        }
        ;
        $scope.controlConnector = function (op) {
            var ids = $scope.selected.map(function (b) {
                return b.mbean;
            });
            if (!angular.isArray(ids)) {
                ids = [
                    ids
                ];
            }
            ids.forEach(function (id) {
                jolokia.request({
                    type: 'exec',
                    mbean: id,
                    operation: op,
                    arguments: null
                }, onSuccess($scope.onResponse, {
                    error: $scope.onResponse
                }));
            });
        };
        $scope.stop = function () {
            $scope.controlConnector('stop');
        };
        $scope.start = function () {
            $scope.controlConnector('start');
        };
        $scope.destroy = function () {
            $scope.controlConnector('destroy');
        };
        $scope.onResponse = function (response) {
            loadData();
        };
        $scope.$on('jmxTreeUpdated', reloadFunction);
        $scope.$watch('workspace.tree', reloadFunction);
        function reloadFunction() {
            setTimeout(loadData, 50);
        }
        function loadData() {
            console.log("Loading tomcat connector data...");
            jolokia.search("Catalina:type=Connector,*", onSuccess(render));
        }
    }
    Tomcat.ConnectorsController = ConnectorsController;
})(Tomcat || (Tomcat = {}));
var Tomcat;
(function (Tomcat) {
    function SessionsController($scope, $location, workspace, jolokia) {
        var stateTemplate = '<div class="ngCellText pagination-centered" title="{{row.getProperty(col.field)}}"><i class="{{row.getProperty(col.field) | tomcatIconClass}}"></i></div>';
        $scope.sessions = [];
        $scope.search = "";
        var columnDefs = [
            {
                field: 'stateName',
                displayName: 'State',
                cellTemplate: stateTemplate,
                width: 56,
                minWidth: 56,
                maxWidth: 56,
                resizable: false
            }, 
            {
                field: 'path',
                displayName: 'Context-Path',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'activeSessions',
                displayName: 'Active Sessions',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'expiredSessions',
                displayName: 'Expired Sessions',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'rejectedSessions',
                displayName: 'Rejected Sessions',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'maxActive',
                displayName: 'Max Active Sessions',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'maxActiveSessions',
                displayName: 'Max Active Sessions Allowed',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'maxInactiveInterval',
                displayName: 'Max Inactive Interval',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'sessionCounter',
                displayName: 'Session Counter',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'sessionCreateRate',
                displayName: 'Session Create Rate',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'sessionExpireRate',
                displayName: 'Session Expire Rate',
                cellFilter: null,
                width: "*",
                resizable: true
            }
        ];
        $scope.gridOptions = {
            data: 'sessions',
            displayFooter: false,
            displaySelectionCheckbox: false,
            canSelectRows: false,
            columnDefs: columnDefs,
            filterOptions: {
                filterText: ''
            }
        };
        function render(response) {
            response = Tomcat.filerTomcatOrCatalina(response);
            $scope.sessions = [];
            function onAttributes(response) {
                var obj = response.value;
                if (obj) {
                    obj.mbean = response.request.mbean;
                    var mbean = obj.mbean;
                    if (mbean) {
                        var context = mbean.toString().split(",")[1];
                        if (context) {
                            if (context.toString().indexOf("path=") !== -1) {
                                obj.path = context.toString().substr(5);
                            } else {
                                obj.path = context.toString().substr(9);
                            }
                        } else {
                            obj.path = "";
                        }
                        $scope.sessions.push(obj);
                        Core.$apply($scope);
                    }
                }
            }
            angular.forEach(response, function (value, key) {
                var mbean = value;
                jolokia.request({
                    type: "read",
                    mbean: mbean
                }, onSuccess(onAttributes));
            });
            Core.$apply($scope);
        }
        ;
        $scope.$on('jmxTreeUpdated', reloadFunction);
        $scope.$watch('workspace.tree', reloadFunction);
        function reloadFunction() {
            setTimeout(loadData, 50);
        }
        function loadData() {
            console.log("Loading tomcat session data...");
            jolokia.search("*:type=Manager,*", onSuccess(render));
        }
    }
    Tomcat.SessionsController = SessionsController;
})(Tomcat || (Tomcat = {}));
var Tomcat;
(function (Tomcat) {
    function TomcatController($scope, $location, workspace, jolokia) {
        var stateTemplate = '<div class="ngCellText pagination-centered" title="{{row.getProperty(col.field)}}"><i class="{{row.getProperty(col.field) | tomcatIconClass}}"></i></div>';
        $scope.uninstallDialog = new Core.Dialog();
        $scope.webapps = [];
        $scope.selected = [];
        var columnDefsTomcat5 = [
            {
                field: 'state',
                displayName: 'State',
                cellTemplate: stateTemplate,
                width: 56,
                minWidth: 56,
                maxWidth: 56,
                resizable: false
            }, 
            {
                field: 'path',
                displayName: 'Context-Path',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'startTime',
                displayName: 'Start Time',
                cellFilter: null,
                width: "*",
                resizable: true
            }
        ];
        var columnDefsTomcat6 = [
            {
                field: 'stateName',
                displayName: 'State',
                cellTemplate: stateTemplate,
                width: 56,
                minWidth: 56,
                maxWidth: 56,
                resizable: false
            }, 
            {
                field: 'path',
                displayName: 'Context-Path',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'startTime',
                displayName: 'Start Time',
                cellFilter: null,
                width: "*",
                resizable: true
            }
        ];
        var columnDefsTomcat7 = [
            {
                field: 'stateName',
                displayName: 'State',
                cellTemplate: stateTemplate,
                width: 56,
                minWidth: 56,
                maxWidth: 56,
                resizable: false
            }, 
            {
                field: 'path',
                displayName: 'Context-Path',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'displayName',
                displayName: 'Display Name',
                cellFilter: null,
                width: "*",
                resizable: true
            }, 
            {
                field: 'startTime',
                displayName: 'Start Time',
                cellFilter: null,
                width: "*",
                resizable: true
            }
        ];
        $scope.gridOptions = {
            data: 'webapps',
            displayFooter: true,
            selectedItems: $scope.selected,
            selectWithCheckboxOnly: true,
            filterOptions: {
                filterText: ''
            }
        };
        function render(response) {
            response = Tomcat.filerTomcatOrCatalina(response);
            $scope.webapps = [];
            $scope.mbeanIndex = {};
            $scope.selected.length = 0;
            function onAttributes(response) {
                var obj = response.value;
                if (obj) {
                    obj.mbean = response.request.mbean;
                    var mbean = obj.mbean;
                    if (mbean) {
                        obj.startTime = Tomcat.millisToDateFormat(obj.startTime);
                        var idx = $scope.mbeanIndex[mbean];
                        if (angular.isDefined(idx)) {
                            $scope.webapps[mbean] = obj;
                        } else {
                            $scope.mbeanIndex[mbean] = $scope.webapps.length;
                            $scope.webapps.push(obj);
                        }
                        Core.$apply($scope);
                    }
                }
            }
            angular.forEach(response, function (value, key) {
                var mbean = value;
                if (Tomcat.isTomcat5($scope.tomcatServerVersion)) {
                    jolokia.request({
                        type: "read",
                        mbean: mbean,
                        attribute: [
                            "path", 
                            "state", 
                            "startTime"
                        ]
                    }, onSuccess(onAttributes));
                } else if (Tomcat.isTomcat6($scope.tomcatServerVersion)) {
                    jolokia.request({
                        type: "read",
                        mbean: mbean,
                        attribute: [
                            "path", 
                            "stateName", 
                            "startTime"
                        ]
                    }, onSuccess(onAttributes));
                } else {
                    jolokia.request({
                        type: "read",
                        mbean: mbean,
                        attribute: [
                            "displayName", 
                            "path", 
                            "stateName", 
                            "startTime"
                        ]
                    }, onSuccess(onAttributes));
                }
            });
            Core.$apply($scope);
        }
        ;
        $scope.controlWebApps = function (op) {
            var mbeanNames = $scope.selected.map(function (b) {
                return b.mbean;
            });
            if (!angular.isArray(mbeanNames)) {
                mbeanNames = [
                    mbeanNames
                ];
            }
            var lastIndex = (mbeanNames.length || 1) - 1;
            angular.forEach(mbeanNames, function (mbean, idx) {
                var onResponse = (idx >= lastIndex) ? $scope.onLastResponse : $scope.onResponse;
                jolokia.request({
                    type: 'exec',
                    mbean: mbean,
                    operation: op,
                    arguments: null
                }, onSuccess(onResponse, {
                    error: onResponse
                }));
            });
        };
        $scope.stop = function () {
            $scope.controlWebApps('stop');
        };
        $scope.start = function () {
            $scope.controlWebApps('start');
        };
        $scope.reload = function () {
            $scope.controlWebApps('reload');
        };
        $scope.uninstall = function () {
            $scope.controlWebApps('destroy');
            $scope.uninstallDialog.close();
        };
        $scope.onLastResponse = function (response) {
            $scope.onResponse(response);
            loadData();
        };
        $scope.onResponse = function (response) {
        };
        $scope.$on('jmxTreeUpdated', reloadFunction);
        $scope.$watch('workspace.tree', reloadFunction);
        function reloadFunction() {
            setTimeout(loadData, 50);
        }
        function loadData() {
            console.log("Loading tomcat webapp data...");
            jolokia.search("*:j2eeType=WebModule,*", onSuccess(render));
        }
        $scope.tomcatServerVersion = "";
        var servers = jolokia.search("*:type=Server");
        servers = Tomcat.filerTomcatOrCatalina(servers);
        if (servers && servers.length === 1) {
            $scope.tomcatServerVersion = jolokia.getAttribute(servers[0], "serverInfo");
        } else {
            console.log("Cannot find Tomcat server or there was more than one server. response is: " + servers);
        }
        if (Tomcat.isTomcat5($scope.tomcatServerVersion)) {
            console.log("Using Tomcat 5");
            $scope.gridOptions.columnDefs = columnDefsTomcat5;
        } else if (Tomcat.isTomcat6($scope.tomcatServerVersion)) {
            console.log("Using Tomcat 6");
            $scope.gridOptions.columnDefs = columnDefsTomcat6;
        } else {
            console.log("Using Tomcat 7");
            $scope.gridOptions.columnDefs = columnDefsTomcat7;
        }
    }
    Tomcat.TomcatController = TomcatController;
})(Tomcat || (Tomcat = {}));
var Tomcat;
(function (Tomcat) {
    function filerTomcatOrCatalina(response) {
        if (response) {
            response = response.filter(function (name) {
                return name.startsWith("Catalina") || name.startsWith("Tomcat");
            });
        }
        return response;
    }
    Tomcat.filerTomcatOrCatalina = filerTomcatOrCatalina;
    ;
    function iconClass(state) {
        if (state) {
            switch(state.toString().toLowerCase()) {
                case '1':
                    return "green icon-play-circle";
                case 'started':
                    return "green icon-play-circle";
                case '0':
                    return "orange icon-off";
                case 'stopped':
                    return "orange icon-off";
            }
        }
        if (angular.isNumber(state)) {
            if (state.toString() === '0') {
                return "orange icon-off";
            }
        }
        return "icon-question-sign";
    }
    Tomcat.iconClass = iconClass;
    function millisToDateFormat(time) {
        if (time) {
            var date = new Date(time);
            return date.toLocaleDateString() + " " + date.toLocaleTimeString();
        } else {
            return "";
        }
    }
    Tomcat.millisToDateFormat = millisToDateFormat;
    function isTomcat5(name) {
        return name.toString().indexOf("Apache Tomcat/5") !== -1;
    }
    Tomcat.isTomcat5 = isTomcat5;
    function isTomcat6(name) {
        return name.toString().indexOf("Apache Tomcat/6") !== -1;
    }
    Tomcat.isTomcat6 = isTomcat6;
})(Tomcat || (Tomcat = {}));
var Tomcat;
(function (Tomcat) {
    var pluginName = 'tomcat';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'ui.bootstrap.dialog', 
        'hawtioCore'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/tomcat/server', {
            templateUrl: 'app/tomcat/html/server.html'
        }).when('/tomcat/applications', {
            templateUrl: 'app/tomcat/html/applications.html'
        }).when('/tomcat/connectors', {
            templateUrl: 'app/tomcat/html/connectors.html'
        }).when('/tomcat/sessions', {
            templateUrl: 'app/tomcat/html/sessions.html'
        }).when('/tomcat/mbeans', {
            templateUrl: 'app/tomcat/html/mbeans.html'
        });
    }).filter('tomcatIconClass', function () {
        return Tomcat.iconClass;
    }).run(function ($location, workspace, viewRegistry, helpRegistry) {
        viewRegistry['tomcat'] = "app/tomcat/html/layoutTomcatTabs.html";
        viewRegistry['tomcatTree'] = "app/tomcat/html/layoutTomcatTree.html";
        helpRegistry.addUserDoc('tomcat', 'app/tomcat/doc/help.md', function () {
            return workspace.treeContainsDomainAndProperties("Tomcat") || workspace.treeContainsDomainAndProperties("Catalina");
        });
        workspace.topLevelTabs.push({
            content: "Tomcat",
            title: "Manage your Tomcat container",
            isValid: function (workspace) {
                return workspace.treeContainsDomainAndProperties("Tomcat") || workspace.treeContainsDomainAndProperties("Catalina");
            },
            href: function () {
                return "#/tomcat/applications";
            },
            isActive: function (workspace) {
                return workspace.isTopTabActive("tomcat");
            }
        });
    });
    hawtioPluginLoader.addModule(pluginName);
})(Tomcat || (Tomcat = {}));
var Tomcat;
(function (Tomcat) {
    function TreeController($scope, $location, workspace) {
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateSelectionFromURL, 50);
        });
        $scope.$watch('workspace.tree', function () {
            console.log("workspace tree has changed, lets reload!!");
            if (workspace.moveIfViewInvalid()) {
                return;
            }
            var children = [];
            var tree = workspace.tree;
            if (tree) {
                var folder = tree.get("Tomcat");
                if (!folder) {
                    folder = tree.get("Catalina");
                }
                if (folder) {
                    children = folder.children;
                }
            }
            var treeElement = $("#tomcatTree");
            Jmx.enableTree($scope, $location, workspace, treeElement, children, true);
            setTimeout(updateSelectionFromURL, 50);
        });
        function updateSelectionFromURL() {
            Jmx.updateTreeSelectionFromURL($location, $("#tomcatTree"), true);
        }
    }
    Tomcat.TreeController = TreeController;
})(Tomcat || (Tomcat = {}));
var Tree;
(function (Tree) {
    var pluginName = 'tree';
    angular.module(pluginName, [
        'bootstrap', 
        'ngResource', 
        'hawtioCore'
    ]).directive('hawtioTree', function (workspace, $timeout, $location, $filter, $compile) {
        return function (scope, element, attrs) {
            var tree = null;
            var data = null;
            var widget = null;
            var timeoutId = null;
            var onSelectFn = lookupFunction("onselect");
            var onDragStartFn = lookupFunction("ondragstart");
            var onDragEnterFn = lookupFunction("ondragenter");
            var onDropFn = lookupFunction("ondrop");
            function lookupFunction(attrName) {
                var answer = null;
                var fnName = attrs[attrName];
                if (fnName) {
                    answer = Core.pathGet(scope, fnName);
                    if (!angular.isFunction(answer)) {
                        answer = null;
                    }
                }
                return answer;
            }
            var data = attrs.hawtioTree;
            var queryParam = data;
            scope.$watch(data, onWidgetDataChange);
            scope.$on("hawtio.tree." + data, function (args) {
                var value = Core.pathGet(scope, data);
                onWidgetDataChange(value);
            });
            element.bind('$destroy', function () {
                $timeout.cancel(timeoutId);
            });
            updateLater();
            function updateWidget() {
                Core.$applyNowOrLater(scope);
            }
            function onWidgetDataChange(value) {
                tree = value;
                if (tree && !widget) {
                    var treeElement = $(element);
                    var children = Core.asArray(tree);
                    var hideRoot = attrs["hideroot"];
                    if ("true" === hideRoot) {
                        children = tree.children;
                    }
                    var config = {
                        clickFolderMode: 3,
                        onActivate: function (node) {
                            var data = node.data;
                            if (onSelectFn) {
                                onSelectFn(data, node);
                            } else {
                                workspace.updateSelectionNode(data);
                            }
                            Core.$apply(scope);
                        },
                        onClick: function (node, event) {
                            if (event["metaKey"]) {
                                event.preventDefault();
                                var url = $location.absUrl();
                                if (node && node.data) {
                                    var key = node.data["key"];
                                    if (key) {
                                        var hash = $location.search();
                                        hash[queryParam] = key;
                                        var idx = url.indexOf('?');
                                        if (idx <= 0) {
                                            url += "?";
                                        } else {
                                            url = url.substring(0, idx + 1);
                                        }
                                        url += $.param(hash);
                                    }
                                }
                                window.open(url, '_blank');
                                window.focus();
                                return false;
                            }
                            return true;
                        },
                        persist: false,
                        debugLevel: 0,
                        children: children,
                        dnd: {
                            onDragStart: onDragStartFn ? onDragStartFn : function (node) {
                                console.log("onDragStart!");
                                return true;
                            },
                            onDragEnter: onDragEnterFn ? onDragEnterFn : function (node, sourceNode) {
                                console.log("onDragEnter!");
                                return true;
                            },
                            onDrop: onDropFn ? onDropFn : function (node, sourceNode, hitMode) {
                                console.log("onDrop!");
                                sourceNode.move(node, hitMode);
                                return true;
                            }
                        }
                    };
                    if (!onDropFn && !onDragEnterFn && !onDragStartFn) {
                        delete config["dnd"];
                    }
                    widget = treeElement.dynatree(config);
                    var activatedNode = false;
                    var activateNodeName = attrs["activatenodes"];
                    if (activateNodeName) {
                        var values = scope[activateNodeName];
                        var tree = treeElement.dynatree("getTree");
                        if (values && tree) {
                            angular.forEach(Core.asArray(values), function (value) {
                                tree.activateKey(value);
                                activatedNode = true;
                            });
                        }
                    }
                    var root = treeElement.dynatree("getRoot");
                    if (root) {
                        var onRootName = attrs["onroot"];
                        if (onRootName) {
                            var fn = scope[onRootName];
                            if (fn) {
                                fn(root);
                            }
                        }
                        if (!activatedNode) {
                            var children = root.getChildren();
                            if (children && children.length) {
                                var child = children[0];
                                child.expand(true);
                                child.activate(true);
                            }
                        }
                    }
                }
                updateWidget();
            }
            function updateLater() {
                timeoutId = $timeout(function () {
                    updateWidget();
                }, 300);
            }
        };
    }).run(function (helpRegistry) {
        helpRegistry.addDevDoc(pluginName, 'app/tree/doc/developer.md');
    });
    hawtioPluginLoader.addModule(pluginName);
})(Tree || (Tree = {}));
var UI;
(function (UI) {
    var AutoColumns = (function () {
        function AutoColumns() {
            this.restrict = 'A';
            this.link = function ($scope, $element, $attr) {
                var selector = UI.getIfSet('hawtioAutoColumns', $attr, 'div');
                var minMargin = UI.getIfSet('minMargin', $attr, '3').toNumber();
                var go = function () {
                    var containerWidth = $element.innerWidth();
                    var childWidth = 0;
                    var children = $element.children(selector);
                    if (children.length === 0) {
                        UI.log.debug("No children, skipping calculating column margins");
                        return;
                    }
                    children.each(function (child) {
                        var self = $(this);
                        if (!self.is(':visible')) {
                            return;
                        }
                        if (self.outerWidth() > childWidth) {
                            childWidth = self.outerWidth();
                        }
                    });
                    if (childWidth === 0) {
                        return;
                    }
                    childWidth = childWidth + (minMargin * 2);
                    var columns = Math.floor(containerWidth / childWidth);
                    if (children.length < columns) {
                        columns = children.length;
                    }
                    var margin = (containerWidth - (columns * childWidth)) / columns / 2;
                    UI.log.debug("child width: ", childWidth);
                    UI.log.debug("Inner width: ", containerWidth);
                    UI.log.debug("columns: ", columns);
                    UI.log.debug("margin: ", margin);
                    children.each(function (child) {
                        $(this).css({
                            'margin-left': margin,
                            'margin-right': margin
                        });
                    });
                };
                setTimeout(go, 300);
                $scope.$watch(go);
                $(window).resize(go);
            };
        }
        return AutoColumns;
    })();
    UI.AutoColumns = AutoColumns;    
})(UI || (UI = {}));
var UI;
(function (UI) {
    var _this = this;
    UI.AutoDropDown = {
        restrict: 'A',
        link: function ($scope, $element, $attrs) {
            function locateElements(event) {
                var el = $element.get(0);
                if (event && event.relatedNode !== el && event.type) {
                    if (event && event.type !== 'resize') {
                        return;
                    }
                }
                var overflowEl = $($element.find('.overflow'));
                var overflowMenu = $(overflowEl.find('ul.dropdown-menu'));
                var margin = overflowEl.outerWidth() - overflowEl.innerWidth();
                var availableWidth = overflowEl.position().left - $element.position().left - 50;
                $element.children('li:not(.overflow):not(.pull-right):not(:hidden)').each(function () {
                    var self = $(this);
                    availableWidth = availableWidth - self.outerWidth(true);
                    if (availableWidth < 0) {
                        self.detach();
                        self.prependTo(overflowMenu);
                    }
                });
                if (overflowMenu.children().length > 0) {
                    overflowEl.css({
                        visibility: "visible"
                    });
                }
                if (availableWidth > 130) {
                    var noSpace = false;
                    overflowMenu.children('li:not(.overflow):not(.pull-right)').filter(function () {
                        return $(this).css('display') !== 'none';
                    }).each(function () {
                        if (noSpace) {
                            return;
                        }
                        var self = $(this);
                        if (availableWidth > self.outerWidth()) {
                            availableWidth = availableWidth - self.outerWidth();
                            self.detach();
                            self.insertBefore(overflowEl);
                        } else {
                            noSpace = true;
                        }
                    });
                }
                if (overflowMenu.children().length === 0) {
                    overflowEl.css({
                        visibility: "hidden"
                    });
                }
            }
            $(window).resize(locateElements);
            $element.get(0).addEventListener("DOMNodeInserted", locateElements);
            $scope.$watch(setTimeout(locateElements, 500));
        }
    };
})(UI || (UI = {}));
var UI;
(function (UI) {
    UI.selected = "selected";
    UI.unselected = "unselected";
    UI.colors = [
        "#5484ED", 
        "#A4BDFC", 
        "#46D6DB", 
        "#7AE7BF", 
        "#51B749", 
        "#FBD75B", 
        "#FFB878", 
        "#FF887C", 
        "#DC2127", 
        "#DBADFF", 
        "#E1E1E1"
    ];
    var ColorPicker = (function () {
        function ColorPicker() {
            this.restrict = 'A';
            this.replace = true;
            this.scope = {
                property: '=hawtioColorPicker'
            };
            this.templateUrl = UI.templatePath + "colorPicker.html";
            this.compile = function (tElement, tAttrs, transclude) {
                return {
                    post: function postLink(scope, iElement, iAttrs, controller) {
                        scope.colorList = [];
                        angular.forEach(UI.colors, function (color) {
                            var select = UI.unselected;
                            if (scope.property === color) {
                                select = UI.selected;
                            }
                            scope.colorList.push({
                                color: color,
                                select: select
                            });
                        });
                    }
                };
            };
            this.controller = function ($scope, $element, $timeout) {
                $scope.popout = false;
                $scope.$watch('popout', function () {
                    $element.find('.color-picker-popout').toggleClass('popout-open', $scope.popout);
                });
                $scope.selectColor = function (color) {
                    for(var i = 0; i < $scope.colorList.length; i++) {
                        $scope.colorList[i].select = UI.unselected;
                        if ($scope.colorList[i] === color) {
                            $scope.property = color.color;
                            $scope.colorList[i].select = UI.selected;
                        }
                    }
                };
            };
        }
        return ColorPicker;
    })();
    UI.ColorPicker = ColorPicker;    
})(UI || (UI = {}));
var UI;
(function (UI) {
    var ConfirmDialog = (function () {
        function ConfirmDialog() {
            this.restrict = 'A';
            this.replace = true;
            this.transclude = true;
            this.templateUrl = UI.templatePath + 'confirmDialog.html';
            this.scope = {
                show: '=hawtioConfirmDialog',
                title: '@',
                okButtonText: '@',
                cancelButtonText: '@',
                onCancel: '&',
                onOk: '&',
                onClose: '&'
            };
            this.controller = function ($scope, $element, $attrs, $transclude, $compile) {
                $scope.clone = null;
                $transclude(function (clone) {
                    $scope.clone = $(clone).filter('.dialog-body');
                });
                $scope.$watch('show', function () {
                    if ($scope.show) {
                        setTimeout(function () {
                            $scope.body = $('.modal-body');
                            $scope.body.html($compile($scope.clone.html())($scope.$parent));
                            Core.$apply($scope);
                        }, 50);
                    }
                });
                $attrs.$observe('okButtonText', function (value) {
                    if (!angular.isDefined(value)) {
                        $scope.okButtonText = "Ok";
                    }
                });
                $attrs.$observe('cancelButtonText', function (value) {
                    if (!angular.isDefined(value)) {
                        $scope.cancelButtonText = "Cancel";
                    }
                });
                $attrs.$observe('title', function (value) {
                    if (!angular.isDefined(value)) {
                        $scope.title = "Are you sure?";
                    }
                });
                function checkClosed() {
                    setTimeout(function () {
                        var backdrop = $("div.modal-backdrop");
                        if (backdrop && backdrop.length) {
                            Logger.get("ConfirmDialog").info("Removing the backdrop div! " + backdrop);
                            backdrop.remove();
                        }
                    }, 200);
                }
                $scope.cancel = function () {
                    $scope.show = false;
                    $scope.$parent.$eval($scope.onCancel);
                    checkClosed();
                };
                $scope.submit = function () {
                    $scope.show = false;
                    $scope.$parent.$eval($scope.onOk);
                    checkClosed();
                };
                $scope.close = function () {
                    $scope.$parent.$eval($scope.onClose);
                    checkClosed();
                };
            };
        }
        ConfirmDialog.prototype.constructor = function () {
        };
        return ConfirmDialog;
    })();
    UI.ConfirmDialog = ConfirmDialog;    
})(UI || (UI = {}));
var UI;
(function (UI) {
    var EditableProperty = (function () {
        function EditableProperty($parse) {
            this.$parse = $parse;
            this.restrict = 'E';
            this.scope = true;
            this.templateUrl = UI.templatePath + 'editableProperty.html';
            this.require = 'ngModel';
            this.link = null;
            this.link = function (scope, element, attrs, ngModel) {
                scope.editing = false;
                $(element.find(".icon-pencil")[0]).hide();
                scope.getPropertyName = function () {
                    var propertyName = $parse(attrs['property'])(scope);
                    if (!propertyName && propertyName !== 0) {
                        propertyName = attrs['property'];
                    }
                    return propertyName;
                };
                scope.propertyName = scope.getPropertyName();
                ngModel.$render = function () {
                    if (!ngModel.$viewValue) {
                        return;
                    }
                    scope.text = ngModel.$viewValue[scope.propertyName];
                };
                scope.showEdit = function () {
                    $(element.find(".icon-pencil")[0]).show();
                };
                scope.hideEdit = function () {
                    $(element.find(".icon-pencil")[0]).hide();
                };
                scope.$watch('editing', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        if (newValue) {
                            $(element.find('input[type=text]')).focus();
                        }
                    }
                });
                scope.doEdit = function () {
                    scope.editing = true;
                };
                scope.stopEdit = function () {
                    scope.editing = false;
                };
                scope.saveEdit = function () {
                    var value = $(element.find(":input[type=text]")[0]).val();
                    var obj = ngModel.$viewValue;
                    obj[scope.propertyName] = value;
                    ngModel.$setViewValue(obj);
                    ngModel.$render();
                    scope.editing = false;
                    scope.$parent.$eval(attrs['onSave']);
                };
            };
        }
        return EditableProperty;
    })();
    UI.EditableProperty = EditableProperty;    
})(UI || (UI = {}));
var UI;
(function (UI) {
    function Editor($parse) {
        return {
            restrict: 'A',
            replace: true,
            templateUrl: UI.templatePath + "editor.html",
            scope: {
                text: '=hawtioEditor',
                mode: '=',
                dirty: '=',
                name: '@'
            },
            controller: function ($scope, $element, $attrs) {
                $scope.codeMirror = null;
                $scope.doc = null;
                $scope.options = [];
                UI.observe($scope, $attrs, 'name', 'editor');
                $scope.applyOptions = function () {
                    if ($scope.codeMirror) {
                        $scope.options.each(function (option) {
                            $scope.codeMirror.setOption(option.key, option['value']);
                        });
                        $scope.options = [];
                    }
                };
                $scope.$watch('doc', function () {
                    if ($scope.doc) {
                        $scope.codeMirror.on('change', function (changeObj) {
                            var phase = $scope.$parent.$$phase;
                            if (!phase) {
                                $scope.text = $scope.doc.getValue();
                                $scope.dirty = !$scope.doc.isClean();
                                Core.$applyNowOrLater($scope);
                            }
                        });
                    }
                });
                $scope.$watch('codeMirror', function () {
                    if ($scope.codeMirror) {
                        $scope.doc = $scope.codeMirror.getDoc();
                    }
                });
                $scope.$watch('text', function (oldValue, newValue) {
                    if ($scope.codeMirror && $scope.doc) {
                        if (!$scope.codeMirror.hasFocus()) {
                            $scope.doc.setValue($scope.text);
                        }
                    }
                });
            },
            link: function ($scope, $element, $attrs) {
                var config = Object.extended($attrs).clone();
                delete config['$$element'];
                delete config['$attr'];
                delete config['class'];
                delete config['hawtioEditor'];
                delete config['mode'];
                delete config['dirty'];
                if ('onChange' in $attrs) {
                    var onChange = $attrs['onChange'];
                    delete config['onChange'];
                    $scope.options.push({
                        onChange: function (codeMirror) {
                            var func = $parse(onChange);
                            if (func) {
                                func($scope.$parent, {
                                    codeMirror: codeMirror
                                });
                            }
                        }
                    });
                }
                angular.forEach(config, function (value, key) {
                    $scope.options.push({
                        key: key,
                        'value': value
                    });
                });
                $scope.$watch('mode', function () {
                    if ($scope.mode) {
                        if (!$scope.codeMirror) {
                            $scope.options.push({
                                key: 'mode',
                                'value': $scope.mode
                            });
                        } else {
                            $scope.codeMirror.setOption('mode', $scope.mode);
                        }
                    }
                });
                $scope.$watch('dirty', function () {
                    if ($scope.dirty && !$scope.doc.isClean()) {
                        $scope.doc.markClean();
                    }
                });
                $scope.$watch('text', function () {
                    if (!$scope.codeMirror) {
                        var options = {
                            value: $scope.text
                        };
                        options = CodeEditor.createEditorSettings(options);
                        $scope.codeMirror = CodeMirror.fromTextArea($element.find('textarea').get(0), options);
                        $scope.applyOptions();
                    }
                });
            }
        };
    }
    UI.Editor = Editor;
})(UI || (UI = {}));
var UI;
(function (UI) {
    var Expandable = (function () {
        function Expandable() {
            var _this = this;
            this.restrict = 'C';
            this.replace = false;
            this.link = null;
            this.link = function (scope, element, attrs) {
                var self = _this;
                var expandable = element;
                var modelName = null;
                var model = null;
                if (angular.isDefined(attrs['model'])) {
                    modelName = attrs['model'];
                    model = scope[modelName];
                    if (!angular.isDefined(scope[modelName]['expanded'])) {
                        model['expanded'] = expandable.hasClass('opened');
                    } else {
                        if (model['expanded']) {
                            self.forceOpen(model, expandable, scope);
                        } else {
                            self.forceClose(model, expandable, scope);
                        }
                    }
                }
                var title = expandable.find('.title');
                var button = expandable.find('.cancel');
                button.bind('click', function () {
                    self.forceClose(model, expandable, scope);
                    return false;
                });
                title.bind('click', function () {
                    if (expandable.hasClass('opened')) {
                        self.close(model, expandable, scope);
                    } else {
                        self.open(model, expandable, scope);
                    }
                    return false;
                });
            };
        }
        Expandable.prototype.open = function (model, expandable, scope) {
            expandable.find('.expandable-body').slideDown(400, function () {
                expandable.toggleClass('opened');
                expandable.toggleClass('closed');
                if (model) {
                    model['expanded'] = true;
                }
                Core.$apply(scope);
            });
        };
        Expandable.prototype.close = function (model, expandable, scope) {
            expandable.find('.expandable-body').slideUp(400, function () {
                expandable.toggleClass('opened');
                expandable.toggleClass('closed');
                if (model) {
                    model['expanded'] = false;
                }
                Core.$apply(scope);
            });
        };
        Expandable.prototype.forceClose = function (model, expandable, scope) {
            expandable.find('.expandable-body').slideUp(0, function () {
                if (!expandable.hasClass('closed')) {
                    expandable.addClass('closed');
                }
                expandable.removeClass('opened');
                if (model) {
                    model['expanded'] = false;
                }
                Core.$apply(scope);
            });
        };
        Expandable.prototype.forceOpen = function (model, expandable, scope) {
            expandable.find('.expandable-body').slideDown(0, function () {
                if (!expandable.hasClass('opened')) {
                    expandable.addClass('opened');
                }
                expandable.removeClass('closed');
                if (model) {
                    model['expanded'] = true;
                }
                Core.$apply(scope);
            });
        };
        return Expandable;
    })();
    UI.Expandable = Expandable;    
})(UI || (UI = {}));
var UI;
(function (UI) {
    UI.fileUploadMBean = "hawtio:type=UploadManager";
    var FileUpload = (function () {
        function FileUpload() {
            this.restrict = 'A';
            this.replace = true;
            this.templateUrl = UI.templatePath + "fileUpload.html";
            this.scope = {
                files: '=hawtioFileUpload',
                target: '@',
                showFiles: '@'
            };
            this.controller = function ($scope, $element, $attrs, jolokia) {
                $scope.target = '';
                $scope.response = '';
                $scope.percentComplete = 0;
                UI.observe($scope, $attrs, 'target', '');
                UI.observe($scope, $attrs, 'showFiles', true);
                $scope.update = function (response) {
                    var responseJson = angular.toJson(response.value);
                    if ($scope.responseJson !== responseJson) {
                        $scope.responseJson = responseJson;
                        $scope.files = response.value;
                        Core.$applyNowOrLater($scope);
                    }
                };
                $scope.delete = function (fileName) {
                    jolokia.request({
                        type: 'exec',
                        mbean: UI.fileUploadMBean,
                        operation: 'delete(java.lang.String, java.lang.String)',
                        arguments: [
                            $scope.target, 
                            fileName
                        ]
                    }, {
                        success: function () {
                            Core.$apply($scope);
                        },
                        error: function (response) {
                            notification('error', "Failed to delete " + fileName + " due to: " + response.error);
                            Core.$apply($scope);
                        }
                    });
                };
                $scope.$watch('target', function (newValue, oldValue) {
                    if (oldValue !== newValue) {
                        Core.unregister(jolokia, $scope);
                    }
                    Core.register(jolokia, $scope, {
                        type: 'exec',
                        mbean: UI.fileUploadMBean,
                        operation: 'list(java.lang.String)',
                        arguments: [
                            $scope.target
                        ]
                    }, onSuccess($scope.update));
                });
            };
            this.link = function ($scope, $element, $attrs) {
                var fileInput = $element.find('input[type=file]');
                var form = $element.find('form[name=file-upload]');
                var button = $element.find('input[type=button]');
                var onFileChange = function () {
                    button.prop('disabled', true);
                    var files = fileInput.get(0).files;
                    var fileName = files.length + " files";
                    if (files.length === 1) {
                        fileName = files[0].name;
                    }
                    form.ajaxSubmit({
                        beforeSubmit: function (arr, $form, options) {
                            notification('info', "Uploading " + fileName);
                            $scope.percentComplete = 0;
                            Core.$apply($scope);
                        },
                        success: function (response, statusText, xhr, $form) {
                            notification('success', "Uploaded " + fileName);
                            setTimeout(function () {
                                button.prop('disabled', false);
                                $scope.percentComplete = 0;
                                Core.$apply($scope);
                            }, 1000);
                            Core.$apply($scope);
                        },
                        error: function (response, statusText, xhr, $form) {
                            notification('error', "Failed to upload " + fileName + " due to " + statusText);
                            setTimeout(function () {
                                button.prop('disabled', false);
                                $scope.percentComplete = 0;
                                Core.$apply($scope);
                            }, 1000);
                            Core.$apply($scope);
                        },
                        uploadProgress: function (event, position, total, percentComplete) {
                            $scope.percentComplete = percentComplete;
                            Core.$apply($scope);
                        }
                    });
                    return false;
                };
                button.click(function () {
                    if (!button.prop('disabled')) {
                        fileInput.click();
                    }
                    return false;
                });
                form.submit(function () {
                    return false;
                });
                if (($).browser.msie) {
                    fileInput.click(function (event) {
                        setTimeout(function () {
                            if (fileInput.val().length > 0) {
                                onFileChange();
                            }
                        }, 0);
                    });
                } else {
                    fileInput.change(onFileChange);
                }
            };
        }
        return FileUpload;
    })();
    UI.FileUpload = FileUpload;    
})(UI || (UI = {}));
var UI;
(function (UI) {
    var GridsterDirective = (function () {
        function GridsterDirective() {
            this.restrict = 'A';
            this.replace = true;
            this.controller = function ($scope, $element, $attrs) {
            };
            this.link = function ($scope, $element, $attrs) {
                var widgetMargins = [
                    6, 
                    6
                ];
                var widgetBaseDimensions = [
                    150, 
                    150
                ];
                var gridSize = [
                    150, 
                    150
                ];
                var extraRows = 10;
                var extraCols = 6;
                if (angular.isDefined($attrs['extraRows'])) {
                    extraRows = $attrs['extraRows'].toNumber();
                }
                if (angular.isDefined($attrs['extraCols'])) {
                    extraCols = $attrs['extraCols'].toNumber();
                }
                var grid = $('<ul style="margin: 0"></ul>');
                var styleStr = '<style type="text/css">';
                var styleStr = styleStr + '</style>';
                $element.append($(styleStr));
                $element.append(grid);
                $scope.gridster = grid.gridster({
                    widget_margins: widgetMargins,
                    grid_size: gridSize,
                    extra_rows: extraRows,
                    extra_cols: extraCols
                }).data('gridster');
            };
        }
        return GridsterDirective;
    })();
    UI.GridsterDirective = GridsterDirective;    
})(UI || (UI = {}));
var UI;
(function (UI) {
    var JSPlumb = (function () {
        function JSPlumb() {
            this.restrict = 'A';
            this.link = function ($scope, $element, $attrs) {
                var enableDragging = true;
                if (angular.isDefined($attrs['draggable'])) {
                    enableDragging = Core.parseBooleanValue($attrs['draggable']);
                }
                var useLayout = true;
                if (angular.isDefined($attrs['layout'])) {
                    useLayout = Core.parseBooleanValue($attrs['layout']);
                }
                var timeout = 100;
                if (angular.isDefined($attrs['timeout'])) {
                    timeout = Core.parseIntValue($attrs['timeout'], "timeout");
                }
                var endpointStyle = [
                    "Dot", 
                    {
                        radius: 10,
                        cssClass: 'jsplumb-circle',
                        hoverClass: 'jsplumb-circle-hover'
                    }
                ];
                var labelStyles = [
                    "Label"
                ];
                var arrowStyles = [
                    "Arrow", 
                    {
                        location: 1,
                        id: "arrow",
                        length: 8,
                        width: 8,
                        foldback: 0.8
                    }
                ];
                var connectorStyle = [
                    "Flowchart", 
                    {
                        cornerRadius: 4,
                        gap: 8
                    }
                ];
                if (angular.isDefined($scope.connectorStyle)) {
                    connectorStyle = $scope.connectorStyle;
                }
                var createNode = function (nodeEl) {
                    var el = $(nodeEl);
                    var id = el.attr('id');
                    var anchors = el.attr('anchors');
                    if (anchors.has("{{") || anchors.has("}}")) {
                        return null;
                    }
                    if (anchors) {
                        anchors = anchors.split(',').map(function (anchor) {
                            return anchor.trim();
                        });
                    } else {
                        anchors = [
                            "Top"
                        ];
                    }
                    var node = {
                        id: id,
                        label: 'node ' + id,
                        el: el,
                        width: el.outerWidth(),
                        height: el.outerHeight(),
                        edges: [],
                        connections: [],
                        endpoints: [],
                        anchors: anchors
                    };
                    return node;
                };
                var createEndpoint = function (jsPlumb, node) {
                    var endpoint = jsPlumb.addEndpoint(node.el, {
                        isSource: true,
                        isTarget: true,
                        anchor: node.anchors,
                        connector: connectorStyle,
                        maxConnections: -1
                    });
                    node.endpoints.push(endpoint);
                    if (enableDragging) {
                        jsPlumb.draggable(node.el, {
                            containment: $element
                        });
                    }
                };
                var nodes = [];
                var transitions = [];
                var nodesById = {};
                var gatherElements = function () {
                    var nodeEls = $element.find('.jsplumb-node');
                    angular.forEach(nodeEls, function (nodeEl) {
                        if (!nodesById[nodeEl.id]) {
                            var node = createNode(nodeEl);
                            if (node) {
                                nodes.push(node);
                                nodesById[node.id] = node;
                            }
                        }
                    });
                    angular.forEach(nodes, function (sourceNode) {
                        var targets = sourceNode.el.attr('connect-to');
                        if (targets) {
                            targets = targets.split(',');
                            angular.forEach(targets, function (target) {
                                var targetNode = nodesById[target.trim()];
                                if (targetNode) {
                                    var edge = {
                                        source: sourceNode,
                                        target: targetNode
                                    };
                                    transitions.push(edge);
                                    sourceNode.edges.push(edge);
                                    targetNode.edges.push(edge);
                                }
                            });
                        }
                    });
                };
                setTimeout(function () {
                    $scope.jsPlumb = jsPlumb.getInstance({
                        Container: $element
                    });
                    $scope.jsPlumb.importDefaults({
                        Anchor: "AutoDefault",
                        Connector: "Flowchart",
                        ConnectorStyle: connectorStyle,
                        DragOptions: {
                            cursor: "pointer",
                            zIndex: 2000
                        },
                        Endpoint: endpointStyle,
                        PaintStyle: {
                            strokeStyle: "#42a62c",
                            lineWidth: 4
                        },
                        HoverPaintStyle: {
                            strokeStyle: "#42a62c",
                            lineWidth: 4
                        },
                        ConnectionOverlays: [
                            arrowStyles, 
                            labelStyles
                        ]
                    });
                    gatherElements();
                    $scope.jsPlumbNodes = nodes;
                    $scope.jsPlumbNodesById = nodesById;
                    $scope.jsPlumbTransitions = transitions;
                    if (useLayout) {
                        $scope.layout = dagre.layout().nodeSep(50).edgeSep(10).rankSep(50).nodes(nodes).edges(transitions).debugLevel(1).run();
                    }
                    angular.forEach($scope.jsPlumbNodes, function (node) {
                        if (useLayout) {
                            node.el.css({
                                top: node.dagre.y,
                                left: node.dagre.x
                            });
                        }
                        createEndpoint($scope.jsPlumb, node);
                    });
                    angular.forEach($scope.jsPlumbTransitions, function (edge) {
                        var connection = $scope.jsPlumb.connect({
                            source: edge.source.el,
                            target: edge.target.el
                        }, {
                            connector: connectorStyle,
                            maxConnections: -1
                        });
                        edge.source.connections.push(connection);
                        edge.target.connections.push(connection);
                    });
                    $scope.jsPlumb.recalculateOffsets($element);
                    $scope.jsPlumb.repaintEverything();
                    if (angular.isDefined($scope.jsPlumbCallback) && angular.isFunction($scope.jsPlumbCallback)) {
                        $scope.jsPlumbCallback($scope.jsPlumb, $scope.jsPlumbNodes, $scope.jsPlumbNodesById, $scope.jsPlumbTransitions);
                    }
                    Core.$apply($scope);
                }, timeout);
            };
        }
        return JSPlumb;
    })();
    UI.JSPlumb = JSPlumb;    
})(UI || (UI = {}));
var UI;
(function (UI) {
    var MessagePanel = (function () {
        function MessagePanel() {
            this.restrict = 'A';
            this.link = function ($scope, $element, $attrs) {
                var height = "100%";
                if ('hawtioMessagePanel' in $attrs) {
                    var wantedHeight = $attrs['hawtioMessagePanel'];
                    if (wantedHeight && !wantedHeight.isBlank()) {
                        height = wantedHeight;
                    }
                }
                var speed = "1s";
                if ('speed' in $attrs) {
                    var wantedSpeed = $attrs['speed'];
                    if (speed && !speed.isBlank()) {
                        speed = wantedSpeed;
                    }
                }
                $element.css({
                    position: 'absolute',
                    bottom: 0,
                    height: 0,
                    'min-height': 0,
                    transition: 'all ' + speed + ' ease-in-out'
                });
                $element.parent().mouseover(function () {
                    $element.css({
                        height: height,
                        'min-height': 'auto'
                    });
                });
                $element.parent().mouseout(function () {
                    $element.css({
                        height: 0,
                        'min-height': 0
                    });
                });
            };
        }
        return MessagePanel;
    })();
    UI.MessagePanel = MessagePanel;    
    var InfoPanel = (function () {
        function InfoPanel() {
            this.restrict = 'A';
            this.link = function ($scope, $element, $attrs) {
                var validDirections = {
                    'left': {
                        side: 'right',
                        out: 'width'
                    },
                    'right': {
                        side: 'left',
                        out: 'width'
                    },
                    'up': {
                        side: 'bottom',
                        out: 'height'
                    },
                    'down': {
                        side: 'top',
                        out: 'height'
                    }
                };
                var direction = "right";
                if ('hawtioInfoPanel' in $attrs) {
                    var wantedDirection = $attrs['hawtioInfoPanel'];
                    if (wantedDirection && !wantedDirection.isBlank()) {
                        if (Object.extended(validDirections).keys().any(wantedDirection)) {
                            direction = wantedDirection;
                        }
                    }
                }
                var speed = "1s";
                if ('speed' in $attrs) {
                    var wantedSpeed = $attrs['speed'];
                    if (speed && !speed.isBlank()) {
                        speed = wantedSpeed;
                    }
                }
                var toggle = "open";
                if ('toggle' in $attrs) {
                    var wantedToggle = $attrs['toggle'];
                    if (toggle && !toggle.isBlank()) {
                        toggle = wantedToggle;
                    }
                }
                var initialCss = {
                    position: 'absolute',
                    transition: 'all ' + speed + ' ease-in-out'
                };
                var openCss = {};
                openCss[validDirections[direction]['out']] = '100%';
                var closedCss = {};
                closedCss[validDirections[direction]['out']] = 0;
                initialCss[validDirections[direction]['side']] = 0;
                initialCss[validDirections[direction]['out']] = 0;
                $element.css(initialCss);
                $scope.$watch(toggle, function (newValue, oldValue) {
                    if (Core.parseBooleanValue(newValue)) {
                        $element.css(openCss);
                    } else {
                        $element.css(closedCss);
                    }
                });
                $element.click(function () {
                    $scope[toggle] = false;
                    Core.$apply($scope);
                });
            };
        }
        return InfoPanel;
    })();
    UI.InfoPanel = InfoPanel;    
})(UI || (UI = {}));
var UI;
(function (UI) {
    var DivRow = (function () {
        function DivRow() {
            this.restrict = 'A';
            this.link = function ($scope, $element, $attrs) {
                $element.get(0).addEventListener("DOMNodeInserted", function () {
                    var targets = $element.children();
                    var width = 0;
                    angular.forEach(targets, function (target) {
                        var el = (angular).element(target);
                        switch(el.css('display')) {
                            case 'none':
                                break;
                            default:
                                width = width + el.outerWidth(true) + 5;
                        }
                    });
                    $element.width(width);
                });
            };
        }
        return DivRow;
    })();
    UI.DivRow = DivRow;    
})(UI || (UI = {}));
var UI;
(function (UI) {
    var SlideOut = (function () {
        function SlideOut() {
            this.restrict = 'A';
            this.replace = true;
            this.transclude = true;
            this.templateUrl = UI.templatePath + 'slideout.html';
            this.scope = {
                show: '=hawtioSlideout',
                direction: '@',
                top: '@',
                height: '@',
                title: '@'
            };
            this.controller = function ($scope, $element, $attrs, $transclude, $compile) {
                $scope.clone = null;
                $transclude(function (clone) {
                    $scope.clone = $(clone).filter('.dialog-body');
                });
                UI.observe($scope, $attrs, 'direction', 'right');
                UI.observe($scope, $attrs, 'top', '10%', function (value) {
                    $element.css('top', value);
                });
                UI.observe($scope, $attrs, 'height', '80%', function (value) {
                    $element.css('height', value);
                });
                UI.observe($scope, $attrs, 'title', '');
                $scope.$watch('show', function () {
                    if ($scope.show) {
                        $scope.body = $element.find('.slideout-body');
                        $scope.body.html($compile($scope.clone.html())($scope.$parent));
                    }
                });
            };
            this.link = function ($scope, $element, $attrs) {
                $scope.element = $($element);
                $scope.element.blur(function () {
                    $scope.show = false;
                    Core.$apply($scope);
                    return false;
                });
                $scope.$watch('show', function () {
                    if ($scope.show) {
                        $scope.element.addClass('out');
                        $scope.element.focus();
                    } else {
                        $scope.element.removeClass('out');
                    }
                });
            };
        }
        return SlideOut;
    })();
    UI.SlideOut = SlideOut;    
})(UI || (UI = {}));
var UI;
(function (UI) {
    var TablePager = (function () {
        function TablePager() {
            var _this = this;
            this.restrict = 'A';
            this.scope = true;
            this.templateUrl = UI.templatePath + 'tablePager.html';
            this.$scope = null;
            this.element = null;
            this.attrs = null;
            this.tableName = null;
            this.setRowIndexName = null;
            this.rowIndexName = null;
            this.link = function (scope, element, attrs) {
                return _this.doLink(scope, element, attrs);
            };
        }
        TablePager.prototype.doLink = function (scope, element, attrs) {
            var _this = this;
            this.$scope = scope;
            this.element = element;
            this.attrs = attrs;
            this.tableName = attrs["hawtioPager"] || attrs["array"] || "data";
            this.setRowIndexName = attrs["onIndexChange"] || "onIndexChange";
            this.rowIndexName = attrs["rowIndex"] || "rowIndex";
            scope.first = function () {
                _this.goToIndex(0);
            };
            scope.last = function () {
                _this.goToIndex(scope.tableLength() - 1);
            };
            scope.previous = function () {
                _this.goToIndex(scope.rowIndex() - 1);
            };
            scope.next = function () {
                _this.goToIndex(scope.rowIndex() + 1);
            };
            scope.isEmptyOrFirst = function () {
                var idx = scope.rowIndex();
                var length = scope.tableLength();
                return length <= 0 || idx <= 0;
            };
            scope.isEmptyOrLast = function () {
                var idx = scope.rowIndex();
                var length = scope.tableLength();
                return length < 1 || idx + 1 >= length;
            };
            scope.rowIndex = function () {
                return scope.$parent[_this.rowIndexName];
            };
            scope.tableLength = function () {
                var data = _this.tableData();
                return data ? data.length : 0;
            };
        };
        TablePager.prototype.tableData = function () {
            return this.$scope.$parent[this.tableName] || [];
        };
        TablePager.prototype.goToIndex = function (idx) {
            var name = this.setRowIndexName;
            var fn = this.$scope[name];
            if (angular.isFunction(fn)) {
                fn(idx);
            } else {
                console.log("No function defined in scope for " + name + " but was " + fn);
                this.$scope[this.rowIndexName] = idx;
            }
        };
        return TablePager;
    })();
    UI.TablePager = TablePager;    
})(UI || (UI = {}));
var UI;
(function (UI) {
    function TemplatePopover($templateCache, $compile, $document) {
        return {
            restrict: 'A',
            link: function ($scope, $element, $attr) {
                var title = UI.getIfSet('title', $attr, undefined);
                var trigger = UI.getIfSet('trigger', $attr, 'hover');
                var html = true;
                var contentTemplate = UI.getIfSet('content', $attr, 'popoverTemplate');
                var placement = UI.getIfSet('placement', $attr, 'auto');
                var delay = UI.getIfSet('delay', $attr, '100');
                var container = UI.getIfSet('container', $attr, 'body');
                var selector = UI.getIfSet('container', $attr, 'false');
                if (selector === 'false') {
                    selector = false;
                }
                var template = $templateCache.get(contentTemplate);
                if (!template) {
                    return;
                }
                ($element).popover({
                    title: title,
                    trigger: trigger,
                    html: html,
                    content: $compile(template)($scope),
                    delay: delay,
                    container: container,
                    selector: selector,
                    placement: function (tip, element) {
                        if (placement !== 'auto') {
                            return placement;
                        }
                        var el = $(element);
                        var offset = el.offset();
                        var width = $document.innerWidth();
                        var elHorizontalCenter = offset['left'] + (el.outerWidth() / 2);
                        var midpoint = width / 2;
                        if (elHorizontalCenter < midpoint) {
                            return 'right';
                        } else {
                            return 'left';
                        }
                    }
                });
            }
        };
    }
    UI.TemplatePopover = TemplatePopover;
})(UI || (UI = {}));
var UI;
(function (UI) {
    function UITestController2($scope, workspace, $templateCache) {
        $scope.fileUploadExMode = 'text/html';
        $scope.menuItems = [];
        $scope.divs = [];
        for(var i = 0; i < 20; i++) {
            $scope.menuItems.push("Some Item " + i);
        }
        for(var i = 0; i < 20; i++) {
            $scope.divs.push(i + 1);
        }
        $scope.things = [
            {
                'name': 'stuff1',
                'foo1': 'bar1',
                'foo2': 'bar2'
            }, 
            {
                'name': 'stuff2',
                'foo3': 'bar3',
                'foo4': 'bar4'
            }
        ];
        $scope.autoDropDown = $templateCache.get("autoDropDownTemplate");
        $scope.zeroClipboard = $templateCache.get("zeroClipboardTemplate");
        $scope.popoverEx = $templateCache.get("myTemplate");
        $scope.popoverUsageEx = $templateCache.get("popoverExTemplate");
        $scope.autoColumnEx = $templateCache.get("autoColumnTemplate");
    }
    UI.UITestController2 = UITestController2;
    function UITestController1($scope, workspace, $templateCache) {
        $scope.jsplumbEx = $templateCache.get("jsplumbTemplate");
        $scope.nodes = [
            "node1", 
            "node2"
        ];
        $scope.otherNodes = [
            "node4", 
            "node5", 
            "node6"
        ];
        $scope.anchors = [
            "Top", 
            "Right", 
            "Bottom", 
            "Left"
        ];
        $scope.createEndpoint = function (nodeId) {
            var node = $scope.jsPlumbNodesById[nodeId];
            if (node) {
                var anchors = $scope.anchors.subtract(node.anchors);
                console.log("anchors: ", anchors);
                if (anchors && anchors.length > 0) {
                    var anchor = anchors.first();
                    node.anchors.push(anchor);
                    node.endpoints.push($scope.jsPlumb.addEndpoint(node.el, {
                        anchor: anchor,
                        isSource: true,
                        isTarget: true,
                        maxConnections: -1
                    }));
                }
            }
        };
        $scope.expandableEx = '' + '<div class="expandable closed">\n' + '   <div title="The title" class="title">\n' + '     <i class="expandable-indicator"></i> Expandable title\n' + '   </div>\n' + '   <div class="expandable-body well">\n' + '     This is the expandable content...  Note that adding the "well" class isn\'t necessary but makes for a nice inset look\n' + '   </div>\n' + '</div>';
        $scope.editablePropertyEx1 = '<editable-property ng-model="editablePropertyModelEx1" property="property"></editable-property>';
        $scope.editablePropertyModelEx1 = {
            property: "This is editable (hover to edit)"
        };
        $scope.showDeleteOne = new Core.Dialog();
        $scope.showDeleteTwo = new Core.Dialog();
        $scope.fileUploadEx1 = '<div hawtio-file-upload="files" target="test1"></div>';
        $scope.fileUploadEx2 = '<div hawtio-file-upload="files" target="test2" show-files="false"></div>';
        $scope.fileUploadExMode = 'text/html';
        $scope.colorPickerEx = 'My Color ({{myColor}}): <div hawtio-color-picker="myColor"></div>';
        $scope.confirmationEx1 = '' + '<button class="btn" ng-click="showDeleteOne.open()">Delete Stuff</button>\n' + '\n' + '<div hawtio-confirm-dialog="showDeleteOne.show"\n' + 'title="Delete Stuff?"\n' + 'ok-button-text="Yes, Delete the Stuff"\n' + 'cancel-button-text="No, Keep the Stuff"\n' + 'on-cancel="onCancelled(\'One\')"\n' + 'on-ok="onOk(\'One\')">\n' + '  <div class="dialog-body">\n' + '    <p>\n' + '        Are you sure you want to delete all the stuff?\n' + '    </p>\n' + '  </div>\n' + '</div>\n';
        $scope.confirmationEx2 = '' + '<button class="btn" ng-click="showDeleteTwo.open()">Delete Other Stuff</button>\n' + '\n' + '<!-- Use more defaults -->\n' + '<div hawtio-confirm-dialog="showDeleteTwo.show\n"' + '  on-cancel="onCancelled(\'Two\')"\n' + '  on-ok="onOk(\'Two\')">\n' + '  <div class="dialog-body">\n' + '    <p>\n' + '      Are you sure you want to delete all the other stuff?\n' + '    </p>\n' + '  </div>\n' + '</div>';
        $scope.sliderEx1 = '' + '<button class="btn" ng-click="showSlideoutRight = !showSlideoutRight">Show Slideout Right</button>\n' + '<div hawtio-slideout="showSlideoutRight" title="Hey look a slider!">\n' + '   <div class="dialog-body">\n' + '     <div>\n' + '       Here is some content or whatever {{transcludedValue}}\n' + '     </div>\n' + '   </div>\n' + '</div>';
        $scope.sliderEx2 = '' + '<button class="btn" ng-click="showSlideoutLeft = !showSlideoutLeft">Show Slideout Left</button>\n' + '<div hawtio-slideout="showSlideoutLeft" direction="left" title="Hey, another slider!">\n' + '   <div class="dialog-body">\n' + '     <div hawtio-editor="someText" mode="javascript"></div>\n' + '   </div>\n' + '</div>\n';
        $scope.editorEx1 = '' + 'Instance 1\n' + '<div class="row-fluid">\n' + '   <div hawtio-editor="someText" mode="mode" dirty="dirty"></div>\n' + '   <div>Text : {{someText}}</div>\n' + '</div>\n' + '\n' + 'Instance 2 (readonly)\n' + '<div class="row-fluid">\n' + '   <div hawtio-editor="someText" read-only="true" mode="mode" dirty="dirty"></div>\n' + '   <div>Text : {{someText}}</div>\n' + '</div>';
        $scope.transcludedValue = "and this is transcluded";
        $scope.onCancelled = function (number) {
            notification('info', 'cancelled ' + number);
        };
        $scope.onOk = function (number) {
            notification('info', number + ' ok!');
        };
        $scope.showSlideoutRight = false;
        $scope.showSlideoutLeft = false;
        $scope.dirty = false;
        $scope.mode = 'javascript';
        $scope.someText = "var someValue = 0;\n" + "var someFunc = function() {\n" + "  return \"Hello World!\";\n" + "}\n";
        $scope.myColor = "#FF887C";
        $scope.showColorDialog = false;
        $scope.files = [];
        $scope.$watch('files', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                console.log("Files: ", $scope.files);
            }
        }, true);
    }
    UI.UITestController1 = UITestController1;
})(UI || (UI = {}));
var UI;
(function (UI) {
    function HawtioTocDisplay(marked, $location, $anchorScroll, $compile) {
        var _this = this;
        var log = Logger.get("UI");
        return {
            restrict: 'A',
            scope: {
                getContents: '&'
            },
            controller: function ($scope, $element, $attrs) {
                $scope.remaining = -1;
                $scope.render = false;
                $scope.chapters = [];
                $scope.addChapter = function (item) {
                    console.log("Adding: ", item);
                    $scope.chapters.push(item);
                    if (!angular.isDefined(item['text'])) {
                        $scope.fetchItemContent(item);
                    }
                };
                $scope.getTarget = function (id) {
                    if (!id) {
                        return '';
                    }
                    return id.replace(".", "_");
                };
                $scope.getFilename = function (href, ext) {
                    var filename = href.split('/').last();
                    if (ext && !filename.endsWith(ext)) {
                        filename = filename + '.' + ext;
                    }
                    return filename;
                };
                $scope.$watch('remaining', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        if (newValue === 0) {
                            $scope.render = true;
                        }
                    }
                });
                $scope.fetchItemContent = function (item) {
                    var me = $scope;
                    $scope.$eval(function (parent) {
                        parent.getContents({
                            filename: item['filename'],
                            cb: function (data) {
                                if (data) {
                                    if (item['filename'].endsWith(".md")) {
                                        item['text'] = marked(data);
                                    } else {
                                        item['text'] = data;
                                    }
                                    $scope.remaining--;
                                    Core.$apply(me);
                                }
                            }
                        });
                    });
                };
            },
            link: function ($scope, $element, $attrs) {
                var offsetTop = 0;
                var logbar = $('.logbar');
                if (logbar.length) {
                    var offsetTop = logbar.height() + logbar.offset().top;
                }
                var previousHtml = null;
                var html = $element;
                var contentDiv = $("#toc-content");
                if (!contentDiv || !contentDiv.length) {
                    contentDiv = $element;
                }
                var ownerScope = $scope.$parent || $scope;
                var scrollDuration = 1000;
                var linkFilter = $attrs["linkFilter"] || "[hawtio-toc]";
                var htmlName = $attrs["html"];
                if (htmlName) {
                    ownerScope.$watch(htmlName, function () {
                        var htmlText = ownerScope[htmlName];
                        if (htmlText && htmlText !== previousHtml) {
                            previousHtml = htmlText;
                            var markup = $compile(htmlText)(ownerScope);
                            $element.children().remove();
                            $element.append(markup);
                            loadChapters();
                        }
                    });
                } else {
                    loadChapters();
                }
                $(window).scroll(setFirstChapterActive);
                function setFirstChapterActive() {
                    var cutoff = $(window).scrollTop();
                    $element.find("li a").removeClass("active");
                    $('.panel-body').each(function () {
                        var offset = $(this).offset();
                        if (offset && offset.top >= cutoff) {
                            var id = $(this).attr("id");
                            if (id) {
                                var link = html.find("a[chapter-id='" + id + "']");
                                link.addClass("active");
                                return false;
                            }
                        }
                    });
                }
                function loadChapters() {
                    if (!html.get(0).id) {
                        html.get(0).id = 'toc';
                    }
                    $scope.tocId = '#' + html.get(0).id;
                    $scope.remaining = html.find('a').filter(linkFilter).length;
                    html.find('a').filter(linkFilter).each(function (index, a) {
                        log.debug("Found: ", a);
                        var filename = $scope.getFilename(a.href, a.getAttribute('file-extension'));
                        var item = {
                            filename: filename,
                            title: a.textContent,
                            link: a
                        };
                        $scope.addChapter(item);
                    });
                    setTimeout(function () {
                        setFirstChapterActive();
                    }, 100);
                }
                $scope.$watch('render', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        if (newValue) {
                            if (!contentDiv.next('.hawtio-toc').length) {
                                var div = $('<div class="hawtio-toc"></div>');
                                div.appendTo(contentDiv);
                                var selectedChapter = $location.search()["chapter"];
                                $scope.chapters.forEach(function (chapter, index) {
                                    log.debug("index:", index);
                                    var panel = $('<div></div>');
                                    var panelHeader = null;
                                    var chapterId = $scope.getTarget(chapter['filename']);
                                    var link = chapter["link"];
                                    if (link) {
                                        link.setAttribute("chapter-id", chapterId);
                                    }
                                    if (index > 0) {
                                        panelHeader = $('<div class="panel-title"><a class="toc-back" href="">Back to Contents</a></div>');
                                    }
                                    var panelBody = $('<div class="panel-body" id="' + chapterId + '">' + chapter['text'] + '</div>');
                                    if (panelHeader) {
                                        panel.append(panelHeader).append(panelBody);
                                    } else {
                                        panel.append(panelBody);
                                    }
                                    panel.hide().appendTo(div).fadeIn(1000);
                                    if (chapterId === selectedChapter) {
                                        scrollToChapter(chapterId);
                                    }
                                });
                                var pageTop = contentDiv.offset().top - offsetTop;
                                div.find('a.toc-back').each(function (index, a) {
                                    $(a).click(function (e) {
                                        e.preventDefault();
                                        $('body').animate({
                                            scrollTop: pageTop
                                        }, 2000);
                                    });
                                });
                                html.find('a').filter(linkFilter).each(function (index, a) {
                                    var href = a.href;
                                    var filename = $scope.getFilename(href, a.getAttribute('file-extension'));
                                    $(a).click(function (e) {
                                        e.preventDefault();
                                        var chapterId = $scope.getTarget(filename);
                                        $location.search("chapter", chapterId);
                                        Core.$apply(ownerScope);
                                        scrollToChapter(chapterId);
                                        return true;
                                    });
                                });
                            }
                        }
                    }
                });
                ownerScope.$on("$locationChangeSuccess", function (event, current, previous) {
                    setTimeout(function () {
                        var currentChapter = $location.search()["chapter"];
                        scrollToChapter(currentChapter);
                    }, 50);
                });
                function scrollToChapter(chapterId) {
                    log.debug("selected chapter changed: " + chapterId);
                    if (chapterId) {
                        var target = '#' + chapterId;
                        var top = 0;
                        var targetElements = $(target);
                        if (targetElements.length) {
                            var offset = targetElements.offset();
                            if (offset) {
                                top = offset.top - offsetTop;
                            }
                            $('body').animate({
                                scrollTop: top
                            }, scrollDuration);
                        }
                    }
                }
            }
        };
    }
    UI.HawtioTocDisplay = HawtioTocDisplay;
})(UI || (UI = {}));
var UI;
(function (UI) {
    UI.log = Logger.get("UI");
    UI.scrollBarWidth = null;
    function getIfSet(attribute, $attr, def) {
        if (attribute in $attr) {
            var wantedAnswer = $attr[attribute];
            if (wantedAnswer && !wantedAnswer.isBlank()) {
                return wantedAnswer;
            }
        }
        return def;
    }
    UI.getIfSet = getIfSet;
    function observe($scope, $attrs, key, defValue, callbackFunc) {
        if (typeof callbackFunc === "undefined") { callbackFunc = null; }
        $attrs.$observe(key, function (value) {
            if (!angular.isDefined(value)) {
                $scope[key] = defValue;
            } else {
                $scope[key] = value;
            }
            if (angular.isDefined(callbackFunc) && callbackFunc) {
                callbackFunc($scope[key]);
            }
        });
    }
    UI.observe = observe;
    function getScrollbarWidth() {
        if (!angular.isDefined(UI.scrollBarWidth)) {
            var div = document.createElement('div');
            div.innerHTML = '<div style="width:50px;height:50px;position:absolute;left:-50px;top:-50px;overflow:auto;"><div style="width:1px;height:100px;"></div></div>';
            div = div.firstChild;
            document.body.appendChild(div);
            UI.scrollBarWidth = div.offsetWidth - div.clientWidth;
            document.body.removeChild(div);
        }
        return UI.scrollBarWidth;
    }
    UI.getScrollbarWidth = getScrollbarWidth;
})(UI || (UI = {}));
var UI;
(function (UI) {
    UI.pluginName = 'hawtio-ui';
    UI.templatePath = 'app/ui/html/';
    angular.module(UI.pluginName, [
        'bootstrap', 
        'ngResource', 
        'hawtioCore', 
        'ui', 
        'ui.bootstrap'
    ]).config(function ($routeProvider) {
        $routeProvider.when('/ui/test', {
            templateUrl: UI.templatePath + 'test.html'
        });
    }).factory('UI', function () {
        return UI;
    }).directive('hawtioConfirmDialog', function () {
        return new UI.ConfirmDialog();
    }).directive('hawtioSlideout', function () {
        return new UI.SlideOut();
    }).directive('hawtioPager', function () {
        return new UI.TablePager();
    }).directive('hawtioEditor', function ($parse) {
        return UI.Editor($parse);
    }).directive('hawtioColorPicker', function () {
        return new UI.ColorPicker();
    }).directive('hawtioFileUpload', function () {
        return new UI.FileUpload();
    }).directive('expandable', function () {
        return new UI.Expandable();
    }).directive('gridster', function () {
        return new UI.GridsterDirective();
    }).directive('editableProperty', function ($parse) {
        return new UI.EditableProperty($parse);
    }).directive('hawtioViewport', function () {
        return new UI.ViewportHeight();
    }).directive('hawtioHorizontalViewport', function () {
        return new UI.HorizontalViewport();
    }).directive('hawtioRow', function () {
        return new UI.DivRow();
    }).directive('hawtioJsplumb', function () {
        return new UI.JSPlumb();
    }).directive('zeroClipboard', function ($parse) {
        return UI.ZeroClipboardDirective($parse);
    }).directive('hawtioAutoDropdown', function () {
        return UI.AutoDropDown;
    }).directive('hawtioMessagePanel', function () {
        return new UI.MessagePanel();
    }).directive('hawtioInfoPanel', function () {
        return new UI.InfoPanel();
    }).directive('hawtioAutoColumns', function () {
        return new UI.AutoColumns();
    }).directive('hawtioTemplatePopover', function ($templateCache, $compile, $document) {
        return UI.TemplatePopover($templateCache, $compile, $document);
    }).directive('hawtioTocDisplay', function (marked, $location, $anchorScroll, $compile) {
        return UI.HawtioTocDisplay(marked, $location, $anchorScroll, $compile);
    }).run(function (helpRegistry) {
        helpRegistry.addDevDoc("ui1", 'app/ui/doc/developerPage1.md');
        helpRegistry.addDevDoc("ui2", 'app/ui/doc/developerPage2.md');
    });
    hawtioPluginLoader.addModule(UI.pluginName);
})(UI || (UI = {}));
var UI;
(function (UI) {
    var ViewportHeight = (function () {
        function ViewportHeight() {
            this.restrict = 'A';
            this.link = function ($scope, $element, $attrs) {
                var lastHeight = 0;
                var resizeFunc = function () {
                    var neighbor = (angular).element($attrs['hawtioViewport']);
                    var container = (angular).element($attrs['containingDiv']);
                    var start = neighbor.position().top + neighbor.height();
                    var myHeight = container.height() - start;
                    if (angular.isDefined($attrs['heightAdjust'])) {
                        var heightAdjust = $attrs['heightAdjust'].toNumber();
                    }
                    myHeight = myHeight + heightAdjust;
                    $element.css({
                        height: myHeight,
                        'min-height': myHeight
                    });
                    if (lastHeight !== myHeight) {
                        lastHeight = myHeight;
                        $element.trigger('resize');
                    }
                };
                resizeFunc();
                $scope.$watch(resizeFunc);
                $().resize(function () {
                    resizeFunc();
                    Core.$apply($scope);
                    return false;
                });
            };
        }
        return ViewportHeight;
    })();
    UI.ViewportHeight = ViewportHeight;    
    var HorizontalViewport = (function () {
        function HorizontalViewport() {
            this.restrict = 'A';
            this.link = function ($scope, $element, $attrs) {
                var adjustParent = angular.isDefined($attrs['adjustParent']) && Core.parseBooleanValue($attrs['adjustParent']);
                $element.get(0).addEventListener("DOMNodeInserted", function () {
                    var canvas = $element.children();
                    $element.height(canvas.outerHeight(true));
                    if (adjustParent) {
                        $element.parent().height($element.outerHeight(true) + UI.getScrollbarWidth());
                    }
                });
            };
        }
        return HorizontalViewport;
    })();
    UI.HorizontalViewport = HorizontalViewport;    
})(UI || (UI = {}));
var UI;
(function (UI) {
    function ZeroClipboardDirective($parse) {
        return {
            restrict: 'A',
            link: function ($scope, $element, $attr) {
                var clip = new (window).ZeroClipboard($element.get(0), {
                    moviePath: "img/ZeroClipboard.swf"
                });
                clip.on('complete', function (client, args) {
                    if (args.text && angular.isString(args.text)) {
                        notification('info', "Copied text to clipboard: " + args.text.truncate(20));
                    }
                    Core.$apply($scope);
                });
                if ('useCallback' in $attr) {
                    var func = $parse($attr['useCallback']);
                    if (func) {
                        func($scope, {
                            clip: clip
                        });
                    }
                }
            }
        };
    }
    UI.ZeroClipboardDirective = ZeroClipboardDirective;
})(UI || (UI = {}));
var Wiki;
(function (Wiki) {
    function CamelController($scope, $location, $routeParams, localStorage, workspace, wikiRepository, jolokia) {
        Wiki.initScope($scope, $routeParams, $location);
        Camel.initEndpointChooserScope($scope, $location, localStorage, workspace, jolokia);
        $scope.schema = Camel.getConfiguredCamelModel();
        $scope.modified = false;
        $scope.findProfileCamelContext = true;
        $scope.camelSelectionDetails = {
            selectedCamelContextId: null,
            selectedRouteId: null
        };
        $scope.isValid = function (nav) {
            return nav && nav.isValid(workspace);
        };
        $scope.camelSubLevelTabs = [
            {
                content: '<i class="icon-picture"></i> Canvas',
                title: "Edit the diagram in a draggy droppy way",
                isValid: function (workspace) {
                    return true;
                },
                href: function () {
                    return Wiki.startLink($scope.branch) + "/camel/canvas/" + $scope.pageId;
                }
            }, 
            {
                content: '<i class=" icon-sitemap"></i> Tree',
                title: "View the routes as a tree",
                isValid: function (workspace) {
                    return true;
                },
                href: function () {
                    return Wiki.startLink($scope.branch) + "/camel/properties/" + $scope.pageId;
                }
            }
        ];
        var routeModel = _apacheCamelModel.definitions.route;
        routeModel["_id"] = "route";
        $scope.addDialog = new Core.Dialog();
        $scope.addDialog.options["dialogClass"] = "modal-large";
        $scope.addDialog.options["cssClass"] = "modal-large";
        $scope.paletteItemSearch = "";
        $scope.paletteTree = new Folder("Palette");
        $scope.paletteActivations = [
            "Routing_aggregate"
        ];
        angular.forEach(_apacheCamelModel.definitions, function (value, key) {
            if (value.group) {
                var group = (key === "route") ? $scope.paletteTree : $scope.paletteTree.getOrElse(value.group);
                if (!group.key) {
                    group.key = value.group;
                }
                value["_id"] = key;
                var title = value["title"] || key;
                var node = new Folder(title);
                node.key = group.key + "_" + key;
                node["nodeModel"] = value;
                var imageUrl = Camel.getRouteNodeIcon(value);
                node.icon = imageUrl;
                var tooltip = value["tooltip"] || value["description"] || '';
                node.tooltip = tooltip;
                group.children.push(node);
            }
        });
        $scope.componentTree = new Folder("Endpoints");
        $scope.$watch("componentNames", function () {
            var componentNames = $scope.componentNames;
            if (componentNames && componentNames.length) {
                $scope.componentTree = new Folder("Endpoints");
                angular.forEach($scope.componentNames, function (endpointName) {
                    var category = Camel.getEndpointCategory(endpointName);
                    var groupName = category.label || "Core";
                    var groupKey = category.id || groupName;
                    var group = $scope.componentTree.getOrElse(groupName);
                    var value = Camel.getEndpointConfig(endpointName, category);
                    var key = endpointName;
                    var label = value["label"] || endpointName;
                    var node = new Folder(label);
                    node.key = groupKey + "_" + key;
                    node.key = key;
                    node["nodeModel"] = value;
                    var tooltip = value["tooltip"] || value["description"] || label;
                    var imageUrl = url(value["icon"] || Camel.endpointIcon);
                    node.icon = imageUrl;
                    node.tooltip = tooltip;
                    group.children.push(node);
                });
            }
        });
        $scope.componentActivations = [
            "bean"
        ];
        $scope.$watch('addDialog.show', function () {
            if ($scope.addDialog.show) {
                setTimeout(function () {
                    $('#submit').focus();
                }, 50);
            }
        });
        $scope.$on("hawtio.form.modelChange", onModelChangeEvent);
        $scope.onRootTreeNode = function (rootTreeNode) {
            $scope.rootTreeNode = rootTreeNode;
            rootTreeNode.data = $scope.camelContextTree;
        };
        $scope.addNode = function () {
            if ($scope.nodeXmlNode) {
                $scope.addDialog.open();
            } else {
                addNewNode(routeModel);
            }
        };
        $scope.onPaletteSelect = function (node) {
            $scope.selectedPaletteNode = (node && node["nodeModel"]) ? node : null;
            if ($scope.selectedPaletteNode) {
                $scope.selectedComponentNode = null;
            }
            console.log("Selected " + $scope.selectedPaletteNode + " : " + $scope.selectedComponentNode);
        };
        $scope.onComponentSelect = function (node) {
            $scope.selectedComponentNode = (node && node["nodeModel"]) ? node : null;
            if ($scope.selectedComponentNode) {
                $scope.selectedPaletteNode = null;
                var nodeName = node.key;
                console.log("loading endpoint schema for node " + nodeName);
                $scope.loadEndpointSchema(nodeName);
                $scope.selectedComponentName = nodeName;
            }
            console.log("Selected " + $scope.selectedPaletteNode + " : " + $scope.selectedComponentNode);
        };
        $scope.selectedNodeModel = function () {
            var nodeModel = null;
            if ($scope.selectedPaletteNode) {
                nodeModel = $scope.selectedPaletteNode["nodeModel"];
                $scope.endpointConfig = null;
            } else if ($scope.selectedComponentNode) {
                var endpointConfig = $scope.selectedComponentNode["nodeModel"];
                var endpointSchema = $scope.endpointSchema;
                nodeModel = $scope.schema.definitions.endpoint;
                $scope.endpointConfig = {
                    key: $scope.selectedComponentNode.key,
                    schema: endpointSchema,
                    details: endpointConfig
                };
            }
            return nodeModel;
        };
        $scope.addAndCloseDialog = function () {
            var nodeModel = $scope.selectedNodeModel();
            if (nodeModel) {
                addNewNode(nodeModel);
            } else {
                console.log("WARNING: no nodeModel!");
            }
            $scope.addDialog.close();
        };
        $scope.removeNode = function () {
            if ($scope.selectedFolder && $scope.treeNode) {
                $scope.selectedFolder.detach();
                $scope.treeNode.remove();
                $scope.selectedFolder = null;
                $scope.treeNode = null;
            }
        };
        $scope.canDelete = function () {
            return $scope.selectedFolder ? true : false;
        };
        $scope.isActive = function (nav) {
            if (angular.isString(nav)) {
                return workspace.isLinkActive(nav);
            }
            var fn = nav.isActive;
            if (fn) {
                return fn(workspace);
            }
            return workspace.isLinkActive(nav.href());
        };
        $scope.save = function () {
            if ($scope.rootTreeNode) {
                var xmlNode = Camel.generateXmlFromFolder($scope.rootTreeNode);
                if (xmlNode) {
                    var text = Core.xmlNodeToString(xmlNode);
                    if (text) {
                        var commitMessage = $scope.commitMessage || "Updated page " + $scope.pageId;
                        wikiRepository.putPage($scope.branch, $scope.pageId, text, commitMessage, function (status) {
                            Wiki.onComplete(status);
                            notification("success", "Saved " + $scope.pageId);
                            $scope.modified = false;
                            goToView();
                            Core.$apply($scope);
                        });
                    }
                }
            }
        };
        $scope.cancel = function () {
            console.log("cancelling...");
        };
        $scope.$watch('workspace.tree', function () {
            if (!$scope.git) {
                setTimeout(updateView, 50);
            }
        });
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateView, 50);
        });
        function getFolderXmlNode(treeNode) {
            var routeXmlNode = Camel.createFolderXmlTree(treeNode, null);
            if (routeXmlNode) {
                $scope.nodeXmlNode = routeXmlNode;
            }
            return routeXmlNode;
        }
        $scope.onNodeSelect = function (folder, treeNode) {
            $scope.selectedFolder = folder;
            $scope.treeNode = treeNode;
            $scope.propertiesTemplate = null;
            $scope.diagramTemplate = null;
            $scope.nodeXmlNode = null;
            if (folder) {
                $scope.nodeData = Camel.getRouteFolderJSON(folder);
                $scope.nodeDataChangedFields = {};
            }
            var nodeName = Camel.getFolderCamelNodeId(folder);
            var routeXmlNode = getFolderXmlNode(treeNode);
            if (nodeName) {
                $scope.nodeModel = Camel.getCamelSchema(nodeName);
                if ($scope.nodeModel) {
                    $scope.propertiesTemplate = "app/wiki/html/camelPropertiesEdit.html";
                }
                $scope.diagramTemplate = "app/camel/html/routes.html";
                Core.$apply($scope);
            }
        };
        $scope.onNodeDragEnter = function (node, sourceNode) {
            var nodeFolder = node.data;
            var sourceFolder = sourceNode.data;
            if (nodeFolder && sourceFolder) {
                var nodeId = Camel.getFolderCamelNodeId(nodeFolder);
                var sourceId = Camel.getFolderCamelNodeId(sourceFolder);
                if (nodeId && sourceId) {
                    if (sourceId === "route") {
                        return nodeId === "route";
                    }
                    return true;
                }
            }
            return false;
        };
        $scope.onNodeDrop = function (node, sourceNode, hitMode, ui, draggable) {
            var nodeFolder = node.data;
            var sourceFolder = sourceNode.data;
            if (nodeFolder && sourceFolder) {
                var nodeId = Camel.getFolderCamelNodeId(nodeFolder);
                var sourceId = Camel.getFolderCamelNodeId(sourceFolder);
                if (nodeId === "route") {
                    if (sourceId === "route") {
                        if (hitMode === "over") {
                            hitMode = "after";
                        }
                    } else {
                        hitMode = "over";
                    }
                } else {
                    if (Camel.acceptOutput(nodeId)) {
                        hitMode = "over";
                    } else {
                        if (hitMode !== "before") {
                            hitMode = "after";
                        }
                    }
                }
                console.log("nodeDrop nodeId: " + nodeId + " sourceId: " + sourceId + " hitMode: " + hitMode);
                sourceNode.move(node, hitMode);
            }
        };
        updateView();
        function addNewNode(nodeModel) {
            var doc = $scope.doc || document;
            var parentFolder = $scope.selectedFolder || $scope.camelContextTree;
            var key = nodeModel["_id"];
            var beforeNode = null;
            if (!key) {
                console.log("WARNING: no id for model " + JSON.stringify(nodeModel));
            } else {
                var treeNode = $scope.treeNode;
                if (key === "route") {
                    treeNode = $scope.rootTreeNode;
                } else {
                    if (!treeNode) {
                        var root = $scope.rootTreeNode;
                        var children = root.getChildren();
                        if (!children || !children.length) {
                            addNewNode(Camel.getCamelSchema("route"));
                            children = root.getChildren();
                        }
                        if (children && children.length) {
                            treeNode = children[children.length - 1];
                        } else {
                            console.log("Could not add a new route to the empty tree!");
                            return;
                        }
                    }
                    var parentId = Camel.getFolderCamelNodeId(treeNode.data);
                    if (!Camel.acceptOutput(parentId)) {
                        beforeNode = treeNode.getNextSibling();
                        treeNode = treeNode.getParent() || treeNode;
                    }
                }
                if (treeNode) {
                    var node = doc.createElement(key);
                    parentFolder = treeNode.data;
                    var addedNode = Camel.addRouteChild(parentFolder, node);
                    if (addedNode) {
                        var added = treeNode.addChild(addedNode, beforeNode);
                        if (added) {
                            getFolderXmlNode(added);
                            added.expand(true);
                            added.select(true);
                            added.activate(true);
                        }
                    }
                }
            }
        }
        function onModelChangeEvent(event, name) {
            if ($scope.nodeData) {
                var fieldMap = $scope.nodeDataChangedFields;
                if (fieldMap) {
                    if (fieldMap[name]) {
                        onNodeDataChanged();
                    } else {
                        fieldMap[name] = true;
                    }
                }
            }
        }
        function onNodeDataChanged() {
            $scope.modified = true;
            var selectedFolder = $scope.selectedFolder;
            if ($scope.treeNode && selectedFolder) {
                var routeXmlNode = getFolderXmlNode($scope.treeNode);
                if (routeXmlNode) {
                    var nodeName = routeXmlNode.localName;
                    var nodeSettings = Camel.getCamelSchema(nodeName);
                    if (nodeSettings) {
                        Camel.updateRouteNodeLabelAndTooltip(selectedFolder, routeXmlNode, nodeSettings);
                        $scope.treeNode.render(false, false);
                    }
                }
                selectedFolder["camelNodeData"] = $scope.nodeData;
            }
        }
        function onResults(response) {
            var text = response.text;
            if (text) {
                var tree = Camel.loadCamelTree(text, $scope.pageId);
                if (tree) {
                    $scope.camelContextTree = tree;
                }
            } else {
                console.log("No XML found for page " + $scope.pageId);
            }
            Core.$applyLater($scope);
        }
        function updateView() {
            $scope.loadEndpointNames();
            $scope.pageId = Wiki.pageId($routeParams, $location);
            console.log("Has page id: " + $scope.pageId + " with $routeParams " + JSON.stringify($routeParams));
            if (Git.getGitMBean(workspace)) {
                $scope.git = wikiRepository.getPage($scope.branch, $scope.pageId, $scope.objectId, onResults);
            }
        }
        function goToView() {
        }
    }
    Wiki.CamelController = CamelController;
})(Wiki || (Wiki = {}));
var Wiki;
(function (Wiki) {
    function CamelCanvasController($scope, $element, workspace, jolokia, wikiRepository) {
        $scope.addDialog = new Core.Dialog();
        $scope.propertiesDialog = new Core.Dialog();
        $scope.modified = false;
        $scope.camelIgnoreIdForLabel = Camel.ignoreIdForLabel(localStorage);
        $scope.camelMaximumLabelWidth = Camel.maximumLabelWidth(localStorage);
        $scope.camelMaximumTraceOrDebugBodyLength = Camel.maximumTraceOrDebugBodyLength(localStorage);
        $scope.$watch("camelContextTree", function () {
            var tree = $scope.camelContextTree;
            $scope.rootFolder = tree;
            $scope.folders = Camel.addFoldersToIndex($scope.rootFolder);
            var doc = Core.pathGet(tree, [
                "xmlDocument"
            ]);
            if (doc) {
                $scope.doc = doc;
                reloadRouteIds();
                onRouteSelectionChanged();
            }
        });
        $scope.addAndCloseDialog = function () {
            var nodeModel = $scope.selectedNodeModel();
            if (nodeModel) {
                addNewNode(nodeModel);
            }
            $scope.addDialog.close();
        };
        $scope.removeNode = function () {
            var folder = getSelectedOrRouteFolder();
            if (folder) {
                var nodeName = Camel.getFolderCamelNodeId(folder);
                folder.detach();
                if ("route" === nodeName) {
                    $scope.selectedRouteId = null;
                }
                updateSelection(null);
                treeModified();
            }
        };
        $scope.doLayout = function () {
            $scope.drawnRouteId = null;
            onRouteSelectionChanged();
        };
        function createEndpointURI(endpointScheme, slashesText, endpointPath, endpointParameters) {
            console.log("scheme " + endpointScheme + " path " + endpointPath + " parameters " + endpointParameters);
            var uri = ((endpointScheme) ? endpointScheme + ":" + slashesText : "") + (endpointPath ? endpointPath : "");
            var paramText = Core.hashToString(endpointParameters);
            if (paramText) {
                uri += "?" + paramText;
            }
            return uri;
        }
        $scope.updatePropertiesAndCloseDialog = function () {
            Wiki.log.info("old URI is " + $scope.nodeData.uri);
            var uri = createEndpointURI($scope.endpointScheme, ($scope.endpointPathHasSlashes ? "//" : ""), $scope.endpointPath, $scope.endpointParameters);
            Wiki.log.info("new URI is " + uri);
            if (uri) {
                $scope.nodeData.uri = uri;
            }
            var selectedFolder = $scope.selectedFolder;
            if (selectedFolder) {
                var nodeName = Camel.getFolderCamelNodeId(selectedFolder);
                if (nodeName) {
                    var nodeSettings = Camel.getCamelSchema(nodeName);
                    if (nodeSettings) {
                        Camel.updateRouteNodeLabelAndTooltip(selectedFolder, selectedFolder["routeXmlNode"], nodeSettings);
                    }
                }
                selectedFolder["camelNodeData"] = $scope.nodeData;
            }
            $scope.propertiesDialog.close();
            Core.$apply($scope);
            treeModified();
        };
        $scope.save = function () {
            if ($scope.rootFolder) {
                var xmlNode = Camel.generateXmlFromFolder($scope.rootFolder);
                if (xmlNode) {
                    var text = Core.xmlNodeToString(xmlNode);
                    if (text) {
                        var commitMessage = $scope.commitMessage || "Updated page " + $scope.pageId;
                        wikiRepository.putPage($scope.branch, $scope.pageId, text, commitMessage, function (status) {
                            Wiki.onComplete(status);
                            notification("success", "Saved " + $scope.pageId);
                            $scope.modified = false;
                            goToView();
                            Core.$apply($scope);
                        });
                    }
                }
            }
        };
        $scope.cancel = function () {
            console.log("cancelling...");
        };
        $scope.$watch("selectedRouteId", onRouteSelectionChanged);
        function goToView() {
        }
        function addNewNode(nodeModel) {
            var doc = $scope.doc || document;
            var parentFolder = $scope.selectedFolder || $scope.rootFolder;
            var key = nodeModel["_id"];
            if (!key) {
                console.log("WARNING: no id for model " + JSON.stringify(nodeModel));
            } else {
                var treeNode = $scope.selectedFolder;
                if (key === "route") {
                    treeNode = $scope.rootFolder;
                } else {
                    if (!treeNode) {
                        var root = $scope.rootFolder;
                        var children = root.children;
                        if (!children || !children.length) {
                            addNewNode(Camel.getCamelSchema("route"));
                            children = root.children;
                        }
                        if (children && children.length) {
                            treeNode = getRouteFolder($scope.rootFolder, $scope.selectedRouteId) || children[children.length - 1];
                        } else {
                            console.log("Could not add a new route to the empty tree!");
                            return;
                        }
                    }
                    var parentTypeName = Camel.getFolderCamelNodeId(treeNode);
                    if (!Camel.acceptOutput(parentTypeName)) {
                        treeNode = treeNode.parent || treeNode;
                    }
                }
                if (treeNode) {
                    var node = doc.createElement(key);
                    parentFolder = treeNode;
                    var addedNode = Camel.addRouteChild(parentFolder, node);
                    var nodeData = {};
                    if (key === "endpoint" && $scope.endpointConfig) {
                        var key = $scope.endpointConfig.key;
                        if (key) {
                            nodeData["uri"] = key + ":";
                        }
                    }
                    addedNode["camelNodeData"] = nodeData;
                    addedNode["endpointConfig"] = $scope.endpointConfig;
                    if (key === "route") {
                        var count = $scope.routeIds.length;
                        var nodeId = null;
                        while(true) {
                            nodeId = "route" + (++count);
                            if (!$scope.routeIds.find(nodeId)) {
                                break;
                            }
                        }
                        addedNode["routeXmlNode"].setAttribute("id", nodeId);
                        $scope.selectedRouteId = nodeId;
                    }
                }
            }
            treeModified();
        }
        function treeModified() {
            var newDoc = Camel.generateXmlFromFolder($scope.rootFolder);
            var tree = Camel.loadCamelTree(newDoc, $scope.pageId);
            if (tree) {
                $scope.rootFolder = tree;
                $scope.doc = Core.pathGet(tree, [
                    "xmlDocument"
                ]);
            }
            $scope.modified = true;
            reloadRouteIds();
            $scope.doLayout();
            Core.$apply($scope);
        }
        function reloadRouteIds() {
            $scope.routeIds = [];
            var doc = $($scope.doc);
            $scope.camelSelectionDetails.selectedCamelContextId = doc.find("camelContext").attr("id");
            doc.find("route").each(function (idx, route) {
                var id = route.getAttribute("id");
                if (id) {
                    $scope.routeIds.push(id);
                }
            });
        }
        function onRouteSelectionChanged() {
            if ($scope.doc) {
                if (!$scope.selectedRouteId && $scope.routeIds && $scope.routeIds.length) {
                    $scope.selectedRouteId = $scope.routeIds[0];
                }
                if ($scope.selectedRouteId && $scope.selectedRouteId !== $scope.drawnRouteId) {
                    var nodes = [];
                    var links = [];
                    Camel.loadRouteXmlNodes($scope, $scope.doc, $scope.selectedRouteId, nodes, links, getWidth());
                    updateSelection($scope.selectedRouteId);
                    $scope.folders = Camel.addFoldersToIndex($scope.rootFolder);
                    showGraph(nodes, links);
                    $scope.drawnRouteId = $scope.selectedRouteId;
                }
                $scope.camelSelectionDetails.selectedRouteId = $scope.selectedRouteId;
            }
        }
        function showGraph(nodes, links) {
            var width = getWidth();
            var height = Camel.getCanvasHeight($($element));
            layoutGraph(nodes, links, width, height);
            return width;
        }
        function getNodeId(node) {
            if (angular.isNumber(node)) {
                var idx = node;
                node = $scope.nodeStates[idx];
                if (!node) {
                    console.log("Cant find node at " + idx);
                    return "node-" + idx;
                }
            }
            return node.cid || "node-" + node.id;
        }
        function getSelectedOrRouteFolder() {
            return $scope.selectedFolder || getRouteFolder($scope.rootFolder, $scope.selectedRouteId);
        }
        function getContainerElement() {
            var rootElement = $element;
            var containerElement = rootElement.find(".canvas");
            if (!containerElement || !containerElement.length) {
                containerElement = rootElement;
            }
            return containerElement;
        }
        function clearCanvasLayout(jsPlumb) {
            try  {
                jsPlumb.detachEveryConnection();
            } catch (e) {
            }
            try  {
                jsPlumb.deleteEveryEndpoint();
            } catch (e) {
            }
            return jsPlumb;
        }
        function configureCanvasLayout(endpointStyle, arrowStyles, labelStyles) {
        }
        function layoutGraph(nodes, links, width, height) {
            var transitions = [];
            var states = Core.createGraphStates(nodes, links, transitions);
            Wiki.log.debug("links: ", links);
            Wiki.log.debug("transitions: ", transitions);
            $scope.nodeStates = states;
            var containerElement = getContainerElement();
            clearCanvasLayout(jsPlumb);
            containerElement.find("div.component").remove();
            var endpointStyle = [
                "Dot", 
                {
                    radius: 4,
                    cssClass: 'camel-canvas-endpoint'
                }
            ];
            var hoverPaintStyle = {
                strokeStyle: "red",
                lineWidth: 3
            };
            var labelStyles = [
                "Label"
            ];
            var arrowStyles = [
                "Arrow", 
                {
                    location: 1,
                    id: "arrow",
                    length: 8,
                    width: 8,
                    foldback: 0.8
                }
            ];
            jsPlumb.importDefaults({
                Endpoint: endpointStyle,
                HoverPaintStyle: hoverPaintStyle,
                ConnectionOverlays: [
                    arrowStyles, 
                    labelStyles
                ]
            });
            containerElement.css({
                'min-height': '800px'
            });
            var containerHeight = 0;
            angular.forEach(states, function (node) {
                var id = getNodeId(node);
                var div = $("<div class='component window' id='" + id + "' title='" + node.tooltip + "'" + "><img class='nodeIcon' src='" + node.imageUrl + "'>" + "<span class='nodeText'>" + node.label + "</span></div>");
                div.appendTo(containerElement);
                var height = div.height();
                var width = div.width();
                if (height || width) {
                    node.width = width;
                    node.height = height;
                    containerHeight = containerHeight + node.height + 75;
                }
                Wiki.log.debug("node: ", id, " width: ", width, " height: ", height);
            });
            dagre.layout().nodeSep(100).edgeSep(10).rankSep(75).nodes(states).edges(transitions).debugLevel(1).run();
            containerElement.css({
                'min-height': containerHeight
            });
            angular.forEach(states, function (node) {
                var id = getNodeId(node);
                var div = $("#" + id);
                div.css({
                    top: node.dagre.y,
                    left: node.dagre.x
                });
            });
            var nodes = containerElement.find("div.component");
            var connectorStyle = [
                "StateMachine", 
                {
                    curviness: 10,
                    proximityLimit: 50
                }
            ];
            nodes.each(function (i, e) {
                var endpoint = $(e);
                jsPlumb.makeSource(endpoint, {
                    filter: "img.nodeIcon",
                    anchor: "Continuous",
                    connector: connectorStyle,
                    connectorStyle: {
                        strokeStyle: "#666",
                        lineWidth: 3
                    },
                    maxConnections: -1
                });
            });
            containerElement.dblclick(function () {
                $scope.propertiesDialog.open();
            });
            nodes.click(function () {
                var thisNode = $(this);
                var newFlag = !thisNode.hasClass("selected");
                nodes.toggleClass("selected", false);
                thisNode.toggleClass("selected", newFlag);
                var id = thisNode.attr("id");
                updateSelection(newFlag ? id : null);
                Core.$apply($scope);
            });
            nodes.dblclick(function () {
                var id = $(this).attr("id");
                updateSelection(id);
                $scope.propertiesDialog.open();
                Core.$apply($scope);
            });
            jsPlumb.makeTarget(nodes, {
                dropOptions: {
                    hoverClass: "dragHover"
                },
                anchor: "Continuous"
            });
            angular.forEach(links, function (link) {
                jsPlumb.connect({
                    source: getNodeId(link.source),
                    target: getNodeId(link.target)
                });
            });
            jsPlumb.draggable(nodes, {
                containment: '.camel-canvas'
            });
            jsPlumb.bind("dblclick", function (connection, originalEvent) {
                alert("double click on connection from " + connection.sourceId + " to " + connection.targetId);
            });
            jsPlumb.bind("click", function (c) {
                jsPlumb.detach(c);
            });
            jsPlumb.bind("contextmenu", function (component, originalEvent) {
                alert("context menu on component " + component.id);
                originalEvent.preventDefault();
                return false;
            });
            return states;
        }
        function updateSelection(folderOrId) {
            var folder = null;
            if (angular.isString(folderOrId)) {
                var id = folderOrId;
                folder = (id && $scope.folders) ? $scope.folders[id] : null;
            } else {
                folder = folderOrId;
            }
            $scope.selectedFolder = folder;
            folder = getSelectedOrRouteFolder();
            $scope.nodeXmlNode = null;
            $scope.propertiesTemplate = null;
            if (folder) {
                var nodeName = Camel.getFolderCamelNodeId(folder);
                $scope.nodeData = Camel.getRouteFolderJSON(folder);
                $scope.nodeDataChangedFields = {};
                $scope.nodeModel = Camel.getCamelSchema(nodeName);
                if ($scope.nodeModel) {
                    $scope.propertiesTemplate = "app/wiki/html/camelPropertiesEdit.html";
                }
                $scope.selectedEndpoint = null;
                if ("endpoint" === nodeName) {
                    var uri = $scope.nodeData["uri"];
                    if (uri) {
                        var idx = uri.indexOf(":");
                        if (idx > 0) {
                            var endpointScheme = uri.substring(0, idx);
                            var endpointPath = uri.substring(idx + 1);
                            $scope.endpointPathHasSlashes = endpointPath ? false : true;
                            if (endpointPath.startsWith("//")) {
                                endpointPath = endpointPath.substring(2);
                                $scope.endpointPathHasSlashes = true;
                            }
                            idx = endpointPath.indexOf("?");
                            var endpointParameters = {};
                            if (idx > 0) {
                                var parameters = endpointPath.substring(idx + 1);
                                endpointPath = endpointPath.substring(0, idx);
                                endpointParameters = Core.stringToHash(parameters);
                            }
                            $scope.endpointScheme = endpointScheme;
                            $scope.endpointPath = endpointPath;
                            $scope.endpointParameters = endpointParameters;
                            console.log("endpoint " + endpointScheme + " path " + endpointPath + " and parameters " + JSON.stringify(endpointParameters));
                            $scope.loadEndpointSchema(endpointScheme);
                            $scope.selectedEndpoint = {
                                endpointScheme: endpointScheme,
                                endpointPath: endpointPath,
                                parameters: endpointParameters
                            };
                        }
                    }
                }
            }
        }
        function getWidth() {
            var canvasDiv = $($element);
            return canvasDiv.width();
        }
        function getFolderIdAttribute(route) {
            var id = null;
            if (route) {
                var xmlNode = route["routeXmlNode"];
                if (xmlNode) {
                    id = xmlNode.getAttribute("id");
                }
            }
            return id;
        }
        function getRouteFolder(tree, routeId) {
            var answer = null;
            if (tree) {
                angular.forEach(tree.children, function (route) {
                    if (!answer) {
                        var id = getFolderIdAttribute(route);
                        if (routeId === id) {
                            answer = route;
                        }
                    }
                });
            }
            return answer;
        }
    }
    Wiki.CamelCanvasController = CamelCanvasController;
})(Wiki || (Wiki = {}));
var Wiki;
(function (Wiki) {
    function CommitController($scope, $location, $routeParams, $templateCache, workspace, marked, fileExtensionTypeRegistry, wikiRepository) {
        Wiki.initScope($scope, $routeParams, $location);
        $scope.commitId = $scope.objectId;
        $scope.selectedItems = [];
        $scope.dateFormat = 'EEE, MMM d, y : hh:mm:ss a';
        $scope.gridOptions = {
            data: 'commits',
            showFilter: false,
            multiSelect: false,
            selectWithCheckboxOnly: true,
            showSelectionCheckbox: true,
            displaySelectionCheckbox: true,
            selectedItems: $scope.selectedItems,
            filterOptions: {
                filterText: ''
            },
            columnDefs: [
                {
                    field: 'path',
                    displayName: 'File Name',
                    cellTemplate: $templateCache.get('fileCellTemplate.html'),
                    width: "***",
                    cellFilter: ""
                }
            ]
        };
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateView, 50);
        });
        $scope.$watch('workspace.tree', function () {
            if (!$scope.git && Git.getGitMBean(workspace)) {
                setTimeout(updateView, 50);
            }
        });
        $scope.canRevert = function () {
            return $scope.selectedItems.length === 1;
        };
        $scope.revert = function () {
            if ($scope.selectedItems.length > 0) {
                var path = commitPath($scope.selectedItems[0]);
                var objectId = $scope.commitId;
                if (path && objectId) {
                    var commitMessage = "Reverting file " + $scope.pageId + " to previous version " + objectId;
                    wikiRepository.revertTo(objectId, $scope.pageId, commitMessage, function (result) {
                        Wiki.onComplete(result);
                        updateView();
                    });
                }
            }
        };
        function commitPath(commit) {
            return commit.path || commit.name;
        }
        $scope.diff = function () {
            if ($scope.selectedItems.length > 0) {
                var commit = $scope.selectedItems[0];
                var link = Wiki.startLink($scope.branch) + "/diff/" + commitPath(commit) + "/" + $scope.commitId + "/";
                var path = Core.trimLeading(link, "#");
                $location.path(path);
            }
        };
        updateView();
        function updateView() {
            var commitId = $scope.commitId;
            Wiki.loadBranches(wikiRepository, $scope);
            wikiRepository.commitInfo(commitId, function (commitInfo) {
                $scope.commitInfo = commitInfo;
                Core.$apply($scope);
            });
            wikiRepository.commitTree(commitId, function (commits) {
                $scope.commits = commits;
                angular.forEach(commits, function (commit) {
                    commit.fileIconHtml = Wiki.fileIconHtml(commit);
                    commit.fileClass = commit.name.endsWith(".profile") ? "green" : "";
                    var changeType = commit.changeType;
                    var path = commitPath(commit);
                    if (path) {
                        commit.fileLink = Wiki.startLink($scope.branch) + '/version/' + path + '/' + commitId;
                    }
                    if (changeType) {
                        changeType = changeType.toLowerCase();
                        if (changeType.startsWith("a")) {
                            commit.changeClass = "change-add";
                            commit.change = "add";
                            commit.title = "added";
                        } else if (changeType.startsWith("d")) {
                            commit.changeClass = "change-delete";
                            commit.change = "delete";
                            commit.title = "deleted";
                            commit.fileLink = null;
                        } else {
                            commit.changeClass = "change-modify";
                            commit.change = "modify";
                            commit.title = "modified";
                        }
                        commit.changeTypeHtml = '<span class="' + commit.changeClass + '">' + commit.title + '</span>';
                    }
                });
                Core.$apply($scope);
            });
        }
    }
    Wiki.CommitController = CommitController;
})(Wiki || (Wiki = {}));
var Wiki;
(function (Wiki) {
    function DozerMappingsController($scope, $location, $routeParams, workspace, jolokia, wikiRepository, $templateCache) {
        var log = Logger.get("Dozer");
        Wiki.initScope($scope, $routeParams, $location);
        Dozer.schemaConfigure();
        $scope.schema = {};
        $scope.addDialog = new Core.Dialog();
        $scope.propertiesDialog = new Core.Dialog();
        $scope.deleteDialog = false;
        $scope.unmappedFieldsHasValid = false;
        $scope.modified = false;
        $scope.selectedItems = [];
        $scope.mappings = [];
        $scope.schemas = [];
        $scope.aName = '';
        $scope.bName = '';
        $scope.connectorStyle = [
            "Bezier"
        ];
        $scope.main = "";
        $scope.tab = "Draggy Droppy";
        $scope.gridOptions = {
            selectedItems: $scope.selectedItems,
            data: 'mappings',
            displayFooter: false,
            showFilter: false,
            filterOptions: {
                filterText: "searchText"
            },
            columnDefs: [
                {
                    field: 'class_a',
                    displayName: 'From',
                    cellTemplate: '<div class="ngCellText">{{row.entity.class_a.name}}</div>'
                }, 
                {
                    field: 'class_b',
                    displayName: 'To',
                    cellTemplate: '<div class="ngCellText">{{row.entity.class_b.name}}</div>'
                }
            ]
        };
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateView, 50);
        });
        $scope.triggerRefresh = function (timeout) {
            if (typeof timeout === "undefined") { timeout = 500; }
            $scope.main = "";
            setTimeout(function () {
                $scope.main = $templateCache.get("pageTemplate.html");
                Core.$apply($scope);
            }, timeout);
        };
        $scope.disableReload = function () {
            var aValue = Core.pathGet($scope, [
                "selectedMapping", 
                "class_a", 
                "value"
            ]);
            var bValue = Core.pathGet($scope, [
                "selectedMapping", 
                "class_b", 
                "value"
            ]);
            return aValue === $scope.aName && bValue === $scope.bName;
        };
        $scope.doReload = function () {
            $scope.selectedMapping.class_a.value = $scope.aName;
            $scope.selectedMapping.class_b.value = $scope.bName;
            $scope.triggerRefresh();
        };
        $scope.$watch('selectedMapping', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $scope.aName = newValue.class_a.value;
                $scope.bName = newValue.class_b.value;
                $scope.triggerRefresh();
            }
        });
        $scope.$watch('selectedMapping.class_a.value', function (newValue, oldValue) {
            if (newValue !== oldValue && newValue !== '') {
                $scope.fetchProperties(newValue, $scope.selectedMapping.class_a, 'Right');
            }
        });
        $scope.$watch('selectedMapping.class_b.value', function (newValue, oldValue) {
            if (newValue !== oldValue && newValue !== '') {
                $scope.fetchProperties(newValue, $scope.selectedMapping.class_b, 'Left');
            }
        });
        $scope.fetchProperties = function (className, target, anchor) {
            var introspectorMBean = Dozer.getIntrospectorMBean(workspace);
            if (introspectorMBean) {
                jolokia.request({
                    type: 'exec',
                    mbean: introspectorMBean,
                    operation: 'getProperties(java.lang.String)',
                    arguments: [
                        className
                    ]
                }, {
                    success: function (response) {
                        target.error = null;
                        target.properties = response.value;
                        var parentId = '';
                        if (angular.isDefined(target.value)) {
                            parentId = target.value;
                        } else {
                            parentId = target.path;
                        }
                        angular.forEach(target.properties, function (property) {
                            property.id = Core.getUUID();
                            property.path = parentId + '/' + property.displayName;
                            property.anchor = anchor;
                        });
                        Core.$apply($scope);
                    },
                    error: function (response) {
                        target.properties = null;
                        target.error = {
                            'type': response.error_type,
                            'stackTrace': response.error
                        };
                        log.error("got: " + response);
                        Core.$apply($scope);
                    }
                });
            } else {
                log.warn("No dozer introspector mbean found!");
            }
        };
        $scope.getSourceAndTarget = function (info) {
            var sourcePath = info.source.attr('field-path');
            var targetPath = info.target.attr('field-path');
            var sourceField = sourcePath.split('/').last();
            var targetField = sourcePath.split('/').last();
            return {
                from: sourceField,
                to: targetField
            };
        };
        function extractProperty(clazz, prop) {
            return (!clazz || !clazz.properties) ? null : clazz.properties.find(function (property) {
                return property.path.endsWith('/' + prop);
            });
        }
        function addConnectionClickHandler(connection, jsplumb) {
            connection.bind('click', function (connection) {
                jsplumb.detach(connection);
            });
        }
        function getPaintStyle() {
            return {
                strokeStyle: UI.colors.sample(),
                lineWidth: 4
            };
        }
        $scope.jsPlumbCallback = function (jsplumb, nodes, nodesById, connections) {
            angular.forEach($scope.selectedMapping.fields, function (field) {
                var a_property = extractProperty($scope.selectedMapping.class_a, field.a.value);
                var b_property = extractProperty($scope.selectedMapping.class_b, field.b.value);
                if (a_property && b_property) {
                    var a_node = nodesById[a_property.id];
                    var b_node = nodesById[b_property.id];
                    var connection = $scope.jsPlumb.connect({
                        source: a_node.el,
                        target: b_node.el
                    }, {
                        connector: $scope.connectorStyle,
                        maxConnections: 1,
                        paintStyle: getPaintStyle()
                    });
                    addConnectionClickHandler(connection, jsplumb);
                    a_node.connections.push(connection);
                    b_node.connections.push(connection);
                }
            });
            jsplumb.bind('connection', function (info) {
                addConnectionClickHandler(info.connection, jsplumb);
                info.connection.setPaintStyle(getPaintStyle());
                var newMapping = $scope.getSourceAndTarget(info);
                var field = new Dozer.Field(new Dozer.FieldDefinition(newMapping.from), new Dozer.FieldDefinition(newMapping.to));
                $scope.selectedMapping.fields.push(field);
                $scope.modified = true;
                Core.$apply($scope);
            });
            jsplumb.bind('connectionDetached', function (info) {
                var toDetach = $scope.getSourceAndTarget(info);
                var field = new Dozer.Field(new Dozer.FieldDefinition(toDetach.from), new Dozer.FieldDefinition(toDetach.to));
                $scope.selectedMapping.fields.remove(field);
                $scope.modified = true;
                Core.$apply($scope);
            });
        };
        $scope.formatStackTrace = function (exception) {
            return Log.formatStackTrace(exception);
        };
        $scope.addMapping = function () {
            var treeNode = $scope.rootTreeNode;
            if (treeNode) {
                var parentFolder = treeNode.data;
                var mapping = new Dozer.Mapping();
                var addedNode = Dozer.createMappingFolder(mapping, parentFolder);
                var added = treeNode.addChild(addedNode);
                if (added) {
                    added.expand(true);
                    added.select(true);
                    added.activate(true);
                    onTreeModified();
                }
                $scope.mappings.push(mapping);
                $scope.selectedMapping = mapping;
            }
        };
        $scope.addField = function () {
            if ($scope.selectedMapping) {
                Dozer.findUnmappedFields(workspace, $scope.selectedMapping, function (data) {
                    log.warn("has unmapped data fields: " + data);
                    $scope.unmappedFields = data;
                    $scope.unmappedFieldsHasValid = false;
                    $scope.addDialog.open();
                    Core.$apply($scope);
                });
            }
        };
        $scope.addAndCloseDialog = function () {
            log.info("About to add the unmapped fields " + JSON.stringify($scope.unmappedFields, null, "  "));
            if ($scope.selectedMapping) {
                angular.forEach($scope.unmappedFields, function (unmappedField) {
                    if (unmappedField.valid) {
                        var field = new Dozer.Field(new Dozer.FieldDefinition(unmappedField.fromField), new Dozer.FieldDefinition(unmappedField.toField));
                        $scope.selectedMapping.fields.push(field);
                        var treeNode = $scope.selectedMappingTreeNode;
                        var mappingFolder = $scope.selectedMappingFolder;
                        if (treeNode && mappingFolder) {
                            var fieldFolder = Dozer.addMappingFieldFolder(field, mappingFolder);
                            var added = treeNode.addChild(fieldFolder);
                            if (added) {
                                added.expand(true);
                                added.select(true);
                                added.activate(true);
                                onTreeModified();
                            }
                        } else {
                            log.warn("No treenode and folder for mapping node! treeNode " + treeNode + " mappingFolder " + mappingFolder);
                        }
                    }
                });
            }
            $scope.addDialog.close();
        };
        $scope.canDelete = function () {
            return $scope.selectedFolder ? true : false;
        };
        $scope.removeNode = function () {
            if ($scope.selectedFolder && $scope.treeNode) {
                var folder = $scope.selectedFolder;
                var entity = folder.entity;
                if (entity instanceof Dozer.Field) {
                    var mapping = Core.pathGet(folder, [
                        "parent", 
                        "entity"
                    ]);
                    if (mapping) {
                        mapping.fields.remove(entity);
                    }
                }
                $scope.selectedFolder.detach();
                $scope.treeNode.remove();
                $scope.selectedFolder = null;
                $scope.treeNode = null;
                onTreeModified();
            }
        };
        $scope.saveMappings = function () {
            $scope.model.mappings = $scope.mappings;
            var text = Dozer.saveToXmlText($scope.model);
            if (text) {
                var commitMessage = $scope.commitMessage || "Updated page " + $scope.pageId;
                wikiRepository.putPage($scope.branch, $scope.pageId, text, commitMessage, function (status) {
                    Wiki.onComplete(status);
                    $scope.modified = false;
                    notification("success", "Saved " + $scope.pageId);
                    goToView();
                    Core.$apply($scope);
                });
            }
        };
        $scope.save = function () {
            if ($scope.tab === "Draggy Droppy") {
                $scope.saveMappings();
                return;
            }
            if ($scope.model) {
                var model = Dozer.loadModelFromTree($scope.rootTreeNode, $scope.model);
                var text = Dozer.saveToXmlText(model);
                if (text) {
                    var commitMessage = $scope.commitMessage || "Updated page " + $scope.pageId;
                    wikiRepository.putPage($scope.branch, $scope.pageId, text, commitMessage, function (status) {
                        Wiki.onComplete(status);
                        $scope.modified = false;
                        notification("success", "Saved " + $scope.pageId);
                        goToView();
                        Core.$apply($scope);
                    });
                }
            }
        };
        $scope.cancel = function () {
            log.info("cancelling...");
        };
        $scope.onRootTreeNode = function (rootTreeNode) {
            $scope.rootTreeNode = rootTreeNode;
        };
        $scope.onNodeSelect = function (folder, treeNode) {
            $scope.selectedFolder = folder;
            $scope.treeNode = treeNode;
            $scope.propertiesTemplate = null;
            $scope.dozerEntity = null;
            $scope.selectedDescription = "";
            $scope.selectedMapping = null;
            $scope.selectedMappingTreeNode = null;
            $scope.selectedMappingFolder = null;
            if ($scope.removeModelChangeListener) {
                $scope.removeModelChangeListener();
                $scope.removeModelChangeListener = null;
            }
            if (folder) {
                var entity = folder.entity;
                $scope.dozerEntity = entity;
                var propertiesTemplate = "app/wiki/html/dozerPropertiesEdit.html";
                if (entity instanceof Dozer.Field) {
                    $scope.propertiesTemplate = propertiesTemplate;
                    $scope.nodeModel = io_hawt_dozer_schema_Field;
                    $scope.selectedDescription = "Field Mapping";
                    $scope.selectedMapping = Core.pathGet(folder, [
                        "parent", 
                        "entity"
                    ]);
                    $scope.selectedMappingFolder = folder.parent;
                    $scope.selectedMappingTreeNode = treeNode.parent;
                } else if (entity instanceof Dozer.Mapping) {
                    $scope.propertiesTemplate = propertiesTemplate;
                    $scope.nodeModel = io_hawt_dozer_schema_Mapping;
                    $scope.selectedDescription = "Class Mapping";
                    $scope.selectedMapping = entity;
                    $scope.selectedMappingFolder = folder;
                    $scope.selectedMappingTreeNode = treeNode;
                }
                if ($scope.selectedMapping && !$scope.removeModelChangeListener) {
                }
            }
            Core.$apply($scope);
        };
        $scope.onUnmappedFieldChange = function (unmappedField) {
            unmappedField.valid = unmappedField.toField ? true : false;
            $scope.unmappedFieldsHasValid = $scope.unmappedFields.find(function (f) {
                return f.valid;
            });
        };
        function findFieldNames(className, text) {
            var properties = Dozer.findProperties(workspace, className, text, null);
            return properties.map(function (p) {
                return p.name;
            });
        }
        $scope.fromFieldNames = function (text) {
            var className = Core.pathGet($scope.selectedMapping, [
                "class_a", 
                "value"
            ]);
            return findFieldNames(className, text);
        };
        $scope.toFieldNames = function (text) {
            var className = Core.pathGet($scope.selectedMapping, [
                "class_b", 
                "value"
            ]);
            return findFieldNames(className, text);
        };
        $scope.classNames = function (text) {
            if (!text || text.length < 2) {
                return [];
            }
            return Core.time("Time the query of classes", function () {
                log.info("searching for class names with filter '" + text + "'");
                var answer = Dozer.findClassNames(workspace, text);
                log.info("Found results: " + answer.length);
                return answer;
            });
        };
        updateView();
        function updateView() {
            $scope.pageId = Wiki.pageId($routeParams, $location);
            if (Git.getGitMBean(workspace)) {
                $scope.git = wikiRepository.getPage($scope.branch, $scope.pageId, $scope.objectId, onResults);
            }
        }
        function onResults(response) {
            var text = response.text;
            if (text && $scope.responseText !== text) {
                $scope.responseText = text;
                $scope.model = Dozer.loadDozerModel(text, $scope.pageId);
                $scope.mappings = Core.pathGet($scope.model, [
                    "mappings"
                ]);
                $scope.mappingTree = Dozer.createDozerTree($scope.model);
                if (!angular.isDefined($scope.selectedMapping)) {
                    $scope.selectedMapping = $scope.mappings.first();
                }
                $scope.main = $templateCache.get("pageTemplate.html");
            } else {
                log.warn("No XML found for page " + $scope.pageId);
            }
            Core.$apply($scope);
        }
        function onTreeModified() {
            $scope.modified = true;
        }
        function goToView() {
        }
    }
    Wiki.DozerMappingsController = DozerMappingsController;
})(Wiki || (Wiki = {}));
var Wiki;
(function (Wiki) {
    function EditController($scope, $location, $routeParams, fileExtensionTypeRegistry, wikiRepository) {
        Wiki.initScope($scope, $routeParams, $location);
        $scope.entity = {
            source: null
        };
        var format = Wiki.fileFormat($scope.pageId, fileExtensionTypeRegistry);
        var form = null;
        if ((format && format === "javascript") || isCreate()) {
            form = $location.search()["form"];
        }
        var options = {
            mode: {
                name: format
            }
        };
        $scope.codeMirrorOptions = CodeEditor.createEditorSettings(options);
        $scope.modified = false;
        $scope.isValid = function () {
            return $scope.fileName;
        };
        $scope.canSave = function () {
            return !$scope.modified;
        };
        $scope.$watch('entity.source', function (newValue, oldValue) {
            $scope.modified = newValue && oldValue && newValue !== oldValue;
        }, true);
        Wiki.log.debug("path: ", $scope.path);
        $scope.$watch('modified', function (newValue, oldValue) {
            Wiki.log.debug("modified: ", newValue);
        });
        $scope.viewLink = function () {
            return Wiki.viewLink($scope.branch, $scope.pageId, $location, $scope.fileName);
        };
        $scope.cancel = function () {
            goToView();
        };
        $scope.save = function () {
            if ($scope.modified && $scope.fileName) {
                saveTo($scope["pageId"]);
            }
        };
        $scope.create = function () {
            var path = $scope.pageId + "/" + $scope.fileName;
            console.log("creating new file at " + path);
            saveTo(path);
        };
        $scope.onSubmit = function (json, form) {
            if (isCreate()) {
                $scope.create();
            } else {
                $scope.save();
            }
        };
        $scope.onCancel = function (form) {
            setTimeout(function () {
                goToView();
                Core.$apply($scope);
            }, 50);
        };
        updateView();
        function isCreate() {
            return $location.path().startsWith("/wiki/create");
        }
        function updateView() {
            if (isCreate()) {
                updateSourceView();
            } else {
                Wiki.log.debug("Getting page, branch: ", $scope.branch, " pageId: ", $scope.pageId, " objectId: ", $scope.objectId);
                wikiRepository.getPage($scope.branch, $scope.pageId, $scope.objectId, onFileContents);
            }
        }
        function onFileContents(details) {
            var contents = details.text;
            $scope.entity.source = contents;
            $scope.fileName = $scope.pageId.split('/').last();
            Wiki.log.debug("file name: ", $scope.fileName);
            Wiki.log.debug("file details: ", details);
            updateSourceView();
            Core.$apply($scope);
        }
        function updateSourceView() {
            if (form) {
                if (isCreate()) {
                    if (!$scope.fileName) {
                        $scope.fileName = "" + Core.getUUID() + ".json";
                    }
                }
                $scope.sourceView = null;
                if (form === "/") {
                    onFormSchema(_jsonSchema);
                } else {
                    $scope.git = wikiRepository.getPage($scope.branch, form, $scope.objectId, function (details) {
                        onFormSchema(Wiki.parseJson(details.text));
                    });
                }
            } else {
                $scope.sourceView = "app/wiki/html/sourceEdit.html";
            }
        }
        function onFormSchema(json) {
            $scope.formDefinition = json;
            if ($scope.entity.source) {
                $scope.formEntity = Wiki.parseJson($scope.entity.source);
            }
            $scope.sourceView = "app/wiki/html/formEdit.html";
            Core.$apply($scope);
        }
        function goToView() {
            var path = Core.trimLeading($scope.viewLink(), "#");
            Wiki.log.debug("going to view " + path);
            $location.path(Wiki.decodePath(path));
            Wiki.log.debug("location is now " + $location.path());
        }
        function saveTo(path) {
            var commitMessage = $scope.commitMessage || "Updated page " + $scope.pageId;
            var contents = $scope.entity.source;
            if ($scope.formEntity) {
                contents = JSON.stringify($scope.formEntity, null, "  ");
            }
            Wiki.log.debug("Saving file, branch: ", $scope.branch, " path: ", $scope.path);
            wikiRepository.putPage($scope.branch, path, contents, commitMessage, function (status) {
                Wiki.onComplete(status);
                $scope.modified = false;
                notification("success", "Saved " + path);
                goToView();
                Core.$apply($scope);
            });
        }
    }
    Wiki.EditController = EditController;
})(Wiki || (Wiki = {}));
var Wiki;
(function (Wiki) {
    function FormTableController($scope, $location, $routeParams, workspace, wikiRepository) {
        Wiki.initScope($scope, $routeParams, $location);
        $scope.columnDefs = [];
        $scope.gridOptions = {
            data: 'list',
            displayFooter: false,
            showFilter: false,
            filterOptions: {
                filterText: ''
            },
            columnDefs: $scope.columnDefs
        };
        $scope.viewLink = function (row) {
            return childLink(row, "/view");
        };
        $scope.editLink = function (row) {
            return childLink(row, "/edit");
        };
        function childLink(child, prefix) {
            var start = Wiki.startLink($scope.branch);
            var childId = (child) ? child["_id"] || "" : "";
            return Core.createHref($location, start + prefix + "/" + $scope.pageId + "/" + childId);
        }
        var linksColumn = {
            field: '_id',
            displayName: 'Actions',
            cellTemplate: '<div class="ngCellText""><a ng-href="{{viewLink(row.entity)}}" class="btn">View</a> <a ng-href="{{editLink(row.entity)}}" class="btn">Edit</a></div>'
        };
        $scope.$watch('workspace.tree', function () {
            if (!$scope.git && Git.getGitMBean(workspace)) {
                setTimeout(updateView, 50);
            }
        });
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateView, 50);
        });
        var form = $location.search()["form"];
        if (form) {
            wikiRepository.getPage($scope.branch, form, $scope.objectId, onFormData);
        }
        updateView();
        function onResults(response) {
            var list = [];
            var map = Wiki.parseJson(response);
            angular.forEach(map, function (value, key) {
                value["_id"] = key;
                list.push(value);
            });
            $scope.list = list;
            Core.$apply($scope);
        }
        function updateView() {
            var filter = Core.pathGet($scope, [
                "gridOptions", 
                "filterOptions", 
                "filterText"
            ]) || "";
            $scope.git = wikiRepository.jsonChildContents($scope.pageId, "*.json", filter, onResults);
        }
        function onFormData(details) {
            var text = details.text;
            if (text) {
                $scope.formDefinition = Wiki.parseJson(text);
                var columnDefs = [];
                var schema = $scope.formDefinition;
                angular.forEach(schema.properties, function (property, name) {
                    if (name) {
                        if (!Forms.isArrayOrNestedObject(property, schema)) {
                            var colDef = {
                                field: name,
                                displayName: property.description || name,
                                visible: true
                            };
                            columnDefs.push(colDef);
                        }
                    }
                });
                columnDefs.push(linksColumn);
                $scope.columnDefs = columnDefs;
                $scope.gridOptions.columnDefs = columnDefs;
                $scope.tableView = "app/wiki/html/formTableDatatable.html";
            }
        }
        Core.$apply($scope);
    }
    Wiki.FormTableController = FormTableController;
})(Wiki || (Wiki = {}));
var Wiki;
(function (Wiki) {
    function HistoryController($scope, $location, $routeParams, $templateCache, workspace, marked, fileExtensionTypeRegistry, wikiRepository) {
        Wiki.initScope($scope, $routeParams, $location);
        $scope.selectedItems = [];
        $scope.dateFormat = 'EEE, MMM d, y : hh:mm:ss a';
        $scope.gridOptions = {
            data: 'logs',
            showFilter: false,
            selectedItems: $scope.selectedItems,
            showSelectionCheckbox: true,
            displaySelectionCheckbox: true,
            filterOptions: {
                filterText: ''
            },
            columnDefs: [
                {
                    field: 'commitHashText',
                    displayName: 'Change',
                    cellTemplate: $templateCache.get('changeCellTemplate.html'),
                    cellFilter: "",
                    width: "*"
                }, 
                {
                    field: 'date',
                    displayName: 'Modified',
                    cellFilter: "date: dateFormat",
                    width: "**"
                }, 
                {
                    field: 'author',
                    displayName: 'Author',
                    cellFilter: "",
                    width: "**"
                }, 
                {
                    field: 'shortMessage',
                    displayName: 'Message',
                    cellTemplate: '<div class="ngCellText" title="{{row.entity.shortMessage}}">{{row.entity.trimmedMessage}}</div>',
                    cellFilter: "",
                    width: "****"
                }
            ]
        };
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(updateView, 50);
        });
        $scope.$watch('workspace.tree', function () {
            if (!$scope.git && Git.getGitMBean(workspace)) {
                setTimeout(updateView, 50);
            }
        });
        $scope.canRevert = function () {
            return $scope.selectedItems.length === 1 && $scope.selectedItems[0] !== $scope.logs[0];
        };
        $scope.revert = function () {
            if ($scope.selectedItems.length > 0) {
                var objectId = $scope.selectedItems[0].name;
                if (objectId) {
                    var commitMessage = "Reverting file " + $scope.pageId + " to previous version " + objectId;
                    wikiRepository.revertTo(objectId, $scope.pageId, commitMessage, function (result) {
                        Wiki.onComplete(result);
                        updateView();
                    });
                }
            }
        };
        $scope.diff = function () {
            var defaultValue = " ";
            var objectId = defaultValue;
            if ($scope.selectedItems.length > 0) {
                objectId = $scope.selectedItems[0].name || defaultValue;
            }
            var baseObjectId = defaultValue;
            if ($scope.selectedItems.length > 1) {
                baseObjectId = $scope.selectedItems[1].name || defaultValue;
            }
            var link = Wiki.startLink($scope.branch) + "/diff/" + $scope.pageId + "/" + objectId + "/" + baseObjectId;
            var path = Core.trimLeading(link, "#");
            $location.path(path);
        };
        updateView();
        function updateView() {
            var objectId = "";
            var limit = 0;
            $scope.git = wikiRepository.history($scope.branch, objectId, $scope.pageId, limit, function (logArray) {
                angular.forEach(logArray, function (log) {
                    var commitId = log.commitHashText || log.name;
                    log.commitLink = Wiki.startLink($scope.branch) + "/commit/" + $scope.pageId + "/" + commitId;
                });
                $scope.logs = logArray;
                Core.$apply($scope);
            });
            Wiki.loadBranches(wikiRepository, $scope);
        }
    }
    Wiki.HistoryController = HistoryController;
})(Wiki || (Wiki = {}));
var Wiki;
(function (Wiki) {
    function NavBarController($scope, $location, $routeParams, workspace, wikiRepository) {
        Wiki.initScope($scope, $routeParams, $location);
        $scope.createLink = function () {
            var pageId = Wiki.pageId($routeParams, $location);
            return Wiki.createLink($scope.branch, pageId, $location, $scope);
        };
        $scope.sourceLink = function () {
            var path = $location.path();
            var answer = null;
            angular.forEach(Wiki.customViewLinks($scope), function (link) {
                if (path.startsWith(link)) {
                    answer = Core.createHref($location, Wiki.startLink($scope.branch) + "/view" + path.substring(link.length));
                }
            });
            return (!answer && $location.search()["form"]) ? Core.createHref($location, "#" + path, [
                "form"
            ]) : answer;
        };
        $scope.isActive = function (href) {
            if (!href) {
                return false;
            }
            return href.endsWith($routeParams['page']);
        };
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(loadBreadcrumbs, 50);
        });
        loadBreadcrumbs();
        function switchFromViewToCustomLink(breadcrumb, link) {
            var href = breadcrumb.href;
            if (href) {
                breadcrumb.href = href.replace("wiki/view", link);
            }
        }
        function loadBreadcrumbs() {
            var start = Wiki.startLink($scope.branch);
            var href = start + "/view";
            $scope.breadcrumbs = [
                {
                    href: href,
                    name: "root"
                }
            ];
            var path = Wiki.pageId($routeParams, $location);
            var array = path ? path.split("/") : [];
            angular.forEach(array, function (name) {
                if (!name.startsWith("/") && !href.endsWith("/")) {
                    href += "/";
                }
                href += Wiki.encodePath(name);
                if (!name.isBlank()) {
                    $scope.breadcrumbs.push({
                        href: href,
                        name: name
                    });
                }
            });
            var loc = $location.path();
            if ($scope.breadcrumbs.length) {
                var last = $scope.breadcrumbs[$scope.breadcrumbs.length - 1];
                last.name = Wiki.hideFineNameExtensions(last.name);
                var swizzled = false;
                angular.forEach(Wiki.customViewLinks($scope), function (link) {
                    if (!swizzled && loc.startsWith(link)) {
                        switchFromViewToCustomLink($scope.breadcrumbs.last(), Core.trimLeading(link, "/"));
                        swizzled = true;
                    }
                });
                if (!swizzled && $location.search()["form"]) {
                    var lastName = $scope.breadcrumbs.last().name;
                    if (lastName && lastName.endsWith(".json")) {
                        switchFromViewToCustomLink($scope.breadcrumbs[$scope.breadcrumbs.length - 2], "wiki/formTable");
                    }
                }
            }
            var name = null;
            if (loc.startsWith("/wiki/version")) {
                name = ($routeParams["objectId"] || "").substring(0, 6) || "Version";
                $scope.breadcrumbs.push({
                    href: "#" + loc,
                    name: name
                });
            }
            if (loc.startsWith("/wiki/diff")) {
                var v1 = ($routeParams["objectId"] || "").substring(0, 6);
                var v2 = ($routeParams["baseObjectId"] || "").substring(0, 6);
                name = "Diff";
                if (v1) {
                    if (v2) {
                        name += " " + v1 + " " + v2;
                    } else {
                        name += " " + v1;
                    }
                }
                $scope.breadcrumbs.push({
                    href: "#" + loc,
                    name: name
                });
            }
            Core.$apply($scope);
        }
    }
    Wiki.NavBarController = NavBarController;
})(Wiki || (Wiki = {}));
var Wiki;
(function (Wiki) {
    function goToLink(link, $timeout, $location) {
        var href = Core.trimLeading(link, "#");
        $timeout(function () {
            console.log("About to navigate to: " + href);
            $location.url(href);
        }, 100);
    }
    function ViewController($scope, $location, $routeParams, $route, $http, $timeout, workspace, marked, fileExtensionTypeRegistry, wikiRepository, $compile, $templateCache) {
        var log = Logger.get("Wiki");
        Wiki.initScope($scope, $routeParams, $location);
        $scope.fabricTopLevel = "fabric/profiles/";
        $scope.versionId = $scope.branch;
        $scope.profileId = Fabric.pagePathToProfileId($scope.pageId);
        $scope.showProfileHeader = $scope.profileId && $scope.pageId.endsWith(Fabric.profileSuffix) ? true : false;
        $scope.operationCounter = 1;
        $scope.addDialog = new Core.Dialog();
        $scope.renameDialog = new Core.Dialog();
        $scope.moveDialog = new Core.Dialog();
        $scope.deleteDialog = false;
        $scope.isFile = false;
        $scope.createDocumentTree = Wiki.createWizardTree();
        $scope.createDocumentTreeActivations = [
            "camel-spring.xml", 
            "ReadMe.md"
        ];
        $scope.fileExists = {
            exists: false,
            name: ""
        };
        Core.bindModelToSearchParam($scope, $location, "searchText", "q", "");
        Core.reloadWhenParametersChange($route, $scope, $location);
        $scope.gridOptions = {
            data: 'children',
            displayFooter: false,
            selectedItems: [],
            showSelectionCheckbox: true,
            enableSorting: false,
            useExternalSorting: true,
            columnDefs: [
                {
                    field: 'name',
                    displayName: 'Name',
                    cellTemplate: $templateCache.get('fileCellTemplate.html'),
                    headerCellTemplate: $templateCache.get('fileColumnTemplate.html')
                }
            ]
        };
        $scope.childActions = [];
        var maybeUpdateView = Core.throttled(updateView, 1000);
        $scope.$on('wikiBranchesUpdated', function () {
            updateView();
        });
        $scope.createDashboardLink = function () {
            var href = '/wiki/branch/:branch/view/*page';
            var page = $routeParams['page'];
            var title = page ? page.split("/").last() : null;
            var size = angular.toJson({
                size_x: 2,
                size_y: 2
            });
            var answer = "#/dashboard/add?tab=dashboard" + "&href=" + encodeURIComponent(href) + "&size=" + encodeURIComponent(size) + "&routeParams=" + encodeURIComponent(angular.toJson($routeParams));
            if (title) {
                answer += "&title=" + encodeURIComponent(title);
            }
            return answer;
        };
        $scope.displayClass = function () {
            if (!$scope.children || $scope.children.length === 0) {
                return "";
            }
            return "span9";
        };
        $scope.parentLink = function () {
            var start = Wiki.startLink($scope.branch);
            var prefix = start + "/view";
            var parts = $scope.pageId.split("/");
            var path = "/" + parts.first(parts.length - 1).join("/");
            return Core.createHref($location, prefix + path, []);
        };
        $scope.childLink = function (child) {
            var start = Wiki.startLink($scope.branch);
            var prefix = start + "/view";
            var postFix = "";
            var path = Wiki.encodePath(child.path);
            if (child.directory) {
                var formPath = path + ".form";
                var children = $scope.children;
                if (children) {
                    var formFile = children.find(function (child) {
                        return child['path'] === formPath;
                    });
                    if (formFile) {
                        prefix = start + "/formTable";
                        postFix = "?form=" + formPath;
                    }
                }
            } else {
                var xmlNamespaces = child.xmlNamespaces;
                if (xmlNamespaces && xmlNamespaces.length) {
                    if (xmlNamespaces.any(function (ns) {
                        return Wiki.camelNamespaces.any(ns);
                    })) {
                        prefix = start + "/camel/canvas";
                    } else if (xmlNamespaces.any(function (ns) {
                        return Wiki.dozerNamespaces.any(ns);
                    })) {
                        prefix = start + "/dozer/mappings";
                    } else {
                        console.log("child " + path + " has namespaces " + xmlNamespaces);
                    }
                }
                if (child.path.endsWith(".form")) {
                    postFix = "?form=/";
                } else if (Wiki.isIndexPage(child.path)) {
                    prefix = start + "/book";
                }
            }
            return Core.createHref($location, prefix + path + postFix, [
                "form"
            ]);
        };
        $scope.fileName = function (entity) {
            return Wiki.hideFineNameExtensions(entity.name);
        };
        $scope.fileClass = function (entity) {
            if (entity.name.has(".profile")) {
                return "green";
            }
            return "";
        };
        $scope.fileIconHtml = function (entity) {
            return Wiki.fileIconHtml(entity);
        };
        $scope.format = Wiki.fileFormat($scope.pageId, fileExtensionTypeRegistry);
        var options = {
            readOnly: true,
            mode: {
                name: $scope.format
            }
        };
        $scope.codeMirrorOptions = CodeEditor.createEditorSettings(options);
        $scope.editLink = function () {
            var pageName = ($scope.directory) ? $scope.readMePath : $scope.pageId;
            return (pageName) ? Wiki.editLink($scope.branch, pageName, $location) : null;
        };
        $scope.branchLink = function (branch) {
            if (branch) {
                return Wiki.branchLink(branch, $scope.pageId, $location);
            }
            return null;
        };
        $scope.historyLink = "#/wiki" + ($scope.branch ? "/branch/" + $scope.branch : "") + "/history/" + $scope.pageId;
        $scope.$watch('workspace.tree', function () {
            if (!$scope.git && Git.getGitMBean(workspace)) {
                setTimeout(maybeUpdateView, 50);
            }
        });
        $scope.$on("$routeChangeSuccess", function (event, current, previous) {
            setTimeout(maybeUpdateView, 50);
        });
        $scope.onSubmit = function (json, form) {
            notification("success", "Submitted form :" + form.get(0).name + " data: " + JSON.stringify(json));
        };
        $scope.onCancel = function (form) {
            notification("success", "Clicked cancel!");
        };
        $scope.onCreateDocumentSelect = function (node) {
            $scope.selectedCreateDocumentTemplate = node ? node.entity : null;
            checkFileExists(getNewDocumentPath());
        };
        $scope.$watch("newDocumentName", function () {
            checkFileExists(getNewDocumentPath());
        });
        $scope.openAddDialog = function () {
            $scope.newDocumentName = null;
            $scope.addDialog.open();
        };
        $scope.addAndCloseDialog = function (fileName) {
            $scope.newDocumentName = fileName;
            var template = $scope.selectedCreateDocumentTemplate;
            var path = getNewDocumentPath();
            if (!template || !path) {
                return;
            }
            var name = Wiki.fileName(path);
            var fileName = name;
            var folder = Wiki.fileParent(path);
            var exemplar = template.exemplar;
            var commitMessage = "Created " + template.label;
            var exemplarUri = url("/app/wiki/exemplar/" + exemplar);
            if (template.folder) {
                notification("success", "Creating new folder " + name);
                wikiRepository.createDirectory($scope.branch, path, commitMessage, function (status) {
                    $scope.addDialog.close();
                    Core.$apply($scope);
                    var link = Wiki.viewLink($scope.branch, path, $location);
                    goToLink(link, $timeout, $location);
                });
            } else if (template.profile) {
                if (name.endsWith(".profile")) {
                    name = name.replace(".profile", '');
                }
                Fabric.createProfile(workspace.jolokia, $scope.branch, name, [
                    'default'
                ], function () {
                    $scope.addDialog.close();
                    notification('success', 'Created profile ' + name);
                    Fabric.newConfigFile(workspace.jolokia, $scope.branch, name, 'ReadMe.md', function () {
                        notification('info', 'Created empty Readme.md in profile ' + name);
                        Core.$apply($scope);
                        var contents = "Here's an empty ReadMe.md for '" + name + "', please update!";
                        Fabric.saveConfigFile(workspace.jolokia, $scope.branch, name, 'ReadMe.md', contents.encodeBase64(), function () {
                            notification('info', 'Updated Readme.md in profile ' + name);
                            Core.$apply($scope);
                            var link = Wiki.viewLink($scope.branch, path + '.profile', $location);
                            goToLink(link, $timeout, $location);
                        }, function (response) {
                            notification('error', 'Failed to set ReadMe.md data in profile ' + name + ' due to ' + response.error);
                            Core.$apply($scope);
                        });
                    }, function (response) {
                        notification('error', 'Failed to create ReadMe.md in profile ' + name + ' due to ' + response.error);
                        Core.$apply($scope);
                    });
                }, function (response) {
                    notification('error', 'Failed to create profile ' + name + ' due to ' + response.error);
                    Core.$apply($scope);
                });
            } else {
                notification("success", "Creating new document " + name);
                $http.get(exemplarUri).success(function (contents) {
                    wikiRepository.putPage($scope.branch, path, contents, commitMessage, function (status) {
                        console.log("Created file " + name);
                        Wiki.onComplete(status);
                        $scope.git = wikiRepository.getPage($scope.branch, folder, $scope.objectId, function (details) {
                            var link = null;
                            if (details && details.children) {
                                console.log("scanned the directory " + details.children.length + " children");
                                var child = details.children.find(function (c) {
                                    return c.name === fileName;
                                });
                                if (child) {
                                    link = $scope.childLink(child);
                                } else {
                                    console.log("Could not find name '" + fileName + "' in the list of file names " + JSON.stringify(details.children.map(function (c) {
                                        return c.name;
                                    })));
                                }
                            }
                            if (!link) {
                                console.log("WARNING: could not find the childLink so reverting to the wiki edit page!");
                                link = Wiki.editLink($scope.branch, path, $location);
                            }
                            $scope.addDialog.close();
                            Core.$apply($scope);
                            goToLink(link, $timeout, $location);
                        });
                    });
                });
            }
            $scope.addDialog.close();
        };
        $scope.openDeleteDialog = function () {
            if ($scope.gridOptions.selectedItems.length) {
                $scope.selectedFileHtml = "<ul>" + $scope.gridOptions.selectedItems.map(function (file) {
                    return "<li>" + file.name + "</li>";
                }).sort().join("") + "</ul>";
                $scope.deleteDialog = true;
            } else {
                console.log("No items selected right now! " + $scope.gridOptions.selectedItems);
            }
        };
        $scope.deleteAndCloseDialog = function () {
            var files = $scope.gridOptions.selectedItems;
            var fileCount = files.length;
            console.log("Deleting selection: " + files);
            angular.forEach(files, function (file, idx) {
                var path = $scope.pageId + "/" + file.name;
                console.log("About to delete " + path);
                $scope.git = wikiRepository.removePage($scope.branch, path, null, function (result) {
                    if (idx + 1 === fileCount) {
                        $scope.gridOptions.selectedItems.splice(0, fileCount);
                        var message = Core.maybePlural(fileCount, "document");
                        notification("success", "Deleted " + message);
                        Core.$apply($scope);
                        updateView();
                    }
                });
            });
            $scope.deleteDialog = false;
        };
        $scope.$watch("newFileName", function () {
            var path = getRenameFilePath();
            if ($scope.originalRenameFilePath === path) {
                $scope.fileExists = {
                    exsits: false,
                    name: null
                };
            } else {
                checkFileExists(path);
            }
        });
        $scope.openRenameDialog = function () {
            var name = null;
            if ($scope.gridOptions.selectedItems.length) {
                var selected = $scope.gridOptions.selectedItems[0];
                name = selected.name;
            }
            if (name) {
                $scope.newFileName = name;
                $scope.originalRenameFilePath = getRenameFilePath();
                $scope.renameDialog.open();
                $timeout(function () {
                    $('#renameFileName').focus();
                }, 50);
            } else {
                console.log("No items selected right now! " + $scope.gridOptions.selectedItems);
            }
        };
        $scope.renameAndCloseDialog = function () {
            if ($scope.gridOptions.selectedItems.length) {
                var selected = $scope.gridOptions.selectedItems[0];
                var newPath = getRenameFilePath();
                if (selected && newPath) {
                    var oldName = selected.name;
                    var newName = Wiki.fileName(newPath);
                    var oldPath = $scope.pageId + "/" + oldName;
                    console.log("About to rename file " + oldPath + " to " + newPath);
                    $scope.git = wikiRepository.rename($scope.branch, oldPath, newPath, null, function (result) {
                        notification("success", "Renamed file to  " + newName);
                        $scope.renameDialog.close();
                        Core.$apply($scope);
                        updateView();
                    });
                }
            }
            $scope.renameDialog.close();
        };
        $scope.openMoveDialog = function () {
            if ($scope.gridOptions.selectedItems.length) {
                $scope.moveFolder = $scope.pageId;
                $scope.moveDialog.open();
                $timeout(function () {
                    $('#moveFolder').focus();
                }, 50);
            } else {
                console.log("No items selected right now! " + $scope.gridOptions.selectedItems);
            }
        };
        $scope.moveAndCloseDialog = function () {
            var files = $scope.gridOptions.selectedItems;
            var fileCount = files.length;
            var moveFolder = $scope.moveFolder;
            var oldFolder = $scope.pageId;
            if (moveFolder && fileCount && moveFolder !== oldFolder) {
                console.log("Moving " + fileCount + " file(s) to " + moveFolder);
                angular.forEach(files, function (file, idx) {
                    var oldPath = oldFolder + "/" + file.name;
                    var newPath = moveFolder + "/" + file.name;
                    console.log("About to move " + oldPath + " to " + newPath);
                    $scope.git = wikiRepository.rename($scope.branch, oldPath, newPath, null, function (result) {
                        if (idx + 1 === fileCount) {
                            $scope.gridOptions.selectedItems.splice(0, fileCount);
                            var message = Core.maybePlural(fileCount, "document");
                            notification("success", "Moved " + message + " to " + newPath);
                            $scope.moveDialog.close();
                            Core.$apply($scope);
                            updateView();
                        }
                    });
                });
            }
            $scope.moveDialog.close();
        };
        $scope.folderNames = function (text) {
            return wikiRepository.completePath($scope.branch, text, true, null);
        };
        setTimeout(maybeUpdateView, 50);
        function isDiffView() {
            var path = $location.path();
            return path && (path.startsWith("/wiki/diff") || path.startsWith("/wiki/branch/" + $scope.branch + "/diff"));
        }
        function updateView() {
            if (isDiffView()) {
                var baseObjectId = $routeParams["baseObjectId"];
                $scope.git = wikiRepository.diff($scope.objectId, baseObjectId, $scope.pageId, onFileDetails);
            } else {
                $scope.git = wikiRepository.getPage($scope.branch, $scope.pageId, $scope.objectId, onFileDetails);
            }
            Wiki.loadBranches(wikiRepository, $scope);
        }
        $scope.updateView = updateView;
        function viewContents(pageName, contents) {
            $scope.sourceView = null;
            var format = null;
            if (isDiffView()) {
                format = "diff";
            } else {
                format = Wiki.fileFormat(pageName, fileExtensionTypeRegistry) || $scope.format;
            }
            if ("markdown" === format) {
                $scope.html = contents ? marked(contents) : "";
                $scope.html = $compile($scope.html)($scope);
            } else if (format && format.startsWith("html")) {
                $scope.html = contents;
                $compile($scope.html)($scope);
            } else {
                var form = null;
                if (format && format === "javascript") {
                    form = $location.search()["form"];
                }
                $scope.source = contents;
                $scope.form = form;
                if (form) {
                    $scope.sourceView = null;
                    if (form === "/") {
                        onFormSchema(_jsonSchema);
                    } else {
                        $scope.git = wikiRepository.getPage($scope.branch, form, $scope.objectId, function (details) {
                            onFormSchema(Wiki.parseJson(details.text));
                        });
                    }
                } else {
                    $scope.sourceView = "app/wiki/html/sourceView.html";
                }
            }
            Core.$apply($scope);
        }
        function onFormSchema(json) {
            $scope.formDefinition = json;
            if ($scope.source) {
                $scope.formEntity = Wiki.parseJson($scope.source);
            }
            $scope.sourceView = "app/wiki/html/formView.html";
            Core.$apply($scope);
        }
        function onFileDetails(details) {
            var contents = details.text;
            $scope.directory = details.directory;
            if (details && details.format) {
                $scope.format = details.format;
            } else {
                $scope.format = Wiki.fileFormat($scope.pageId, fileExtensionTypeRegistry);
            }
            $scope.codeMirrorOptions.mode.name = $scope.format;
            $scope.children = null;
            if (details.directory) {
                var directories = details.children.filter(function (dir) {
                    return dir.directory && !dir.name.has(".profile");
                });
                var profiles = details.children.filter(function (dir) {
                    return dir.directory && dir.name.has(".profile");
                });
                var files = details.children.filter(function (file) {
                    return !file.directory;
                });
                directories = directories.sortBy(function (dir) {
                    return dir.name;
                });
                profiles = profiles.sortBy(function (dir) {
                    return dir.name;
                });
                files = files.sortBy(function (file) {
                    return file.name;
                }).sortBy(function (file) {
                    return file.name.split('.').last();
                });
                $scope.children = (Array).create(directories, profiles, files);
            }
            $scope.html = null;
            $scope.source = null;
            $scope.readMePath = null;
            $scope.isFile = false;
            if ($scope.children) {
                var item = $scope.children.find(function (info) {
                    var name = (info.name || "").toLowerCase();
                    var ext = Wiki.fileExtension(name);
                    return name && ext && ((name.startsWith("readme.") || name === "readme") || (name.startsWith("index.") || name === "index"));
                });
                if (item) {
                    var pageName = item.path;
                    $scope.readMePath = pageName;
                    wikiRepository.getPage($scope.branch, pageName, $scope.objectId, function (readmeDetails) {
                        viewContents(pageName, readmeDetails.text);
                    });
                }
            } else {
                var pageName = $scope.pageId;
                viewContents(pageName, contents);
                $scope.isFile = true;
            }
            Core.$apply($scope);
        }
        function checkFileExists(path) {
            $scope.operationCounter += 1;
            var counter = $scope.operationCounter;
            if (path) {
                wikiRepository.exists($scope.branch, path, function (result) {
                    if ($scope.operationCounter === counter) {
                        console.log("for path " + path + " got result " + result);
                        $scope.fileExists.exists = result ? true : false;
                        $scope.fileExists.name = result ? result.name : null;
                        Core.$apply($scope);
                    } else {
                    }
                });
            }
        }
        $scope.getContents = function (filename, cb) {
            var pageId = filename;
            if ($scope.directory) {
                pageId = $scope.pageId + '/' + filename;
            } else {
                var pathParts = $scope.pageId.split('/');
                pathParts = pathParts.remove(pathParts.last());
                pathParts.push(filename);
                pageId = pathParts.join('/');
            }
            log.debug("pageId: ", $scope.pageId);
            log.debug("branch: ", $scope.branch);
            log.debug("filename: ", filename);
            log.debug("using pageId: ", pageId);
            wikiRepository.getPage($scope.branch, pageId, undefined, function (data) {
                cb(data.text);
            });
        };
        function getNewDocumentPath() {
            var template = $scope.selectedCreateDocumentTemplate;
            if (!template) {
                console.log("No template selected");
                return null;
            }
            var exemplar = template.exemplar;
            var name = $scope.newDocumentName || exemplar;
            if (name.indexOf('.') < 0) {
                var idx = exemplar.lastIndexOf(".");
                if (idx > 0) {
                    name += exemplar.substring(idx);
                }
            }
            var folder = $scope.pageId;
            if ($scope.isFile) {
                var idx = folder.lastIndexOf("/");
                if (idx <= 0) {
                    folder = "";
                } else {
                    folder = folder.substring(0, idx);
                }
            }
            var fileName = name;
            var idx = name.lastIndexOf("/");
            if (idx > 0) {
                folder += "/" + name.substring(0, idx);
                name = name.substring(idx + 1);
            }
            folder = Core.trimLeading(folder, "/");
            return folder + (folder ? "/" : "") + name;
        }
        function getRenameFilePath() {
            return ($scope.pageId && $scope.newFileName) ? $scope.pageId + "/" + $scope.newFileName : null;
        }
    }
    Wiki.ViewController = ViewController;
})(Wiki || (Wiki = {}));
var Wiki;
(function (Wiki) {
    Wiki.log = Logger.get("Wiki");
    Wiki.camelNamespaces = [
        "http://camel.apache.org/schema/spring", 
        "http://camel.apache.org/schema/blueprint"
    ];
    Wiki.springNamespaces = [
        "http://www.springframework.org/schema/beans"
    ];
    Wiki.droolsNamespaces = [
        "http://drools.org/schema/drools-spring"
    ];
    Wiki.dozerNamespaces = [
        "http://dozer.sourceforge.net"
    ];
    Wiki.activemqNamespaces = [
        "http://activemq.apache.org/schema/core"
    ];
    Wiki.excludeAdjustmentPrefixes = [
        "http://", 
        "https://", 
        "#"
    ];
    Wiki.customWikiViewPages = [
        "/formTable", 
        "/camel/diagram", 
        "/camel/canvas", 
        "/camel/properties", 
        "/dozer/mappings"
    ];
    Wiki.hideExtentions = [
        ".profile"
    ];
    Wiki.documentTemplates = [
        {
            label: "Folder",
            tooltip: "Create a new folder to contain documents",
            folder: true,
            icon: "/app/wiki/img/folder.gif",
            exemplar: "New Folder"
        }, 
        {
            label: "Fabric Profile",
            tooltip: "Create a new empty Fabric profile.  Using a hyphen ('-') will create a folder heirarchy, for example 'my-awesome-profile' will be available via the path 'my/awesome/profile'.",
            profile: true,
            addClass: "icon-book green",
            exemplar: "user-profile"
        }, 
        {
            label: "Properties File",
            tooltip: "A properties file typically used to configure Java classes",
            exemplar: "properties-file.properties"
        }, 
        {
            label: "Markdown Document",
            tooltip: "A basic markup document using the Markdown wiki markup, particularly useful for ReadMe files in directories",
            exemplar: "ReadMe.md"
        }, 
        {
            label: "HTML Document",
            tooltip: "A HTML document you can edit directly using the HTML markup",
            exemplar: "document.html"
        }, 
        {
            label: "XML Document",
            tooltip: "An empty XML document",
            exemplar: "document.xml"
        }, 
        {
            label: "Integration Flows",
            tooltip: "Camel routes for defining your integration flows",
            children: [
                {
                    label: "Camel XML document",
                    tooltip: "A vanilla Camel XML document for integration flows",
                    icon: "/app/camel/img/camel.png",
                    exemplar: "camel.xml"
                }, 
                {
                    label: "Camel OSGi Blueprint XML document",
                    tooltip: "A vanilla Camel XML document for integration flows when using OSGi Blueprint",
                    icon: "/app/camel/img/camel.png",
                    exemplar: "camel-blueprint.xml"
                }, 
                {
                    label: "Camel Spring XML document",
                    tooltip: "A vanilla Camel XML document for integration flows when using the Spring framework",
                    icon: "/app/camel/img/camel.png",
                    exemplar: "camel-spring.xml"
                }
            ]
        }, 
        {
            label: "Data Mapping Document",
            tooltip: "Dozer based configuration of mapping documents",
            icon: "/app/dozer/img/dozer.gif",
            exemplar: "dozerMapping.xml"
        }
    ];
    function isWikiEnabled(workspace, jolokia, localStorage) {
        return Git.createGitRepository(workspace, jolokia, localStorage) !== null;
    }
    Wiki.isWikiEnabled = isWikiEnabled;
    function customViewLinks($scope) {
        var branch = $scope.branch;
        var prefix = Core.trimLeading(Wiki.startLink(branch), "#");
        return Wiki.customWikiViewPages.map(function (path) {
            return prefix + path;
        });
    }
    Wiki.customViewLinks = customViewLinks;
    function createWizardTree() {
        var root = new Folder("New Documents");
        addCreateWizardFolders(root, Wiki.documentTemplates);
        return root;
    }
    Wiki.createWizardTree = createWizardTree;
    function addCreateWizardFolders(parent, templates) {
        angular.forEach(templates, function (template) {
            var title = template.label || key;
            var node = new Folder(title);
            node.parent = parent;
            node.entity = template;
            var addClass = template.addClass;
            if (addClass) {
                node.addClass = addClass;
            }
            var key = template.exemplar;
            var parentKey = parent.key || "";
            node.key = parentKey ? parentKey + "_" + key : key;
            var icon = template.icon;
            if (icon) {
                node.icon = url(icon);
            }
            var tooltip = template["tooltip"] || template["description"] || '';
            node.tooltip = tooltip;
            if (template["folder"]) {
                node.isFolder = function () {
                    return true;
                };
            }
            parent.children.push(node);
            var children = template.children;
            if (children) {
                addCreateWizardFolders(node, children);
            }
        });
    }
    Wiki.addCreateWizardFolders = addCreateWizardFolders;
    function startLink(branch) {
        var start = "#/wiki";
        if (branch) {
            start += "/branch/" + branch;
        }
        return start;
    }
    Wiki.startLink = startLink;
    function isIndexPage(path) {
        return path && (path.endsWith("index.md") || path.endsWith("index.html") || path.endsWith("index")) ? true : false;
    }
    Wiki.isIndexPage = isIndexPage;
    function viewLink(branch, pageId, $location, fileName) {
        if (typeof fileName === "undefined") { fileName = null; }
        var link = null;
        var start = startLink(branch);
        if (pageId) {
            var view = isIndexPage(pageId) ? "/book/" : "/view/";
            link = start + view + encodePath(Core.trimLeading(pageId, "/"));
        } else {
            var path = $location.path();
            link = "#" + path.replace(/(edit|create)/, "view");
        }
        if (fileName && pageId && pageId.endsWith(fileName)) {
            return link;
        }
        if (fileName) {
            if (!link.endsWith("/")) {
                link += "/";
            }
            link += fileName;
        }
        return link;
    }
    Wiki.viewLink = viewLink;
    function branchLink(branch, pageId, $location, fileName) {
        if (typeof fileName === "undefined") { fileName = null; }
        return viewLink(branch, pageId, $location, fileName);
    }
    Wiki.branchLink = branchLink;
    function editLink(branch, pageId, $location) {
        var link = null;
        var start = startLink(branch);
        if (pageId) {
            link = start + "/edit/" + encodePath(pageId);
        } else {
            var path = $location.path();
            link = "#" + path.replace(/(view|create)/, "edit");
        }
        return link;
    }
    Wiki.editLink = editLink;
    function createLink(branch, pageId, $location, $scope) {
        var path = $location.path();
        var start = startLink(branch);
        var link = null;
        if (pageId) {
            link = start + "/create/" + encodePath(pageId);
        } else {
            link = "#" + path.replace(/(view|edit|formTable)/, "create");
        }
        var idx = link.lastIndexOf("/");
        if (idx > 0 && !$scope.children && !path.startsWith("/wiki/formTable")) {
            link = link.substring(0, idx + 1);
        }
        return link;
    }
    Wiki.createLink = createLink;
    function encodePath(pageId) {
        return pageId.split("/").map(encodeURIComponent).join("/");
    }
    Wiki.encodePath = encodePath;
    function decodePath(pageId) {
        return pageId.split("/").map(decodeURIComponent).join("/");
    }
    Wiki.decodePath = decodePath;
    function fileFormat(name, fileExtensionTypeRegistry) {
        var extension = fileExtension(name);
        var answer = null;
        angular.forEach(fileExtensionTypeRegistry, function (array, key) {
            if (array.indexOf(extension) >= 0) {
                answer = key;
            }
        });
        return answer;
    }
    Wiki.fileFormat = fileFormat;
    function fileName(path) {
        if (path) {
            var idx = path.lastIndexOf("/");
            if (idx > 0) {
                return path.substring(idx + 1);
            }
        }
        return path;
    }
    Wiki.fileName = fileName;
    function fileParent(path) {
        if (path) {
            var idx = path.lastIndexOf("/");
            if (idx > 0) {
                return path.substring(0, idx);
            }
        }
        return "";
    }
    Wiki.fileParent = fileParent;
    function hideFineNameExtensions(name) {
        if (name) {
            angular.forEach(Wiki.hideExtentions, function (extension) {
                if (name.endsWith(extension)) {
                    name = name.substring(0, name.length - extension.length);
                }
            });
        }
        return name;
    }
    Wiki.hideFineNameExtensions = hideFineNameExtensions;
    function fileIconHtml(row) {
        var name = row.name;
        var directory = row.directory;
        var xmlNamespaces = row.xmlNamespaces;
        var entity = row.entity;
        if (entity) {
            name = name || entity.name;
            directory = directory || entity.directory;
            xmlNamespaces = xmlNamespaces || entity.xmlNamespaces;
        }
        var css = null;
        var icon = null;
        var extension = fileExtension(name);
        if (xmlNamespaces && xmlNamespaces.length) {
            if (xmlNamespaces.any(function (ns) {
                return Wiki.camelNamespaces.any(ns);
            })) {
                icon = "/app/camel/img/camel.png";
            } else if (xmlNamespaces.any(function (ns) {
                return Wiki.dozerNamespaces.any(ns);
            })) {
                icon = "/app/dozer/img/dozer.gif";
            } else if (xmlNamespaces.any(function (ns) {
                return Wiki.activemqNamespaces.any(ns);
            })) {
                icon = "/app/activemq/img/message_broker.png";
            } else {
                console.log("file " + name + " has namespaces " + xmlNamespaces);
            }
        }
        if (!icon) {
            if (directory) {
                if ("profile" === extension) {
                    css = "icon-book";
                } else {
                    css = "icon-folder-close";
                }
            } else if ("xml" === extension) {
                css = "icon-file-text";
            } else {
                css = "icon-file-alt";
            }
        }
        if (icon) {
            return "<img src='" + url(icon) + "'>";
        } else {
            return "<i class='" + css + "'></i>";
        }
    }
    Wiki.fileIconHtml = fileIconHtml;
    function iconClass(row) {
        var name = row.getProperty("name");
        var extension = fileExtension(name);
        var directory = row.getProperty("directory");
        if (directory) {
            return "icon-folder-close";
        }
        if ("xml" === extension) {
            return "icon-cog";
        }
        return "icon-file-alt";
    }
    Wiki.iconClass = iconClass;
    function initScope($scope, $routeParams, $location) {
        $scope.pageId = Wiki.pageId($routeParams, $location);
        $scope.branch = $routeParams["branch"] || $location.search()["branch"];
        $scope.objectId = $routeParams["objectId"];
        $scope.startLink = Wiki.startLink($scope.branch);
        $scope.historyLink = startLink($scope.branch) + "/history/" + ($scope.pageId || "");
    }
    Wiki.initScope = initScope;
    function loadBranches(wikiRepository, $scope) {
        wikiRepository.branches(function (response) {
            $scope.branches = response.sortBy(function (v) {
                return Core.versionToSortableString(v);
            }, true);
            if (!$scope.branch && $scope.branches.find(function (branch) {
                return branch === "master";
            })) {
                $scope.branch = "master";
            }
        });
    }
    Wiki.loadBranches = loadBranches;
    function pageId($routeParams, $location) {
        var pageId = $routeParams['page'];
        if (!pageId) {
            for(var i = 0; i < 100; i++) {
                var value = $routeParams['path' + i];
                if (angular.isDefined(value)) {
                    if (!pageId) {
                        pageId = value;
                    } else {
                        pageId += "/" + value;
                    }
                } else {
                    break;
                }
            }
            return pageId || "/";
        }
        if (!pageId) {
            pageId = pageIdFromURI($location.path());
        }
        return pageId;
    }
    Wiki.pageId = pageId;
    function pageIdFromURI(url) {
        var wikiPrefix = "/wiki/";
        if (url && url.startsWith(wikiPrefix)) {
            var idx = url.indexOf("/", wikiPrefix.length + 1);
            if (idx > 0) {
                return url.substring(idx + 1, url.length);
            }
        }
        return null;
    }
    Wiki.pageIdFromURI = pageIdFromURI;
    function fileExtension(name) {
        if (name.indexOf('#') > 0) {
            name = name.substring(0, name.indexOf('#'));
        }
        return Core.fileExtension(name, "markdown");
    }
    Wiki.fileExtension = fileExtension;
    function onComplete(status) {
        console.log("Completed operation with status: " + JSON.stringify(status));
    }
    Wiki.onComplete = onComplete;
    function parseJson(text) {
        if (text) {
            try  {
                return JSON.parse(text);
            } catch (e) {
                notification("error", "Failed to parse JSON: " + e);
            }
        }
        return null;
    }
    Wiki.parseJson = parseJson;
    function adjustHref($scope, $location, href, fileExtension) {
        var extension = fileExtension ? "." + fileExtension : "";
        var path = $location.path();
        var folderPath = path;
        var idx = path.lastIndexOf("/");
        if (idx > 0) {
            var lastName = path.substring(idx + 1);
            if (lastName.indexOf(".") >= 0) {
                folderPath = path.substring(0, idx);
            }
        }
        if (href.startsWith('../')) {
            var parts = href.split('/');
            var pathParts = folderPath.split('/');
            var parents = parts.filter(function (part) {
                return part === "..";
            });
            parts = parts.last(parts.length - parents.length);
            pathParts = pathParts.first(pathParts.length - parents.length);
            return '#' + pathParts.join('/') + '/' + parts.join('/') + extension + $location.hash();
        }
        if (href.startsWith('/')) {
            return Wiki.branchLink($scope.branch, href + extension, $location) + extension;
        }
        if (!Wiki.excludeAdjustmentPrefixes.any(function (exclude) {
            return href.startsWith(exclude);
        })) {
            return '#' + folderPath + "/" + href + extension + $location.hash();
        } else {
            return null;
        }
    }
    Wiki.adjustHref = adjustHref;
})(Wiki || (Wiki = {}));
var Wiki;
(function (Wiki) {
    var pluginName = 'wiki';
    Wiki.templatePath = 'app/wiki/html/';
    angular.module(pluginName, [
        'bootstrap', 
        'ui.bootstrap.dialog', 
        'ui.bootstrap.tabs', 
        'ngResource', 
        'hawtioCore', 
        'hawtio-ui', 
        'tree', 
        'camel'
    ]).config(function ($routeProvider) {
        angular.forEach([
            "", 
            "/branch/:branch"
        ], function (path) {
            $routeProvider.when('/wiki' + path + '/view', {
                templateUrl: 'app/wiki/html/viewPage.html',
                reloadOnSearch: false
            }).when('/wiki' + path + '/view/*page', {
                templateUrl: 'app/wiki/html/viewPage.html',
                reloadOnSearch: false
            }).when('/wiki' + path + '/book/*page', {
                templateUrl: 'app/wiki/html/viewBook.html',
                reloadOnSearch: false
            }).when('/wiki' + path + '/create/*page', {
                templateUrl: 'app/wiki/html/createPage.html'
            }).when('/wiki' + path + '/edit/*page', {
                templateUrl: 'app/wiki/html/editPage.html'
            }).when('/wiki' + path + '/version/*page/:objectId', {
                templateUrl: 'app/wiki/html/viewPage.html'
            }).when('/wiki' + path + '/history/*page', {
                templateUrl: 'app/wiki/html/history.html'
            }).when('/wiki' + path + '/commit/*page/:objectId', {
                templateUrl: 'app/wiki/html/commit.html'
            }).when('/wiki' + path + '/diff/*page/:objectId/:baseObjectId', {
                templateUrl: 'app/wiki/html/viewPage.html',
                reloadOnSearch: false
            }).when('/wiki' + path + '/formTable/*page', {
                templateUrl: 'app/wiki/html/formTable.html'
            }).when('/wiki' + path + '/dozer/mappings/*page', {
                templateUrl: 'app/wiki/html/dozerMappings.html'
            }).when('/wiki' + path + '/camel/diagram/*page', {
                templateUrl: 'app/wiki/html/camelDiagram.html'
            }).when('/wiki' + path + '/camel/canvas/*page', {
                templateUrl: 'app/wiki/html/camelCanvas.html'
            }).when('/wiki' + path + '/camel/properties/*page', {
                templateUrl: 'app/wiki/html/camelProperties.html'
            });
        });
    }).factory('wikiRepository', function (workspace, jolokia, localStorage) {
        return new Wiki.GitWikiRepository(function () {
            return Git.createGitRepository(workspace, jolokia, localStorage);
        });
    }).factory('fileExtensionTypeRegistry', function () {
        return {
            "markdown": [
                "md", 
                "markdown", 
                "mdown", 
                "mkdn", 
                "mkd"
            ],
            "htmlmixed": [
                "html", 
                "xhtml", 
                "htm"
            ],
            "text/x-java": [
                "java"
            ],
            "text/x-scala": [
                "scala"
            ],
            "javascript": [
                "js", 
                "json", 
                "javascript", 
                "jscript", 
                "ecmascript", 
                "form"
            ],
            "xml": [
                "xml", 
                "xsd", 
                "wsdl", 
                "atom"
            ],
            "properties": [
                "properties"
            ]
        };
    }).filter('fileIconClass', function () {
        return Wiki.iconClass;
    }).directive('wikiHrefAdjuster', function ($location) {
        return {
            restrict: 'A',
            link: function ($scope, $element, $attr) {
                $element.bind('DOMNodeInserted', function (event) {
                    var ays = $element.find('a');
                    angular.forEach(ays, function (a) {
                        if (a.hasAttribute('no-adjust')) {
                            return;
                        }
                        a = $(a);
                        var href = (a.attr('href') || "").trim();
                        if (href) {
                            var fileExtension = a.attr('file-extension');
                            var newValue = Wiki.adjustHref($scope, $location, href, fileExtension);
                            if (newValue) {
                                a.attr('href', newValue);
                            }
                        }
                    });
                    var imgs = $element.find('img');
                    angular.forEach(imgs, function (a) {
                        if (a.hasAttribute('no-adjust')) {
                            return;
                        }
                        a = $(a);
                        var href = (a.attr('src') || "").trim();
                        if (href) {
                            if (href.startsWith("/")) {
                                href = url(href);
                                a.attr('src', href);
                                a.attr('no-adjust', 'true');
                            }
                        }
                    });
                });
            }
        };
    }).run(function ($location, workspace, viewRegistry, jolokia, localStorage, layoutFull, helpRegistry) {
        viewRegistry['wiki'] = layoutFull;
        helpRegistry.addUserDoc('wiki', 'app/wiki/doc/help.md', function () {
            return Wiki.isWikiEnabled(workspace, jolokia, localStorage);
        });
        workspace.topLevelTabs.push({
            content: "Wiki",
            title: "View and edit wiki pages",
            isValid: function (workspace) {
                return Wiki.isWikiEnabled(workspace, jolokia, localStorage);
            },
            href: function () {
                return "#/wiki/view";
            },
            isActive: function (workspace) {
                return workspace.isLinkActive("/wiki") && !workspace.linkContains("fabric", "profiles") && !workspace.linkContains("editFeatures");
            }
        });
    });
    hawtioPluginLoader.addModule(pluginName);
})(Wiki || (Wiki = {}));
var Wiki;
(function (Wiki) {
    var GitWikiRepository = (function () {
        function GitWikiRepository(factoryMethod) {
            this.factoryMethod = factoryMethod;
            this.directoryPrefix = "";
        }
        GitWikiRepository.prototype.exists = function (branch, path, fn) {
            var fullPath = this.getPath(path);
            this.git().exists(branch, fullPath, fn);
        };
        GitWikiRepository.prototype.completePath = function (branch, completionText, directoriesOnly, fn) {
            return this.git().completePath(branch, completionText, directoriesOnly, fn);
        };
        GitWikiRepository.prototype.getPage = function (branch, path, objectId, fn) {
            var _this = this;
            var git = this.git();
            path = path || "/";
            if (git) {
                if (objectId) {
                    var blobPath = this.getLogPath(path);
                    git.getContent(objectId, blobPath, function (content) {
                        var details = {
                            text: content,
                            directory: false
                        };
                        fn(details);
                    });
                } else {
                    var fullPath = this.getPath(path);
                    git.read(branch, fullPath, function (details) {
                        var children = details.children;
                        angular.forEach(children, function (child) {
                            var path = child.path;
                            if (path) {
                                var directoryPrefix = "/" + _this.directoryPrefix;
                                if (path.startsWith(directoryPrefix)) {
                                    path = "/" + path.substring(directoryPrefix.length);
                                    child.path = path;
                                }
                            }
                        });
                        fn(details);
                    });
                }
            }
            return git;
        };
        GitWikiRepository.prototype.diff = function (objectId, baseObjectId, path, fn) {
            var fullPath = this.getLogPath(path);
            var git = this.git();
            if (git) {
                git.diff(objectId, baseObjectId, fullPath, function (content) {
                    var details = {
                        text: content,
                        format: "diff",
                        directory: false
                    };
                    fn(details);
                });
            }
            return git;
        };
        GitWikiRepository.prototype.commitInfo = function (commitId, fn) {
            this.git().commitInfo(commitId, fn);
        };
        GitWikiRepository.prototype.commitTree = function (commitId, fn) {
            this.git().commitTree(commitId, fn);
        };
        GitWikiRepository.prototype.putPage = function (branch, path, contents, commitMessage, fn) {
            var fullPath = this.getPath(path);
            this.git().write(branch, fullPath, commitMessage, contents, fn);
        };
        GitWikiRepository.prototype.createDirectory = function (branch, path, commitMessage, fn) {
            var fullPath = this.getPath(path);
            this.git().createDirectory(branch, fullPath, commitMessage, fn);
        };
        GitWikiRepository.prototype.revertTo = function (objectId, blobPath, commitMessage, fn) {
            var fullPath = this.getLogPath(blobPath);
            this.git().revertTo(objectId, fullPath, commitMessage, fn);
        };
        GitWikiRepository.prototype.rename = function (branch, oldPath, newPath, commitMessage, fn) {
            var fullOldPath = this.getPath(oldPath);
            var fullNewPath = this.getPath(newPath);
            if (!commitMessage) {
                commitMessage = "Renaming page " + oldPath + " to " + newPath;
            }
            this.git().rename(branch, fullOldPath, fullNewPath, commitMessage, fn);
        };
        GitWikiRepository.prototype.removePage = function (branch, path, commitMessage, fn) {
            var fullPath = this.getPath(path);
            if (!commitMessage) {
                commitMessage = "Removing page " + path;
            }
            this.git().remove(branch, fullPath, commitMessage, fn);
        };
        GitWikiRepository.prototype.getPath = function (path) {
            var directoryPrefix = this.directoryPrefix;
            return (directoryPrefix) ? directoryPrefix + path : path;
        };
        GitWikiRepository.prototype.getLogPath = function (path) {
            return Core.trimLeading(this.getPath(path), "/");
        };
        GitWikiRepository.prototype.history = function (branch, objectId, path, limit, fn) {
            var fullPath = this.getLogPath(path);
            var git = this.git();
            if (git) {
                git.history(branch, objectId, fullPath, limit, fn);
            }
            return git;
        };
        GitWikiRepository.prototype.getContent = function (objectId, blobPath, fn) {
            var fullPath = this.getLogPath(blobPath);
            var git = this.git();
            if (git) {
                git.getContent(objectId, fullPath, fn);
            }
            return git;
        };
        GitWikiRepository.prototype.branches = function (fn) {
            var git = this.git();
            if (git) {
                git.branches(fn);
            }
            return git;
        };
        GitWikiRepository.prototype.jsonChildContents = function (path, nameWildcard, search, fn) {
            var fullPath = this.getLogPath(path);
            var git = this.git();
            if (git) {
                git.readJsonChildContent(fullPath, nameWildcard, search, fn);
            }
            return git;
        };
        GitWikiRepository.prototype.git = function () {
            var repository = this.factoryMethod();
            if (!repository) {
                console.log("No repository yet! TODO we should use a local impl!");
            }
            return repository;
        };
        return GitWikiRepository;
    })();
    Wiki.GitWikiRepository = GitWikiRepository;    
})(Wiki || (Wiki = {}));
