You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spot.apache.org by ev...@apache.org on 2016/12/08 18:48:41 UTC

[01/50] [abbrv] incubator-spot git commit: Spot ui colors (#138)

Repository: incubator-spot
Updated Branches:
  refs/heads/master [created] 8830127b1


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/css/poc.css
----------------------------------------------------------------------
diff --git a/spot-oa/ui/css/poc.css b/spot-oa/ui/css/poc.css
deleted file mode 100755
index b9cafc6..0000000
--- a/spot-oa/ui/css/poc.css
+++ /dev/null
@@ -1,307 +0,0 @@
-body {
-  font-size: 14px;
-}
-
-.navbar {
-    margin-bottom: 0px;
-    border-radius: 0px;
-    border: 0px none transparent;
-}
-
-#spot-nav {
-    background-color:#0071C5;
-}
-
-#spot-nav .navbar-brand {
-    color: #ffffff;
-}
-#spot-nav .navbar-nav>li>a {
-    color: #ffffff;
-}
-
-.navbar #search-box {
-  background-color: #edeff0;
-  padding: 5px 0;
-  min-height: 44px;
-}
-
-.navbar #nav_form label {
-  margin: 0 10px;
-}
-
-.spot-frame-content > .panel {
-    border-color: #0071C5;
-}
-
-.spot-frame-content > .panel > .panel-heading {
-    color: #fff;
-    background-color: #0071C5;
-    border-color: #0071C5;
-}
-
-.spot-loader
-{
-    text-align: center;
-    margin-top: 20px;
-}
-
-.spot-loader .spinner
-{
-    display: inline-block;
-    width: 16px;
-    height: 11px;
-    margin-left: 5px;
-    background-image: url(../images/ajax-loader.gif);
-}
-
-.spot-grid-panel > table > thead th {
-    vertical-align: middle;
-}
-
-.d3-tip {
-    line-height: 1;
-    padding: 12px;
-    background: rgba(0, 0, 0, 0.9);
-    color: #fff;
-    border-radius: 5px;
-    font-size: 12px;
-    z-index: 10000;
-}
-
-.d3-tip .d3-tip-label {
-    color: #888888;
-    font-weight: bold;
-}
-
-.d3-tip .d3-tip-label strong {
-    color: white;
-}
-
-.d3-tip .d3-tip-message {
-    font-size: 12px;
-    text-align: left;
-    word-break: break-all;
-}
-
-/* Creates a small triangle extender for the tooltip */
-.d3-tip:after {
-    box-sizing: border-box;
-    display: inline;
-    font-size: 10px;
-    width: 100%;
-    line-height: 1;
-    color: rgba(0, 0, 0, 0.8);
-    position: absolute;
-    pointer-events: none;
-}
-
-/* Northward tooltips */
-.d3-tip.n:after {
-    content: "\25BC";
-    margin: -1px 0 0 0;
-    top: 100%;
-    left: 0;
-    text-align: center;
-}
-
-/* Eastward tooltips */
-.d3-tip.e:after {
-    content: "\25C0";
-    margin: -4px 0 0 0;
-    top: 50%;
-    left: -8px;
-}
-
-/* Southward tooltips */
-.d3-tip.s:after {
-    content: "\25B2";
-    margin: 0 0 1px 0;
-    top: -8px;
-    left: 0;
-    text-align: center;
-}
-
-/* Westward tooltips */
-.d3-tip.w:after {
-    content: "\25B6";
-    margin: -4px 0 0 -1px;
-    top: 50%;
-    left: 100%;
-}
-
-/* Northwestward tooltips */
-.d3-tip.nw:after {
-    content: "\25E2";
-    margin: -5px 0 0 -5px;
-    top: 100%;
-    left: 100%;
-}
-
-/* Northestward tooltips */
-.d3-tip.ne:after {
-    content: "\25E3";
-    margin: -5px 0 0 0;
-    top: 100%;
-    left: -4px;
-}
-
-/* Southestward tooltips */
-.d3-tip.se:after {
-    content: "\25E4";
-    top: -4px;
-    left: -4px;
-}
-
-/* Southwestward tooltips */
-.d3-tip.sw:after {
-    content: "\25E5";
-    margin: 0 0 0 -5px;
-    top: -4px;
-    left: 100%;
-}
-
-/*****************************************
- **           Network View              **
- *****************************************/
-.edge {
-    stroke-width: 3px;
-    transition: stroke .5s linear;
-}
-
-.edge.active {
-    stroke: #FDB813 !important;
-    stroke-opacity: 1 !important;
-}
-
-.edge.highlight {
-    stroke: #FDB813 !important;
-    stroke-opacity: 1 !important;
-}
-
-.edge-faded {
-    stroke-opacity: 0.2 !important;
-}
-
-.node-faded, .faded {
-    fill-opacity: 0.2 !important;
-    stroke-opacity: 0.2 !important;
-}
-
-.node {
-    stroke: hsl(0,60%,100%);
-    stroke-width: 2.5px;
-    fill: hsl(0,601,40%);
-}
-
-.node-label {
-    position: absolute;
-    top: 0;
-    left: 0;
-    z-index: 10;
-    visibility: hidden;
-    background: white;
-    border-style: solid;
-    border-color: black;
-    border-radius: 10px;
-    font-family: verdana, san-serif;
-    padding: 10px;
-}
-
-/*-------------------------- Flashing/ blinker Animation----------------------*/
-.blink_me {
-    -webkit-animation-name: blinker;
-    -webkit-animation-duration: 1.5s;
-    -webkit-animation-timing-function: linear;
-    -webkit-animation-iteration-count: infinite;
-    -moz-animation-name: blinker;
-    -moz-animation-duration: 1.5s;
-    -moz-animation-timing-function: linear;
-    -moz-animation-iteration-count: infinite;
-    animation-name: blinker;
-    animation-duration: 1.5s;
-    animation-timing-function: linear;
-    animation-iteration-count: infinite;
-}
-
-.proxy-force .edge.blink_me {
-    stroke: #FDB813;
-}
-
-@-moz-keyframes blinker {
-    0% {
-        stroke-opacity: 1.0;
-        fill-opacity: 1.0;
-    }
-
-    50% {
-        stroke-opacity: 0.3;
-        fill-opacity: 0.3;
-    }
-
-    100% {
-        stroke-opacity: 1.0;
-        fill-opacity: 1.0;
-    }
-}
-
-@-webkit-keyframes blinker {
-    0% {
-        stroke-opacity: 1.0;
-        fill-opacity: 1.0;
-    }
-
-    50% {
-        stroke-opacity: 0.3;
-        fill-opacity: 0.3;
-    }
-
-    100% {
-        stroke-opacity: 1.0;
-        fill-opacity: 1.0;
-    }
-}
-
-@keyframes blinker {
-    0% {
-        stroke-opacity: 1.0;
-        fill-opacity: 1.0;
-    }
-
-    50% {
-        stroke-opacity: 0.3;
-        fill-opacity: 0.3;
-    }
-
-    100% {
-        stroke-opacity: 1.0;
-        fill-opacity: 1.0;
-    }
-}
-
-/*************************************
- **         Chords Diagram          **
- *************************************/
-.chord path {
-    fill-opacity: .67;
-    stroke: #000;
-    stroke-width: .5px;
-}
-
-/*************************************
- **         Ingest Summary          **
- *************************************/
-
-
-.x.axis path {
-    stroke: #000;
-}
-
-.y.axis path {
-    stroke: #000;
-}
-
-path.line {
-    fill: none;
-    stroke: #000;
-    stroke-width: .5px;
-}

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/dns/js/components/SuspiciousPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/dns/js/components/SuspiciousPanel.react.js b/spot-oa/ui/dns/js/components/SuspiciousPanel.react.js
index 96da42b..6cc2a2f 100755
--- a/spot-oa/ui/dns/js/components/SuspiciousPanel.react.js
+++ b/spot-oa/ui/dns/js/components/SuspiciousPanel.react.js
@@ -53,7 +53,7 @@ var SuspiciousPanel = React.createClass({
     if (item.network_context)
     {
       ip_dst_info = (
-        <span className={'fa fa-lg fa-info-circle text-primary'}
+        <span className={'fa fa-lg fa-info-circle text-info'}
             data-container="body" data-toggle="popover" data-placement="right" data-content={item.network_context}>
         </span>
       );

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/dns/storyboard.html
----------------------------------------------------------------------
diff --git a/spot-oa/ui/dns/storyboard.html b/spot-oa/ui/dns/storyboard.html
index 82ca55b..5f9f725 100755
--- a/spot-oa/ui/dns/storyboard.html
+++ b/spot-oa/ui/dns/storyboard.html
@@ -6,15 +6,11 @@
     <meta charset="UTF-8">
 
     <!--Bootstrap styles-->
-    <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap/dist/css/bootstrap.min.css" />
-    <!--CDN for font awesome ICONS-->
-    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
+    <link rel="stylesheet" type="text/css" href="../css/bootstrap-spot.min.css" />
     <!--Bootstrap Date picker styles-->
     <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css" />
     <!-- Spot styles -->
     <link rel="stylesheet" type="text/css" href="../css/main.css" />
-    <!-- PoC theme -->
-    <link rel="stylesheet" type="text/css" href="../css/poc.css" />
     <!-- Dendrogram styles -->
     <link rel="stylesheet" type="text/css" href="../css/dendrogram.css" />
     <!-- Favicon -->
@@ -43,7 +39,7 @@
    </style>
 </head>
 <body>
-    <nav id="spot-nav" class="navbar navbar-inverse">
+    <nav id="spot-nav" class="navbar navbar-default">
         <div class="container-fluid">
             <!-- App name and toggle get grouped for better mobile display -->
             <div class="navbar-header">

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/dns/suspicious.html
----------------------------------------------------------------------
diff --git a/spot-oa/ui/dns/suspicious.html b/spot-oa/ui/dns/suspicious.html
index 0cfb5c1..6d008b3 100755
--- a/spot-oa/ui/dns/suspicious.html
+++ b/spot-oa/ui/dns/suspicious.html
@@ -6,15 +6,13 @@
     <meta charset="UTF-8">
 
     <!--Bootstrap styles-->
-    <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap/dist/css/bootstrap.min.css" />
-    <!--CDN for font awesome ICONS-->
-    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
+    <link rel="stylesheet" type="text/css" href="../css/bootstrap-spot.min.css" />
+    <!--Font awesome ICONS-->
+    <link rel="stylesheet" href="../node_modules/font-awesome/css/font-awesome.min.css">
     <!--Bootstrap Date picker styles-->
     <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css" />
     <!-- Spot styles -->
     <link rel="stylesheet" type="text/css" href="../css/main.css" />
-    <!-- PoC theme -->
-    <link rel="stylesheet" type="text/css" href="../css/poc.css" />
     <!-- Dendrogram styles -->
     <link rel="stylesheet" type="text/css" href="../css/dendrogram.css" />
     <!-- Favicon -->
@@ -51,7 +49,7 @@
     </style>
 </head>
 <body>
-    <nav id="spot-nav" class="navbar navbar-inverse">
+    <nav id="spot-nav" class="navbar navbar-default">
         <div class="container-fluid">
             <!-- App name and toggle get grouped for better mobile display -->
             <div class="navbar-header">

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/dns/threat-investigation.html
----------------------------------------------------------------------
diff --git a/spot-oa/ui/dns/threat-investigation.html b/spot-oa/ui/dns/threat-investigation.html
index c76a9df..cf5966d 100755
--- a/spot-oa/ui/dns/threat-investigation.html
+++ b/spot-oa/ui/dns/threat-investigation.html
@@ -6,15 +6,11 @@
     <meta charset="UTF-8">
 
     <!--Bootstrap styles-->
-    <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap/dist/css/bootstrap.min.css" />
-    <!--CDN for font awesome ICONS-->
-    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
+    <link rel="stylesheet" type="text/css" href="../css/bootstrap-spot.min.css" />
     <!--Bootstrap Date picker styles-->
     <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css" />
     <!-- Spot styles -->
     <link rel="stylesheet" type="text/css" href="../css/main.css" />
-    <!-- PoC theme -->
-    <link rel="stylesheet" type="text/css" href="../css/poc.css" />
     <!-- Favicon -->
     <link rel="apple-touch-icon" sizes="57x57" href="../images/favicon/apple-icon-57x57.png">
     <link rel="apple-touch-icon" sizes="60x60" href="../images/favicon/apple-icon-60x60.png"
@@ -41,7 +37,7 @@
     </style>
 </head>
 <body>
-    <nav id="spot-nav" class="navbar navbar-inverse">
+    <nav id="spot-nav" class="navbar navbar-default">
         <div class="container-fluid">
             <!-- App name and toggle get grouped for better mobile display -->
             <div class="navbar-header">

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/flow/ingest-summary.html
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/ingest-summary.html b/spot-oa/ui/flow/ingest-summary.html
index a3cd12c..c13ab9f 100755
--- a/spot-oa/ui/flow/ingest-summary.html
+++ b/spot-oa/ui/flow/ingest-summary.html
@@ -6,15 +6,11 @@
     <meta charset="UTF-8">
 
     <!--Bootstrap styles-->
-    <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap/dist/css/bootstrap.min.css" />
-    <!--CDN for font awesome ICONS-->
-    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
+    <link rel="stylesheet" type="text/css" href="../css/bootstrap-spot.min.css" />
     <!--Bootstrap Date picker styles-->
     <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css" />
     <!-- Spot styles -->
     <link rel="stylesheet" type="text/css" href="../css/main.css" />
-    <!-- PoC theme -->
-    <link rel="stylesheet" type="text/css" href="../css/poc.css" />
     <!-- Favicon -->
     <link rel="apple-touch-icon" sizes="57x57" href="../images/favicon/apple-icon-57x57.png">
     <link rel="apple-touch-icon" sizes="60x60" href="../images/favicon/apple-icon-60x60.png"
@@ -67,7 +63,7 @@
     </style>
 </head>
 <body>
-    <nav id="spot-nav" class="navbar navbar-inverse">
+    <nav id="spot-nav" class="navbar navbar-default">
         <div class="container-fluid">
             <!-- App name and toggle get grouped for better mobile display -->
             <div class="navbar-header">

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/flow/js/components/SuspiciousPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/components/SuspiciousPanel.react.js b/spot-oa/ui/flow/js/components/SuspiciousPanel.react.js
index aae33fd..4857534 100755
--- a/spot-oa/ui/flow/js/components/SuspiciousPanel.react.js
+++ b/spot-oa/ui/flow/js/components/SuspiciousPanel.react.js
@@ -27,7 +27,7 @@ var SuspiciousPanel = React.createClass({
     _renderIpCell: function (keyPrefix, ip, isInternal) {
         var internalCssCls;
 
-        internalCssCls = isInternal ? 'label label-primary' : '';
+        internalCssCls = isInternal ? 'label label-info' : '';
 
         return (
             <span key={keyPrefix + '_label'} className={internalCssCls}>{ip} </span>

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/flow/storyboard.html
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/storyboard.html b/spot-oa/ui/flow/storyboard.html
index 967f6cb..8596eea 100755
--- a/spot-oa/ui/flow/storyboard.html
+++ b/spot-oa/ui/flow/storyboard.html
@@ -6,15 +6,11 @@
     <meta charset="UTF-8">
 
     <!--Bootstrap styles-->
-    <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap/dist/css/bootstrap.min.css" />
-    <!--CDN for font awesome ICONS-->
-    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
+    <link rel="stylesheet" type="text/css" href="../css/bootstrap-spot.min.css" />
     <!--Bootstrap Date picker styles-->
     <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css" />
     <!-- Spot styles -->
     <link rel="stylesheet" type="text/css" href="../css/main.css" />
-    <!-- PoC theme -->
-    <link rel="stylesheet" type="text/css" href="../css/poc.css" />
     <!-- Charts styles -->
     <link rel="stylesheet" type="text/css" href="../css/dendrogram.css" />
     <link rel="stylesheet" type="text/css" href="../node_modules/event-drops/css/style.css" />
@@ -43,7 +39,7 @@
     </style>
 </head>
 <body>
-    <nav id="spot-nav" class="navbar navbar-inverse">
+    <nav id="spot-nav" class="navbar navbar-default">
         <div class="container-fluid">
             <!-- App name and toggle get grouped for better mobile display -->
             <div class="navbar-header">

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/flow/suspicious.html
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/suspicious.html b/spot-oa/ui/flow/suspicious.html
index b8b6d16..9bd47c8 100755
--- a/spot-oa/ui/flow/suspicious.html
+++ b/spot-oa/ui/flow/suspicious.html
@@ -6,15 +6,13 @@
     <meta charset="UTF-8">
 
     <!--Bootstrap styles-->
-    <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap/dist/css/bootstrap.min.css" />
-    <!--CDN for font awesome ICONS-->
-    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
+    <link rel="stylesheet" type="text/css" href="../css/bootstrap-spot.min.css" />
+    <!--Font awesome ICONS-->
+    <link rel="stylesheet" href="../node_modules/font-awesome/css/font-awesome.min.css">
     <!--Bootstrap Date picker styles-->
     <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css" />
     <!-- Spot styles -->
     <link rel="stylesheet" type="text/css" href="../css/main.css" />
-    <!-- PoC theme -->
-    <link rel="stylesheet" type="text/css" href="../css/poc.css" />
     <!-- Favicon -->
     <link rel="apple-touch-icon" sizes="57x57" href="../images/favicon/apple-icon-57x57.png">
     <link rel="apple-touch-icon" sizes="60x60" href="../images/favicon/apple-icon-60x60.png"
@@ -45,7 +43,7 @@
     </style>
 </head>
 <body>
-    <nav id="spot-nav" class="navbar navbar-inverse">
+    <nav id="spot-nav" class="navbar navbar-default">
         <div class="container-fluid">
             <!-- App name and toggle get grouped for better mobile display -->
             <div class="navbar-header">

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/flow/threat-investigation.html
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/threat-investigation.html b/spot-oa/ui/flow/threat-investigation.html
index 3008918..d80ccc6 100755
--- a/spot-oa/ui/flow/threat-investigation.html
+++ b/spot-oa/ui/flow/threat-investigation.html
@@ -6,15 +6,11 @@
     <meta charset="UTF-8">
 
     <!--Bootstrap styles-->
-    <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap/dist/css/bootstrap.min.css" />
-    <!--CDN for font awesome ICONS-->
-    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
+    <link rel="stylesheet" type="text/css" href="../css/bootstrap-spot.min.css" />
     <!--Bootstrap Date picker styles-->
     <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css" />
     <!-- Spot styles -->
     <link rel="stylesheet" type="text/css" href="../css/main.css" />
-    <!-- PoC theme -->
-    <link rel="stylesheet" type="text/css" href="../css/poc.css" />
     <!-- Favicon -->
     <link rel="apple-touch-icon" sizes="57x57" href="../images/favicon/apple-icon-57x57.png">
     <link rel="apple-touch-icon" sizes="60x60" href="../images/favicon/apple-icon-60x60.png"
@@ -41,7 +37,7 @@
     </style>
 </head>
 <body>
-    <nav id="spot-nav" class="navbar navbar-inverse">
+    <nav id="spot-nav" class="navbar navbar-default">
         <div class="container-fluid">
             <!-- App name and toggle get grouped for better mobile display -->
             <div class="navbar-header">

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/package.json
----------------------------------------------------------------------
diff --git a/spot-oa/ui/package.json b/spot-oa/ui/package.json
index 8c59555..a07a106 100644
--- a/spot-oa/ui/package.json
+++ b/spot-oa/ui/package.json
@@ -14,6 +14,7 @@
     "d3-tip": "^0.6.7",
     "event-drops": "^0.1.1",
     "flux": "^2.0.0",
+    "font-awesome": "^4.7.0",
     "jquery": "^2.0.0",
     "js-base64": "^2.1.9",
     "object-assign": "^1.0.0",

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/proxy/storyboard.html
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/storyboard.html b/spot-oa/ui/proxy/storyboard.html
index 022fcb1..6968566 100755
--- a/spot-oa/ui/proxy/storyboard.html
+++ b/spot-oa/ui/proxy/storyboard.html
@@ -6,15 +6,11 @@
     <meta charset="UTF-8">
 
     <!--Bootstrap styles-->
-    <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap/dist/css/bootstrap.min.css" />
-    <!--CDN for font awesome ICONS-->
-    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
+    <link rel="stylesheet" type="text/css" href="../css/bootstrap-spot.min.css" />
     <!--Bootstrap Date picker styles-->
     <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css" />
     <!-- Spot styles -->
     <link rel="stylesheet" type="text/css" href="../css/main.css" />
-    <!-- PoC theme -->
-    <link rel="stylesheet" type="text/css" href="../css/poc.css" />
     <!-- Charts styles -->
     <link rel="stylesheet" type="text/css" href="../css/dendrogram.css" />
     <link rel="stylesheet" type="text/css" href="../node_modules/event-drops/css/style.css" />
@@ -121,7 +117,7 @@
     </style>
 </head>
 <body>
-    <nav id="spot-nav" class="navbar navbar-inverse">
+    <nav id="spot-nav" class="navbar navbar-default">
         <div class="container-fluid">
             <!-- App name and toggle get grouped for better mobile display -->
             <div class="navbar-header">

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/proxy/suspicious.html
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/suspicious.html b/spot-oa/ui/proxy/suspicious.html
index e999c75..828a42c 100755
--- a/spot-oa/ui/proxy/suspicious.html
+++ b/spot-oa/ui/proxy/suspicious.html
@@ -6,15 +6,13 @@
     <meta charset="UTF-8">
 
     <!--Bootstrap styles-->
-    <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap/dist/css/bootstrap.min.css" />
-    <!--CDN for font awesome ICONS-->
-    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
+    <link rel="stylesheet" type="text/css" href="../css/bootstrap-spot.min.css" />
+    <!--Font awesome ICONS-->
+    <link rel="stylesheet" href="../node_modules/font-awesome/css/font-awesome.min.css">
     <!--Bootstrap Date picker styles-->
     <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css" />
     <!-- Spot styles -->
     <link rel="stylesheet" type="text/css" href="../css/main.css" />
-    <!-- PoC theme -->
-    <link rel="stylesheet" type="text/css" href="../css/poc.css" />
     <!-- Favicon -->
     <link rel="apple-touch-icon" sizes="57x57" href="../images/favicon/apple-icon-57x57.png">
     <link rel="apple-touch-icon" sizes="60x60" href="../images/favicon/apple-icon-60x60.png">
@@ -109,7 +107,7 @@
     </style>
 </head>
 <body>
-    <nav id="spot-nav" class="navbar navbar-inverse">
+    <nav id="spot-nav" class="navbar navbar-default">
         <div class="container-fluid">
             <!-- App name and toggle get grouped for better mobile display -->
             <div class="navbar-header">

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/proxy/threat-investigation.html
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/threat-investigation.html b/spot-oa/ui/proxy/threat-investigation.html
index b2b514b..ae740a9 100755
--- a/spot-oa/ui/proxy/threat-investigation.html
+++ b/spot-oa/ui/proxy/threat-investigation.html
@@ -6,15 +6,11 @@
     <meta charset="UTF-8">
 
     <!--Bootstrap styles-->
-    <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap/dist/css/bootstrap.min.css" />
-    <!--CDN for font awesome ICONS-->
-    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
+    <link rel="stylesheet" type="text/css" href="../css/bootstrap-spot.min.css" />
     <!--Bootstrap Date picker styles-->
     <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css" />
     <!-- Spot styles -->
     <link rel="stylesheet" type="text/css" href="../css/main.css" />
-    <!-- PoC theme -->
-    <link rel="stylesheet" type="text/css" href="../css/poc.css" />
     <!-- Favicon -->
     <link rel="apple-touch-icon" sizes="57x57" href="../images/favicon/apple-icon-57x57.png">
     <link rel="apple-touch-icon" sizes="60x60" href="../images/favicon/apple-icon-60x60.png"
@@ -40,7 +36,7 @@
     </style>
 </head>
 <body>
-    <nav id="spot-nav" class="navbar navbar-inverse">
+    <nav id="spot-nav" class="navbar navbar-default">
         <div class="container-fluid">
             <!-- App name and toggle get grouped for better mobile display -->
             <div class="navbar-header">


[13/50] [abbrv] incubator-spot git commit: adding join to avoid overflow of processes, multiprocessing is manage by the number of workers

Posted by ev...@apache.org.
adding join to avoid overflow of processes, multiprocessing is manage by the number of workers


Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/90a0a313
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/90a0a313
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/90a0a313

Branch: refs/heads/master
Commit: 90a0a313224c0b0ab53a0148fbc433b8349ecdab
Parents: ea52d12
Author: elopezsa <ev...@intel.com>
Authored: Thu Nov 24 12:33:11 2016 -0600
Committer: elopezsa <ev...@intel.com>
Committed: Thu Nov 24 12:33:11 2016 -0600

----------------------------------------------------------------------
 spot-ingest/pipelines/dns/worker.py | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/90a0a313/spot-ingest/pipelines/dns/worker.py
----------------------------------------------------------------------
diff --git a/spot-ingest/pipelines/dns/worker.py b/spot-ingest/pipelines/dns/worker.py
index 06a381a..6e9e041 100755
--- a/spot-ingest/pipelines/dns/worker.py
+++ b/spot-ingest/pipelines/dns/worker.py
@@ -45,6 +45,7 @@ class Worker(object):
         self._logger.info("File: {0} ".format(file))        
         p = Process(target=self._process_new_file, args=(file,))
         p.start() 
+        p.join()
 
     def _process_new_file(self,file):
 


[47/50] [abbrv] incubator-spot git commit: update README with the correct links

Posted by ev...@apache.org.
update README with the correct links


Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/300d313d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/300d313d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/300d313d

Branch: refs/heads/master
Commit: 300d313d74efd46eb226d856de1bf3c31ab8c1b2
Parents: 508c63e
Author: elopezsa <ev...@intel.com>
Authored: Thu Dec 8 10:09:48 2016 -0600
Committer: elopezsa <ev...@intel.com>
Committed: Thu Dec 8 10:09:48 2016 -0600

----------------------------------------------------------------------
 README.md | 45 ++++++++-------------------------------------
 1 file changed, 8 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/300d313d/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 340bc38..b215a10 100644
--- a/README.md
+++ b/README.md
@@ -62,30 +62,21 @@ pull the code from [oni-demo repo](https://github.com/Open-Network-Insight/oni-d
 
 Apache Spot can be installed by following our installation manual. To get started, [check out the installation instructions in the documentation](https://github.com/Open-Network-Insight/open-network-insight/wiki).
 
-## If you want all of the Apache Spot code at once, just clone it!
-        git clone --recursive https://github.com/Open-Network-Insight/open-network-insight.git
-
-## **Roadmap**
-
-TBD
-
 ## **Documentation (Developer Guide)**
 
-Apache Spot functionality is divided into different repositories, go to each repository for developer documentation:
+Apache Spot functionality is divided into different modules, go to each module for developer documentation:
 
-* [oni-ingest](https://github.com/Open-Network-Insight/oni-ingest)
-* [oni-ml](https://github.com/Open-Network-Insight/oni-ml)
-* [oni-oa](https://github.com/Open-Network-Insight/oni-oa)
-* [oni-setup](https://github.com/Open-Network-Insight/oni-setup)
-* [oni-nfdump](https://github.com/Open-Network-Insight/oni-nfdump)
-* [oni-lda-c](https://github.com/Open-Network-Insight/oni-lda-c)
+* [spot-ingest](spot-ingest/README.md)
+* [spot-ml](spot-ml/README.md)
+* [spot-oa](spot-oa/README.md)
+* [spot-setup](spot-setup/README.md)
 
 ## **Community Support**
 
 Our Central repository for our Apache Spot solution is found here. If you find a bug, have question or something to discuss please contact us:
 
-* [Create an Issue](https://github.com/Open-Network-Insight/open-network-insight/issues). For issue creation guidelines and how to create an issue for Apache Spot please go to: [How to create an Issue](ISSUES.md)
-* [Go to our Slack channel](https://opennetworkinsights.slack.com/messages/general/). 
+* [Create an Issue](https://issues.apache.org/jira/browse/SPOT-20?jql=project%20%3D%20SPOT). 
+* [Go to our Slack channel](https://spot.slack.com/messages/general/). 
 
 ## **Contributing to Apache Spot**
 
@@ -99,20 +90,7 @@ and join our community.
 * Fork the repo of the module that you wish to commit to.
 * Create a Branch, we use [topic branches](https://git-scm.com/book/en/v2/Git-Branching-Branching-Workflows#Topic-Branches) for our commits. 
 * Push your commit(s) to your repository.
-* Create a pull request to the original repo in Apache Spot organization
-TBD
-## **Documentation (Developer Guide)**
-Apache Spot functionality is divided into different repositories, go to each repository for developer documentation:
-* [oni-ingest](https://github.com/Open-Network-Insight/oni-ingest)
-* [oni-ml](https://github.com/Open-Network-Insight/oni-ml)
-* [oni-oa](https://github.com/Open-Network-Insight/oni-oa)
-* [oni-setup](https://github.com/Open-Network-Insight/oni-setup)
-* [oni-nfdump](https://github.com/Open-Network-Insight/oni-nfdump)
-* [oni-lda-c](https://github.com/Open-Network-Insight/oni-lda-c)
-## **Community Support**
-Our Central repository for our Open Network Insight solution is found here. If you find a bug, have question or something to discuss please contact us:
-* [Create an Issue](https://github.com/Open-Network-Insight/open-network-insight/issues). For issue creation guidelines and how to create an issue for ONI please go to: [How to create an Issue](ISSUES.md)
- organization.
+* Create a pull request to the original repo in Apache Spot organization.
 
 ### **Commit Guidelines**
 
@@ -122,12 +100,6 @@ Our Central repository for our Open Network Insight solution is found here. If y
 
 ### **Merge approval**
 
-* [Create an Issue](https://github.com/Open-Network-Insight/open-network-insight/issues). For issue creation guidelines and how to create an issue for Apache Spot please go to: [How to create an Issue](ISSUES.md)
- organization.
-### **Commit Guidelines**
-* Bug fixes should be a single commit.
-* Please be clear with the commit messages about what you are fixing or adding to the code base. If you code is addressing an open issue please add the reference to the issue in the comments with: Fix: Issue's URL. 
-### **Merge approval**
 ONI maintainers use LGTM (Looks Good to Me) in a comments on the code review to indicate acceptance, 
 at least 3 "LGTM" from maintainers are required to approve the merge. If you have any question or concern please feel free to add a comment in your pull request or branch and tag any of the maintainers.
 
@@ -137,7 +109,6 @@ at least 3 "LGTM" from maintainers are required to approve the merge. If you hav
 Apache Spot is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for the full license text.
 
 * oni-nfdump [License](https://github.com/Open-Network-Insight/oni-nfdump/blob/master/BSD-license.txt)
-* oni-lda-c [License](https://github.com/Open-Network-Insight/oni-lda-c/blob/1.0.1/license.txt)
 
 ## **Maintainers**
 


[40/50] [abbrv] incubator-spot git commit: Adding join to avoid multiprocessing overflow

Posted by ev...@apache.org.
Adding join to avoid multiprocessing overflow

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

Branch: refs/heads/master
Commit: f9b8e1181db2ec128aaf7be8fa85e3a8a26ef376
Parents: ee98df8
Author: Everardo Lopez Sandoval <ev...@intel.com>
Authored: Mon Dec 5 16:02:01 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Mon Dec 5 16:02:01 2016 -0600

----------------------------------------------------------------------
 spot-ingest/pipelines/flow/worker.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/f9b8e118/spot-ingest/pipelines/flow/worker.py
----------------------------------------------------------------------
diff --git a/spot-ingest/pipelines/flow/worker.py b/spot-ingest/pipelines/flow/worker.py
index 8d2efd9..f160ea0 100755
--- a/spot-ingest/pipelines/flow/worker.py
+++ b/spot-ingest/pipelines/flow/worker.py
@@ -44,8 +44,9 @@ class Worker(object):
         self._logger.info("-------------------------------------- New File received --------------------------------------")
         self._logger.info("File: {0} ".format(file))        
         p = Process(target=self._process_new_file, args=(file,))
-        p.start()        
-
+        p.start()
+        p.join()
+        
     def _process_new_file(self,file):
 
         # get file from hdfs


[15/50] [abbrv] incubator-spot git commit: Impact Analysis chart improvement (#147)

Posted by ev...@apache.org.
Impact Analysis chart improvement (#147)

Adding mixins and simplifying chart code

Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/0ee93180
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/0ee93180
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/0ee93180

Branch: refs/heads/master
Commit: 0ee9318088bb6cf8904fdebed8f74e92d980dd6c
Parents: dcdf0ca
Author: daortizh <di...@intel.com>
Authored: Fri Nov 25 16:37:46 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Fri Nov 25 16:37:46 2016 -0600

----------------------------------------------------------------------
 .../js/components/ImpactAnalysisPanel.react.js  | 350 ++++++-------------
 1 file changed, 99 insertions(+), 251 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/0ee93180/spot-oa/ui/flow/js/components/ImpactAnalysisPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/components/ImpactAnalysisPanel.react.js b/spot-oa/ui/flow/js/components/ImpactAnalysisPanel.react.js
index e490c5d..581232c 100755
--- a/spot-oa/ui/flow/js/components/ImpactAnalysisPanel.react.js
+++ b/spot-oa/ui/flow/js/components/ImpactAnalysisPanel.react.js
@@ -1,226 +1,118 @@
 const React = require('react');
 const ReactDOM = require('react-dom');
 const ImpactAnalysisStore = require('../stores/ImpactAnalysisStore');
+const ContentLoaderMixin = require('../../../js/components/ContentLoaderMixin.react');
+const ChartMixin = require('../../../js/components/ChartMixin.react');
 
-var svg, xAxis, x, y, z;
-
-function buildGraph(root, ipsrc)
-{
-    var container = $(ReactDOM.findDOMNode(this));
-    $(container).html("");
-    var m = [50, 50, 0, 100], // top right bottom left
-           w = container.width() - m[1] - m[3], // width
-           h = container.height() - m[0] - m[2]; // height
-
-    x = d3.scale.linear().range([0, w]);
-    y = Math.round(h * 0.1); // bar height
-    z = d3.scale.ordinal().range(["#0071c5", "#939598"]); // bar color
-
-    var hierarchy = d3.layout.partition()
-        .value(function (d) { return d.size; });
-
-    xAxis = d3.svg.axis()
-        .scale(x)
-        .orient("top");
-
-    svg = d3.select(container[0]).append("svg:svg")
-        .attr("width", w + m[1] + m[3])
-        .attr("height", h + m[0] + m[2])
-        .append("svg:g")
-        .attr("transform", "translate(" + m[3] + "," + m[0] + ")");
-
-    function resizeHandler() {
-        buildGraph.call(this, root, ipsrc);
-    }
-
-    window.removeEventListener('resize', resizeHandler.bind(this));
-    window.addEventListener('resize', resizeHandler.bind(this));
-
-    $('svg', ReactDOM.findDOMNode(this)).off('parentUpdate').on('parentUpdate', resizeHandler.bind(this));
-
-    svg.append("svg:rect")
-        .attr("class", "background")
-        .attr("width", w)
-        .attr("height", h)
-        .on("click", up);
-
-    svg.append("svg:g")
-        .attr("class", "x axis");
-
-    svg.append("svg:g")
-        .attr("class", "y axis")
-        .append("svg:line")
-        .attr("y1", "100%");
-
-    hierarchy.nodes(root);
-    x.domain([0, root.value]).nice();
-    down.call(ReactDOM.findDOMNode(this), root, 0);
-
-}
-
-function down(d, i) {
-    if (!d.children || this.__transition__) return;
-    var duration = d3.event && d3.event.altKey ? 7500 : 750,
-        delay = duration / d.children.length;
-
-    // Mark any currently-displayed bars as exiting.
-    var exit = svg.selectAll(".enter").attr("class", "exit");
-
-    // Entering nodes immediately obscure the clicked-on bar, so hide it.
-    exit.selectAll("rect").filter(function (p) { return p === d; })
-        .style("fill-opacity", 1e-6);
-
-    // Enter the new bars for the clicked-on data.
-    // Per above, entering bars are immediately visible.
-    var enter = bar(d)
-        .attr("transform", stack(i))
-        .style("opacity", 1);
-
-    // Have the text fade-in, even though the bars are visible.
-    // Color the bars as parents; they will fade to children if appropriate.
-    enter.select("text").style("fill-opacity", 1e-6);
-    enter.select("rect").style("fill", z(true));
-
-    // Update the x-scale domain.
-    x.domain([0, d3.max(d.children, function (d) { return d.value; })]).nice();
-
-    // Update the x-axis.
-    svg.selectAll(".x.axis").transition()
-        .duration(duration)
-        .call(xAxis);
-
-    // Transition entering bars to their new position.
-    var enterTransition = enter.transition()
-        .duration(duration)
-        .delay(function (d, i) { return i * delay; })
-        .attr("transform", function (d, i) { return "translate(0," + y * i * 1.2 + ")"; });
-
-    // Transition entering text.
-    enterTransition.select("text").style("fill-opacity", 1);
-
-    // Transition entering rects to the new x-scale.
-    enterTransition.select("rect")
-        .attr("width", function (d) { return x(d.value); })
-        .style("fill", function (d) { return z(!!d.children); });
-
-    // Transition exiting bars to fade out.
-    var exitTransition = exit.transition()
-        .duration(duration)
-        .style("opacity", 1e-6)
-        .remove();
-
-    // Transition exiting bars to the new x-scale.
-    exitTransition.selectAll("rect").attr("width", function (d) { return x(d.value); });
-
-    // Rebind the current node to the background.
-    svg.select(".background").data([d]).transition().duration(duration * 2); d.index = i;
-}
-
-function up(d) {
-    if (!d.parent || this.__transition__) return;
-    var duration = d3.event && d3.event.altKey ? 7500 : 750,
-        delay = duration / d.children.length;
-
-    // Mark any currently-displayed bars as exiting.
-    var exit = svg.selectAll(".enter").attr("class", "exit");
-
-    // Enter the new bars for the clicked-on data's parent.
-    var enter = bar(d.parent)
-        .attr("transform", function (d, i) { return "translate(0," + y * i * 1.2 + ")"; })
-        .style("opacity", 1e-6);
-
-    // Color the bars as appropriate.
-    // Exiting nodes will obscure the parent bar, so hide it.
-    enter.select("rect")
-        .style("fill", function (d) { return z(!!d.children); })
-        .filter(function (p) { return p === d; })
-        .style("fill-opacity", 1e-6);
-
-    // Update the x-scale domain.
-    x.domain([0, d3.max(d.parent.children, function (d) { return d.value; })]).nice();
+const ImpactAnalysisPanel = React.createClass({
+    mixins: [ContentLoaderMixin, ChartMixin],
+    componentDidMount: function ()
+    {
+        ImpactAnalysisStore.addChangeDataListener(this._onChange);
+    },
+    componentWillUnmount: function ()
+    {
+        ImpactAnalysisStore.removeChangeDataListener(this._onChange);
+    },
+    buildChart() {
+        const svgSel = d3.select(this.svg);
+
+        svgSel
+            .attr('width', '100%')
+            .attr('height', '100%')
+            .on('click', () => {
+                this.drawBars(this.state.data);
+            });
 
-    // Update the x-axis.
-    svg.selectAll(".x.axis").transition()
-        .duration(duration * 2)
-        .call(xAxis);
+        this.canvas = svgSel.append('g');
 
-    // Transition entering bars to fade in over the full duration.
-    var enterTransition = enter.transition()
-        .duration(duration * 2)
-        .style("opacity", 1);
+        this.canvas.append('g').attr('class', 'x axis');
 
-    // Transition entering rects to the new x-scale.
-    // When the entering parent rect is done, make it visible!
-    enterTransition.select("rect")
-        .attr("width", function (d) { return x(d.value); })
-        .each("end", function (p) { if (p === d) d3.select(this).style("fill-opacity", null); });
+        this.barCanvas = this.canvas.append('g').attr('transform', 'translate(0, 5)');
 
-    // Transition exiting bars to the parent's position.
-    var exitTransition = exit.selectAll("g").transition()
-        .duration(duration)
-        .delay(function (d, i) { return i * delay; })
-        .attr("transform", stack(d.index));
+        // Layout our data
+        d3.layout.partition()
+            .value(d => d.size)
+            .nodes(this.state.data);
 
-    // Transition exiting text to fade out.
-    exitTransition.select("text")
-        .style("fill-opacity", 1e-6);
+        // Create scales
+        this.xScale = d3.scale.linear().domain([0, this.state.data.value]).nice();
+        this.colorScale = d3.scale.ordinal().range(['#0071c5', '#939598']); // bar color
 
-    // Transition exiting rects to the new scale and fade to parent color.
-    exitTransition.select("rect")
-        .attr("width", function (d) { return x(d.value); })
-        .style("fill", z(true));
+        this.xAxis = d3.svg.axis().scale(this.xScale).orient('top');
+    },
+    draw() {
+        const container = $(ReactDOM.findDOMNode(this));
 
-    // Remove exiting nodes when the last child has finished transitioning.
-    exit.transition().duration(duration * 2).remove();
+        const m = [50, 50, 0, 100]; // top right bottom left
+        const w = container.width() - m[1] - m[3]; // width
+        const h = container.height() - m[0] - m[2]; // height
 
-    // Rebind the current parent to the background.
-    svg.select(".background").data([d.parent]).transition().duration(duration * 2);
-}
+        this.xScale.range([0, w]);
+        this.y = Math.round(h * 0.1); // bar height
 
-// Creates a set of bars for the given data node, at the specified index.
-function bar(d) {
-    var bar = svg.insert("svg:g", ".y.axis")
-        .attr("class", "enter")
-        .attr("transform", "translate(0,5)")
-      .selectAll("g")
-        .data(d.children)
-      .enter().append("svg:g")
-        .style("cursor", function (d) { return !d.children ? null : "pointer"; })
-        .on("click", down);
+        this.canvas.attr('transform', `translate(${m[3]},${m[0]})`);
 
-    bar.append("svg:text")
-        .attr("x", -6)
-        .attr("y", y / 2)
-        .attr("dy", ".35em")
-        .attr("text-anchor", "end")
-        .text(function (d) { return d.name; });
+        this.drawBars(this.state.data);
+    },
+    drawBars(root) {
+        const duration = d3.event && d3.event.altKey ? 7500 : 750;
+        const delay = duration / (root.children.length + 1);
+
+        // Update the x-scale domain.
+        this.xScale.domain([0, d3.max(root.children, d => d.value)]).nice();
+
+        // Update the x-axis.
+        this.canvas.select('.x.axis')
+            .transition()
+            .duration(duration)
+            .call(this.xAxis);
+
+        const barSel = {};
+
+        barSel.update = this.barCanvas.selectAll('.bar').data(root.children, d => d.name);
+        barSel.enter = barSel.update.enter();
+        barSel.exit = barSel.update.exit();
+
+        const exitTransition = barSel.exit.transition().duration(duration).delay((d, i) => (i+1) * delay)
+        // Fade out text
+        exitTransition.selectAll('text').style('fill-opacity', 0);
+        // Shrink bar
+        exitTransition.selectAll('rect').attr('width', '0');
+        // Finally remove g element after transition has finished
+        exitTransition.remove();
+
+        const newBar = barSel.enter.append('g')
+            .classed('bar', true)
+            .attr('transform', (d, i) => `translate(0,${this.y * i * 1.2})`)
+            .style('cursor', d => d.children ? 'pointer' : null)
+            .on('click', d => {
+                d3.event.stopPropagation();
+
+                if (d.children && d.children.length)
+                {
+                    this.drawBars(d);
+                }
+            });
 
-    bar.append("svg:rect")
-        .attr("width", function (d) { return x(d.value); })
-        .attr("height", y);
+        newBar.append('text')
+            .attr('x', -6)
+            .attr('y', this.y / 2)
+            .attr('dy', '.35em')
+            .attr('text-anchor', 'end')
+            .style('fill-opacity', 1e-6) // Fade In
+            .text(d => d.name);
 
-    return bar;
-}
+        newBar.append('rect')
+            .attr('width', '0')
+            .attr('height', this.y)
+            .style('fill', (d) => this.colorScale(!!d.children));
 
-// A stateful closure for stacking bars horizontally.
-function stack(i) {
-    var x0 = 0;
-    return function (d) {
-        var tx = "translate(" + x0 + "," + y * i * 1.2 + ")";
-        x0 += x(d.value);
-        return tx;
-    };
-}
+        const enterTransition = barSel.update.transition().duration(duration).delay((d, i) => (i+1) * delay);
 
+        enterTransition.selectAll('text').style('fill-opacity', 1);
 
-var ImpactAnalysisPanel = React.createClass({
-    componentDidMount: function ()
-    {
-        ImpactAnalysisStore.addChangeDataListener(this._onChange);
-    },
-    componentWillUnmount: function ()
-    {
-        ImpactAnalysisStore.removeChangeDataListener(this._onChange);
+        enterTransition.selectAll('rect').attr('width', d => this.xScale(d.value));
     },
     _onChange: function ()
     {
@@ -232,12 +124,12 @@ var ImpactAnalysisPanel = React.createClass({
             state.error = storeData.error;
         }
         else if(!storeData.loading && storeData.data) {
-            state.root = {
+            state.data = {
                 name: ImpactAnalysisStore.getIp(),
-                size: 0
+                size: storeData.data.children.length
             };
 
-            state.root.children = storeData.data.children.map((item) => {
+            state.data.children = storeData.data.children.map((item) => {
                 return {
                     name: item.name,
                     size: item.size,
@@ -247,50 +139,6 @@ var ImpactAnalysisPanel = React.createClass({
         }
 
         this.replaceState(state);
-    },
-    getInitialState: function ()
-    {
-        return {loading: false};
-    },
-    render:function()
-    {
-        var content;
-
-        if (this.state.error)
-        {
-            content = (
-                <div className="text-center text-danger">
-                    {this.state.error}
-                </div>
-            );
-        }
-        else if (this.state.loading)
-        {
-          content = (
-            <div className="spot-loader">
-                Loading <span className="spinner"></span>
-            </div>
-          );
-        }
-        else
-        {
-          content = '';
-        }
-        return (
-          <div>{content}</div>
-        )
-    },
-    componentDidUpdate: function ()
-    {
-        if (!this.state.loading && !this.state.error)
-        {
-          if (this.state.root) {
-              buildGraph.call(this, this.state.root);
-          }
-          else {
-              d3.select(ReactDOM.findDOMNode(this)).selectAll('*').remove();
-          }
-        }
     }
 });
 


[49/50] [abbrv] incubator-spot git commit: removing github issues

Posted by ev...@apache.org.
removing github issues


Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/6586bb0f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/6586bb0f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/6586bb0f

Branch: refs/heads/master
Commit: 6586bb0f2e29591be5d31d42e06c8560929d84bb
Parents: d8f2543
Author: elopezsa <ev...@intel.com>
Authored: Thu Dec 8 10:30:23 2016 -0600
Committer: elopezsa <ev...@intel.com>
Committed: Thu Dec 8 10:30:23 2016 -0600

----------------------------------------------------------------------
 ISSUES.md | 53 -----------------------------------------------------
 1 file changed, 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/6586bb0f/ISSUES.md
----------------------------------------------------------------------
diff --git a/ISSUES.md b/ISSUES.md
deleted file mode 100644
index e2a3900..0000000
--- a/ISSUES.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# **How to create an issue for ONI**
-
-Please help us to improve ONI! Create your issues found following the next steps:
-
-
-## **Create an Issue**
-
-To create an issue please go to [ONI Issues](https://github.com/Open-Network-Insight/open-network-insight/issues), 
-* Review current open issues for any matches.
-* If there is a match, please feel free to comment on the issue.
-* If you don't find a match, please continue creating your own issue.
-
-## **Add issue type label**
-
-![Issue type](docs/label-issue-type.bmp)
-
-* **Bug:** Something that is not working properly according the functional spec.
-* **Enhancement:** Add new functionality or improve existing functionality.
-* **Discussion:** Open a discussion related to any topic about ONI solution.
-
-## **Add repo label**
-Once an issue is created, add a repo tag to identify the module that needs to be tracked.
- 
-![oni repos](docs/label-repos.bmp "ONI Repos")
-
-# **Context Labels (Added by ONI team)**  
-
-ONI team will add a label that will be used to add context and status of the issue:
-
-![oni Bugs/Enhancement](docs/label-tracking.bmp)
-
-* **Wontfix:** We won't fix this issue, as part of current release or roadmap.  It  will be a nice-to-have
-* **Tracked:** This issue is already part of our backlog and will be planned for future releases.
-* **Duplicated:** The issue already exists.
-* **Invalid:** Expected ONI functionality based in the functional spec.
-* **Help wanted:** More details are required to understand the reported issue.
-
-![oni Design](docs/labels-design-tracking.bmp)
-
-* **Design Review:** After a Design Spec has been submitted, this label will be applied to notify the contributor this design is under review and pending approval.
-The Maintainers of ONI recommend submitting a Design Spec prior to coding feature enhancements or major changes to the code base.
-* **Code Review**: This label indicates the Design has been approved and we are ready to review a PR related to your Design Spec.
-* **Documentation Review**: After the code has been approved, The related documentation will need to be updated and approved.
-* **Ready to Merge**: Success! this has been tested and is now ready to be merged pending LGTM from the maintainers.
-
-
-
-
-
-
-
-
-


[03/50] [abbrv] incubator-spot git commit: Spot ui colors (#138)

Posted by ev...@apache.org.
Spot ui colors (#138)

* Using Spot color palette

Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/717982f4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/717982f4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/717982f4

Branch: refs/heads/master
Commit: 717982f4a72425f6885b461afdd1869532d8e751
Parents: fb9da79
Author: daortizh <di...@intel.com>
Authored: Fri Nov 18 12:32:36 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Fri Nov 18 12:32:36 2016 -0600

----------------------------------------------------------------------
 spot-oa/ui/css/bootstrap-spot-theme.less        |  274 ++++
 spot-oa/ui/css/bootstrap-spot-variables.less    |  389 +++++
 spot-oa/ui/css/bootstrap-spot.min.css           | 1484 ++++++++++++++++++
 spot-oa/ui/css/main.css                         |    1 -
 spot-oa/ui/css/poc.css                          |  307 ----
 .../dns/js/components/SuspiciousPanel.react.js  |    2 +-
 spot-oa/ui/dns/storyboard.html                  |    8 +-
 spot-oa/ui/dns/suspicious.html                  |   10 +-
 spot-oa/ui/dns/threat-investigation.html        |    8 +-
 spot-oa/ui/flow/ingest-summary.html             |    8 +-
 .../flow/js/components/SuspiciousPanel.react.js |    2 +-
 spot-oa/ui/flow/storyboard.html                 |    8 +-
 spot-oa/ui/flow/suspicious.html                 |   10 +-
 spot-oa/ui/flow/threat-investigation.html       |    8 +-
 spot-oa/ui/package.json                         |    1 +
 spot-oa/ui/proxy/storyboard.html                |    8 +-
 spot-oa/ui/proxy/suspicious.html                |   10 +-
 spot-oa/ui/proxy/threat-investigation.html      |    8 +-
 18 files changed, 2176 insertions(+), 370 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/css/bootstrap-spot-theme.less
----------------------------------------------------------------------
diff --git a/spot-oa/ui/css/bootstrap-spot-theme.less b/spot-oa/ui/css/bootstrap-spot-theme.less
new file mode 100644
index 0000000..3de44a1
--- /dev/null
+++ b/spot-oa/ui/css/bootstrap-spot-theme.less
@@ -0,0 +1,274 @@
+/*****************************************
+ **              Spot Header            **
+ *****************************************/
+
+#spot-nav {
+  border: none;
+}
+
+#search-box {
+  background-color: rgb(224, 224, 224);
+  color: @gray-base;
+  padding: 5px 0;
+}
+
+#search-box .form-group {
+    margin-left: 10px;
+}
+
+/*****************************************
+ **         Spot loading spinner        **
+ *****************************************/
+
+.spot-loader
+{
+    text-align: center;
+    margin-top: 20px;
+}
+
+.spot-loader .spinner
+{
+    display: inline-block;
+    width: 16px;
+    height: 11px;
+    margin-left: 5px;
+    background-image: url(../images/ajax-loader.gif);
+}
+
+/*****************************************
+ **             Spot Tooltip            **
+ *****************************************/
+
+.d3-tip {
+    line-height: 1;
+    padding: 12px;
+    background: rgba(0, 0, 0, 0.9);
+    color: #fff;
+    border-radius: 5px;
+    font-size: 12px;
+    z-index: 10000;
+}
+
+.d3-tip .d3-tip-label {
+    color: #888888;
+    font-weight: bold;
+}
+
+.d3-tip .d3-tip-label strong {
+    color: white;
+}
+
+.d3-tip .d3-tip-message {
+    font-size: 12px;
+    text-align: left;
+    word-break: break-all;
+}
+
+/* Creates a small triangle extender for the tooltip */
+.d3-tip:after {
+    box-sizing: border-box;
+    display: inline;
+    font-size: 10px;
+    width: 100%;
+    line-height: 1;
+    color: rgba(0, 0, 0, 0.8);
+    position: absolute;
+    pointer-events: none;
+}
+
+/* Northward tooltips */
+.d3-tip.n:after {
+    content: "\25BC";
+    margin: -1px 0 0 0;
+    top: 100%;
+    left: 0;
+    text-align: center;
+}
+
+/* Eastward tooltips */
+.d3-tip.e:after {
+    content: "\25C0";
+    margin: -4px 0 0 0;
+    top: 50%;
+    left: -8px;
+}
+
+/* Southward tooltips */
+.d3-tip.s:after {
+    content: "\25B2";
+    margin: 0 0 1px 0;
+    top: -8px;
+    left: 0;
+    text-align: center;
+}
+
+/* Westward tooltips */
+.d3-tip.w:after {
+    content: "\25B6";
+    margin: -4px 0 0 -1px;
+    top: 50%;
+    left: 100%;
+}
+
+/* Northwestward tooltips */
+.d3-tip.nw:after {
+    content: "\25E2";
+    margin: -5px 0 0 -5px;
+    top: 100%;
+    left: 100%;
+}
+
+/* Northestward tooltips */
+.d3-tip.ne:after {
+    content: "\25E3";
+    margin: -5px 0 0 0;
+    top: 100%;
+    left: -4px;
+}
+
+/* Southestward tooltips */
+.d3-tip.se:after {
+    content: "\25E4";
+    top: -4px;
+    left: -4px;
+}
+
+/* Southwestward tooltips */
+.d3-tip.sw:after {
+    content: "\25E5";
+    margin: 0 0 0 -5px;
+    top: -4px;
+    left: 100%;
+}
+
+/*****************************************
+ **          Spot Network View          **
+ *****************************************/
+.edge {
+    stroke-width: 3px;
+    transition: stroke .5s linear;
+}
+
+.edge.active {
+    stroke: @brand-warning !important;
+    stroke-opacity: 1 !important;
+}
+
+.edge.highlight {
+    stroke: @brand-warning !important;
+    stroke-opacity: 1 !important;
+}
+
+.edge-faded {
+    stroke-opacity: 0.2 !important;
+}
+
+.node-faded, .faded {
+    fill-opacity: 0.2 !important;
+    stroke-opacity: 0.2 !important;
+}
+
+.node {
+    stroke: hsl(0,60%,100%);
+    stroke-width: 2.5px;
+    fill: @brand-warning;
+}
+
+/*-------------------------- Flashing/ blinker Animation----------------------*/
+.blink_me {
+    -webkit-animation-name: blinker;
+    -webkit-animation-duration: 1.5s;
+    -webkit-animation-timing-function: linear;
+    -webkit-animation-iteration-count: infinite;
+    -moz-animation-name: blinker;
+    -moz-animation-duration: 1.5s;
+    -moz-animation-timing-function: linear;
+    -moz-animation-iteration-count: infinite;
+    animation-name: blinker;
+    animation-duration: 1.5s;
+    animation-timing-function: linear;
+    animation-iteration-count: infinite;
+}
+
+.proxy-force .edge.blink_me {
+    stroke: @brand-warning;
+}
+
+@-moz-keyframes blinker {
+    0% {
+        stroke-opacity: 1.0;
+        fill-opacity: 1.0;
+    }
+
+    50% {
+        stroke-opacity: 0.3;
+        fill-opacity: 0.3;
+    }
+
+    100% {
+        stroke-opacity: 1.0;
+        fill-opacity: 1.0;
+    }
+}
+
+@-webkit-keyframes blinker {
+    0% {
+        stroke-opacity: 1.0;
+        fill-opacity: 1.0;
+    }
+
+    50% {
+        stroke-opacity: 0.3;
+        fill-opacity: 0.3;
+    }
+
+    100% {
+        stroke-opacity: 1.0;
+        fill-opacity: 1.0;
+    }
+}
+
+@keyframes blinker {
+    0% {
+        stroke-opacity: 1.0;
+        fill-opacity: 1.0;
+    }
+
+    50% {
+        stroke-opacity: 0.3;
+        fill-opacity: 0.3;
+    }
+
+    100% {
+        stroke-opacity: 1.0;
+        fill-opacity: 1.0;
+    }
+}
+
+/*************************************
+ **      Spot Chords Diagram        **
+ *************************************/
+
+.chord path {
+    fill-opacity: .67;
+    stroke: #000;
+    stroke-width: .5px;
+}
+
+/*************************************
+ **      Spot Ingest Summary        **
+ *************************************/
+
+.x.axis path {
+    stroke: #000;
+}
+
+.y.axis path {
+    stroke: #000;
+}
+
+path.line {
+    fill: none;
+    stroke: #000;
+    stroke-width: .5px;
+}

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/css/bootstrap-spot-variables.less
----------------------------------------------------------------------
diff --git a/spot-oa/ui/css/bootstrap-spot-variables.less b/spot-oa/ui/css/bootstrap-spot-variables.less
new file mode 100644
index 0000000..9be53ef
--- /dev/null
+++ b/spot-oa/ui/css/bootstrap-spot-variables.less
@@ -0,0 +1,389 @@
+/*! Generated by Live LESS Theme Customizer */
+
+@gray-base: rgb(12, 11, 12);
+@gray-darker: rgb(76, 75, 81);
+@gray-dark: rgb(130, 131, 126);
+@gray: rgb(163,163,160);
+@gray-light: rgb(198, 194, 190);
+@gray-lighter: rgb(214, 212, 208);
+@brand-primary: rgb(23,77,114);
+@brand-success: rgb(92, 184, 92);
+@brand-info: rgb(91, 192, 222);
+@brand-warning: rgb(247, 167, 6);
+@brand-danger: rgb(217, 83, 79);
+@body-bg: rgb(255, 255, 255);
+@text-color: @gray-dark;
+@link-color: @brand-primary;
+@link-hover-color: @brand-warning;
+@link-hover-decoration: underline;
+@font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif;
+@font-family-serif: Georgia, "Times New Roman", Times, serif;
+@font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace;
+@font-family-base: @font-family-sans-serif;
+@font-size-base: 14px;
+@font-size-large: ceil((@font-size-base * 1.25));
+@font-size-small: ceil((@font-size-base * 0.85));
+@font-size-h1: floor((@font-size-base * 2.6));
+@font-size-h2: floor((@font-size-base * 2.15));
+@font-size-h3: ceil((@font-size-base * 1.7));
+@font-size-h4: ceil((@font-size-base * 1.25));
+@font-size-h5: @font-size-base;
+@font-size-h6: ceil((@font-size-base * 0.85));
+@line-height-base: 1.428571429;
+@line-height-computed: floor((@font-size-base * @line-height-base));
+@headings-font-family: inherit;
+@headings-font-weight: 500;
+@headings-line-height: 1.1;
+@headings-color: inherit;
+@icon-font-path: "../node_modules/bootstrap/fonts/";
+@icon-font-name: "glyphicons-halflings-regular";
+@icon-font-svg-id: "glyphicons_halflingsregular";
+@padding-base-vertical: 6px;
+@padding-base-horizontal: 12px;
+@padding-large-vertical: 10px;
+@padding-large-horizontal: 16px;
+@padding-small-vertical: 5px;
+@padding-small-horizontal: 10px;
+@padding-xs-vertical: 1px;
+@padding-xs-horizontal: 5px;
+@line-height-large: 1.3333333;
+@line-height-small: 1.5;
+@border-radius-base: 4px;
+@border-radius-large: 6px;
+@border-radius-small: 3px;
+@component-active-color: rgb(255, 255, 255);
+@component-active-bg: @brand-primary;
+@caret-width-base: 4px;
+@caret-width-large: 5px;
+@table-cell-padding: 8px;
+@table-condensed-cell-padding: 5px;
+@table-bg: transparent;
+@table-bg-accent: rgb(249, 249, 249);
+@table-bg-hover: rgb(245, 245, 245);
+@table-bg-active: @table-bg-hover;
+@table-border-color: rgb(221, 221, 221);
+@btn-font-weight: normal;
+@btn-default-color: rgb(51, 51, 51);
+@btn-default-bg: rgb(255, 255, 255);
+@btn-default-border: rgb(204, 204, 204);
+@btn-primary-color: rgb(255, 255, 255);
+@btn-primary-bg: @brand-primary;
+@btn-primary-border: darken(@btn-primary-bg, 5%);
+@btn-success-color: rgb(255, 255, 255);
+@btn-success-bg: @brand-success;
+@btn-success-border: darken(@btn-success-bg, 5%);
+@btn-info-color: rgb(255, 255, 255);
+@btn-info-bg: @brand-info;
+@btn-info-border: darken(@btn-info-bg, 5%);
+@btn-warning-color: rgb(255, 255, 255);
+@btn-warning-bg: @brand-warning;
+@btn-warning-border: darken(@btn-warning-bg, 5%);
+@btn-danger-color: rgb(255, 255, 255);
+@btn-danger-bg: @brand-danger;
+@btn-danger-border: darken(@btn-danger-bg, 5%);
+@btn-link-disabled-color: @gray-light;
+@btn-border-radius-base: @border-radius-base;
+@btn-border-radius-large: @border-radius-large;
+@btn-border-radius-small: @border-radius-small;
+@input-bg: rgb(255, 255, 255);
+@input-bg-disabled: @gray-lighter;
+@input-color: @gray;
+@input-border: rgb(204, 204, 204);
+@input-border-radius: @border-radius-base;
+@input-border-radius-large: @border-radius-large;
+@input-border-radius-small: @border-radius-small;
+@input-border-focus: rgb(102, 175, 233);
+@input-color-placeholder: rgb(153, 153, 153);
+@input-height-base: (@line-height-computed + (@padding-base-vertical * 2) + 2);
+@input-height-large: (ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2);
+@input-height-small: (floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2);
+@form-group-margin-bottom: 15px;
+@legend-color: @gray-dark;
+@legend-border-color: rgb(229, 229, 229);
+@input-group-addon-bg: @gray-lighter;
+@input-group-addon-border-color: @input-border;
+@cursor-disabled: not-allowed;
+@dropdown-bg: rgb(255, 255, 255);
+@dropdown-border: rgba(0, 0, 0, 0.15);
+@dropdown-fallback-border: rgb(204, 204, 204);
+@dropdown-divider-bg: rgb(229, 229, 229);
+@dropdown-link-color: @gray-dark;
+@dropdown-link-hover-color: darken(@gray-dark, 5%);
+@dropdown-link-hover-bg: rgb(245, 245, 245);
+@dropdown-link-active-color: @component-active-color;
+@dropdown-link-active-bg: @component-active-bg;
+@dropdown-link-disabled-color: @gray-light;
+@dropdown-header-color: @gray-light;
+@dropdown-caret-color: rgb(0, 0, 0);
+@zindex-navbar: 1000;
+@zindex-dropdown: 1000;
+@zindex-popover: 1060;
+@zindex-tooltip: 1070;
+@zindex-navbar-fixed: 1030;
+@zindex-modal-background: 1040;
+@zindex-modal: 1050;
+@screen-xs: 480px;
+@screen-xs-min: @screen-xs;
+@screen-phone: @screen-xs-min;
+@screen-sm: 768px;
+@screen-sm-min: @screen-sm;
+@screen-tablet: @screen-sm-min;
+@screen-md: 992px;
+@screen-md-min: @screen-md;
+@screen-desktop: @screen-md-min;
+@screen-lg: 1200px;
+@screen-lg-min: @screen-lg;
+@screen-lg-desktop: @screen-lg-min;
+@screen-xs-max: (@screen-sm-min - 1);
+@screen-sm-max: (@screen-md-min - 1);
+@screen-md-max: (@screen-lg-min - 1);
+@grid-columns: 12;
+@grid-gutter-width: 30px;
+@grid-float-breakpoint: @screen-sm-min;
+@grid-float-breakpoint-max: (@grid-float-breakpoint - 1);
+@container-tablet: (720px + @grid-gutter-width);
+@container-sm: @container-tablet;
+@container-desktop: (940px + @grid-gutter-width);
+@container-md: @container-desktop;
+@container-large-desktop: (1140px + @grid-gutter-width);
+@container-lg: @container-large-desktop;
+@navbar-height: 50px;
+@navbar-margin-bottom: @line-height-computed;
+@navbar-border-radius: @border-radius-base;
+@navbar-padding-horizontal: floor((@grid-gutter-width / 2));
+@navbar-padding-vertical: ((@navbar-height - @line-height-computed) / 2);
+@navbar-collapse-max-height: 340px;
+@navbar-default-color: rgb(224, 224, 224);
+@navbar-default-bg: @brand-primary;
+@navbar-default-border: darken(@navbar-default-bg, 6.5%);
+@navbar-default-link-color: rgb(198, 194, 190);
+@navbar-default-link-hover-color: @brand-warning;
+@navbar-default-link-hover-bg: transparent;
+@navbar-default-link-active-color: @brand-warning;
+@navbar-default-link-active-bg: darken(@navbar-default-bg, 6.5%);
+@navbar-default-link-disabled-color: @gray-dark;
+@navbar-default-link-disabled-bg: transparent;
+@navbar-default-brand-color: rgb(232, 229, 224);
+@navbar-default-brand-hover-color: rgb(232, 229, 224);
+@navbar-default-brand-hover-bg: transparent;
+@navbar-default-toggle-hover-bg: rgb(221, 221, 221);
+@navbar-default-toggle-icon-bar-bg: rgb(136, 136, 136);
+@navbar-default-toggle-border-color: rgb(221, 221, 221);
+@navbar-inverse-color: lighten(@gray-light, 15%);
+@navbar-inverse-bg: rgb(34, 34, 34);
+@navbar-inverse-border: darken(@navbar-inverse-bg, 10%);
+@navbar-inverse-link-color: lighten(@gray-light, 15%);
+@navbar-inverse-link-hover-color: @brand-warning;
+@navbar-inverse-link-hover-bg: transparent;
+@navbar-inverse-link-active-color: @navbar-inverse-link-hover-color;
+@navbar-inverse-link-active-bg: darken(@navbar-inverse-bg, 10%);
+@navbar-inverse-link-disabled-color: rgb(68, 68, 68);
+@navbar-inverse-link-disabled-bg: transparent;
+@navbar-inverse-brand-color: @navbar-inverse-link-color;
+@navbar-inverse-brand-hover-color: rgb(255, 255, 255);
+@navbar-inverse-brand-hover-bg: transparent;
+@navbar-inverse-toggle-hover-bg: rgb(51, 51, 51);
+@navbar-inverse-toggle-icon-bar-bg: rgb(255, 255, 255);
+@navbar-inverse-toggle-border-color: rgb(51, 51, 51);
+@nav-link-padding: 10px 15px;
+@nav-link-hover-bg: @gray-lighter;
+@nav-disabled-link-color: @gray-light;
+@nav-disabled-link-hover-color: @gray-light;
+@nav-tabs-border-color: rgb(221, 221, 221);
+@nav-tabs-link-hover-border-color: @gray-lighter;
+@nav-tabs-active-link-hover-bg: @body-bg;
+@nav-tabs-active-link-hover-color: @gray;
+@nav-tabs-active-link-hover-border-color: rgb(221, 221, 221);
+@nav-tabs-justified-link-border-color: rgb(221, 221, 221);
+@nav-tabs-justified-active-link-border-color: @body-bg;
+@nav-pills-border-radius: @border-radius-base;
+@nav-pills-active-link-hover-bg: @component-active-bg;
+@nav-pills-active-link-hover-color: @component-active-color;
+@pagination-color: @link-color;
+@pagination-bg: rgb(255, 255, 255);
+@pagination-border: rgb(221, 221, 221);
+@pagination-hover-color: @link-hover-color;
+@pagination-hover-bg: @gray-lighter;
+@pagination-hover-border: rgb(221, 221, 221);
+@pagination-active-color: rgb(255, 255, 255);
+@pagination-active-bg: @brand-primary;
+@pagination-active-border: @brand-primary;
+@pagination-disabled-color: @gray-light;
+@pagination-disabled-bg: rgb(255, 255, 255);
+@pagination-disabled-border: rgb(221, 221, 221);
+@pager-bg: @pagination-bg;
+@pager-border: @pagination-border;
+@pager-border-radius: 15px;
+@pager-hover-bg: @pagination-hover-bg;
+@pager-active-bg: @pagination-active-bg;
+@pager-active-color: @pagination-active-color;
+@pager-disabled-color: @pagination-disabled-color;
+@jumbotron-padding: 30px;
+@jumbotron-color: inherit;
+@jumbotron-bg: @gray-lighter;
+@jumbotron-heading-color: inherit;
+@jumbotron-font-size: ceil((@font-size-base * 1.5));
+@jumbotron-heading-font-size: ceil((@font-size-base * 4.5));
+@state-success-text: rgb(60, 118, 61);
+@state-success-bg: rgb(223, 240, 216);
+@state-success-border: darken(spin(@state-success-bg, -10), 5%);
+@state-info-text: rgb(49, 112, 143);
+@state-info-bg: rgb(217, 237, 247);
+@state-info-border: darken(spin(@state-info-bg, -10), 7%);
+@state-warning-text: rgb(138, 109, 59);
+@state-warning-bg: rgb(252, 248, 227);
+@state-warning-border: darken(spin(@state-warning-bg, -10), 5%);
+@state-danger-text: rgb(169, 68, 66);
+@state-danger-bg: rgb(242, 222, 222);
+@state-danger-border: darken(spin(@state-danger-bg, -10), 5%);
+@tooltip-max-width: 200px;
+@tooltip-color: rgb(255, 255, 255);
+@tooltip-bg: rgb(0, 0, 0);
+@tooltip-opacity: .9;
+@tooltip-arrow-width: 5px;
+@tooltip-arrow-color: @tooltip-bg;
+@popover-bg: rgb(255, 255, 255);
+@popover-max-width: 276px;
+@popover-border-color: rgba(0, 0, 0, 0.2);
+@popover-fallback-border-color: rgb(204, 204, 204);
+@popover-title-bg: darken(@popover-bg, 3%);
+@popover-arrow-width: 10px;
+@popover-arrow-color: @popover-bg;
+@popover-arrow-outer-width: (@popover-arrow-width + 1);
+@popover-arrow-outer-color: fadein(@popover-border-color, 5%);
+@popover-arrow-outer-fallback-color: darken(@popover-fallback-border-color, 20%);
+@label-default-bg: @gray-light;
+@label-primary-bg: @brand-primary;
+@label-success-bg: @brand-success;
+@label-info-bg: @brand-info;
+@label-warning-bg: @brand-warning;
+@label-danger-bg: @brand-danger;
+@label-color: rgb(255, 255, 255);
+@label-link-hover-color: rgb(255, 255, 255);
+@modal-inner-padding: 15px;
+@modal-title-padding: 15px;
+@modal-title-line-height: @line-height-base;
+@modal-content-bg: rgb(255, 255, 255);
+@modal-content-border-color: rgba(0, 0, 0, 0.2);
+@modal-content-fallback-border-color: rgb(153, 153, 153);
+@modal-backdrop-bg: rgb(0, 0, 0);
+@modal-backdrop-opacity: .5;
+@modal-header-border-color: rgb(229, 229, 229);
+@modal-footer-border-color: @modal-header-border-color;
+@modal-lg: 900px;
+@modal-md: 600px;
+@modal-sm: 300px;
+@alert-padding: 15px;
+@alert-border-radius: @border-radius-base;
+@alert-link-font-weight: bold;
+@alert-success-bg: @state-success-bg;
+@alert-success-text: @state-success-text;
+@alert-success-border: @state-success-border;
+@alert-info-bg: @state-info-bg;
+@alert-info-text: @state-info-text;
+@alert-info-border: @state-info-border;
+@alert-warning-bg: @state-warning-bg;
+@alert-warning-text: @state-warning-text;
+@alert-warning-border: @state-warning-border;
+@alert-danger-bg: @state-danger-bg;
+@alert-danger-text: @state-danger-text;
+@alert-danger-border: @state-danger-border;
+@progress-bg: rgb(245, 245, 245);
+@progress-bar-color: rgb(255, 255, 255);
+@progress-border-radius: @border-radius-base;
+@progress-bar-bg: @brand-primary;
+@progress-bar-success-bg: @brand-success;
+@progress-bar-warning-bg: @brand-warning;
+@progress-bar-danger-bg: @brand-danger;
+@progress-bar-info-bg: @brand-info;
+@list-group-bg: rgb(255, 255, 255);
+@list-group-border: rgb(221, 221, 221);
+@list-group-border-radius: @border-radius-base;
+@list-group-hover-bg: rgb(245, 245, 245);
+@list-group-active-color: @component-active-color;
+@list-group-active-bg: @component-active-bg;
+@list-group-active-border: @list-group-active-bg;
+@list-group-active-text-color: lighten(@list-group-active-bg, 40%);
+@list-group-disabled-color: @gray-light;
+@list-group-disabled-bg: @gray-lighter;
+@list-group-disabled-text-color: @list-group-disabled-color;
+@list-group-link-color: rgb(85, 85, 85);
+@list-group-link-hover-color: @list-group-link-color;
+@list-group-link-heading-color: rgb(51, 51, 51);
+@panel-bg: rgb(255, 255, 255);
+@panel-body-padding: 15px;
+@panel-heading-padding: 10px 15px;
+@panel-footer-padding: @panel-heading-padding;
+@panel-border-radius: @border-radius-base;
+@panel-inner-border: rgb(221, 221, 221);
+@panel-footer-bg: rgb(245, 245, 245);
+@panel-default-text: @gray-dark;
+@panel-default-border: rgb(221, 221, 221);
+@panel-default-heading-bg: rgb(245, 245, 245);
+@panel-primary-text: rgb(255, 255, 255);
+@panel-primary-border: @brand-primary;
+@panel-primary-heading-bg: @brand-primary;
+@panel-success-text: @state-success-text;
+@panel-success-border: @state-success-border;
+@panel-success-heading-bg: @state-success-bg;
+@panel-info-text: @state-info-text;
+@panel-info-border: @state-info-border;
+@panel-info-heading-bg: @state-info-bg;
+@panel-warning-text: @state-warning-text;
+@panel-warning-border: @state-warning-border;
+@panel-warning-heading-bg: @state-warning-bg;
+@panel-danger-text: @state-danger-text;
+@panel-danger-border: @state-danger-border;
+@panel-danger-heading-bg: @state-danger-bg;
+@thumbnail-padding: 4px;
+@thumbnail-bg: @body-bg;
+@thumbnail-border: rgb(221, 221, 221);
+@thumbnail-border-radius: @border-radius-base;
+@thumbnail-caption-color: @text-color;
+@thumbnail-caption-padding: 9px;
+@well-bg: rgb(245, 245, 245);
+@well-border: darken(@well-bg, 7%);
+@badge-color: rgb(255, 255, 255);
+@badge-link-hover-color: rgb(255, 255, 255);
+@badge-bg: @gray-light;
+@badge-active-color: @link-color;
+@badge-active-bg: rgb(255, 255, 255);
+@badge-font-weight: bold;
+@badge-line-height: 1;
+@badge-border-radius: 10px;
+@breadcrumb-padding-vertical: 8px;
+@breadcrumb-padding-horizontal: 15px;
+@breadcrumb-bg: rgb(245, 245, 245);
+@breadcrumb-color: rgb(204, 204, 204);
+@breadcrumb-active-color: @gray-light;
+@breadcrumb-separator: "/";
+@carousel-text-shadow: 0 1px 2px rgba(0,0,0,.6);
+@carousel-control-color: rgb(255, 255, 255);
+@carousel-control-width: 15%;
+@carousel-control-opacity: .5;
+@carousel-control-font-size: 20px;
+@carousel-indicator-active-bg: rgb(255, 255, 255);
+@carousel-indicator-border-color: rgb(255, 255, 255);
+@carousel-caption-color: rgb(255, 255, 255);
+@close-font-weight: bold;
+@close-color: rgb(0, 0, 0);
+@close-text-shadow: 0 1px 0 #fff;
+@code-color: rgb(199, 37, 78);
+@code-bg: rgb(249, 242, 244);
+@kbd-color: rgb(255, 255, 255);
+@kbd-bg: rgb(51, 51, 51);
+@pre-bg: rgb(245, 245, 245);
+@pre-color: @gray-dark;
+@pre-border-color: rgb(204, 204, 204);
+@pre-scrollable-max-height: 340px;
+@component-offset-horizontal: 180px;
+@text-muted: @gray-light;
+@abbr-border-color: @gray-light;
+@headings-small-color: @gray-light;
+@blockquote-small-color: @gray-light;
+@blockquote-font-size: (@font-size-base * 1.25);
+@blockquote-border-color: @gray-lighter;
+@page-header-border-color: @gray-lighter;
+@dl-horizontal-offset: @component-offset-horizontal;
+@hr-border: @gray-lighter;
+


[26/50] [abbrv] incubator-spot git commit: Adding ingest summary functionality to OA module

Posted by ev...@apache.org.
Adding ingest summary functionality to OA module


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

Branch: refs/heads/master
Commit: 3cb7dbe38e11a5f4dd43aaaaf3e90490c18dda30
Parents: 9763e2a
Author: elopezsa <ev...@intel.com>
Authored: Wed Nov 30 09:46:58 2016 -0600
Committer: elopezsa <ev...@intel.com>
Committed: Wed Nov 30 09:46:58 2016 -0600

----------------------------------------------------------------------
 spot-ingest/README.md      | 21 +++++++++++----
 spot-oa/oa/flow/flow_oa.py | 58 ++++++++++++++++++++++++++++++++++-------
 2 files changed, 64 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/3cb7dbe3/spot-ingest/README.md
----------------------------------------------------------------------
diff --git a/spot-ingest/README.md b/spot-ingest/README.md
index 193ea9f..6239844 100644
--- a/spot-ingest/README.md
+++ b/spot-ingest/README.md
@@ -22,7 +22,7 @@ Ingest data is captured or transferred into the Hadoop cluster, where they are t
 
 Ingest framework needs Kafka to work in real-time streaming. Add Kafka service using Cloudera Manager. If you are using a Cloudera Manager version < 5.4.1 you will need to add the kafka parcel manually.
 
-Ingest module uses a default configuration for the message size (999999 bytes), if you modify this size in the ingest configuration file you will need to modify the following configuration properties in kafka:
+Ingest module uses a default configuration for the message size (900000 bytes), if you modify this size in the ingest configuration file you will need to modify the following configuration properties in kafka:
 
 * message.max.bytes
 * replica.fetch.max.bytes
@@ -48,19 +48,30 @@ The file **ingest_conf.json** contains all the required configuration to start t
 *  **dbname:** Name of HIVE database where all the ingested data will be stored in avro-parquet format.
 *  **hdfs_app_path:** Application path in HDFS where the pipelines will be stored (i.e /user/_application_user_/). 
 *  **kafka:** Kafka and Zookeeper server information required to create/listen topics and partitions.
+*  **collector_processes:** Ingest framework uses  multiprocessing to collect files (different from workers), this configuration key defines the numbers of collector processes to use.
+*  **spark-streaming:** Proxy pipeline uses spark streaming to ingest data, this configuration is required to setup the spark application for more details please check : [how to configure spark](https://github.com/Open-Network-Insight/open-network-insight/blob/spot/spot-ml/SPARKCONF.md)
 *  **pipelines:** In this section you can add multiple configurations for either the same pipeline or different pipelines. The configuration name must be lowercase without spaces (i.e. flow_internals).
 
 **Configuration example:**
 
-      "dbname" : "database name",
-      "hdfs_app_path" : "hdfs application path",
+     "dbname" : "database name",
+     "hdfs_app_path" : "hdfs application path",
+     "collector_processes":5,
+     "ingestion_interval":1,
+     "spark-streaming":{
+                "driver_memory":"",
+                "spark_exec":"",
+                "spark_executor_memory":"",
+                "spark_executor_cores":"",
+                "spark_batch_size":""
+      },
       "kafka":{
             "kafka_server":"kafka ip",
             "kafka_port":"kafka port",
             "zookeper_server":"zk ip",
             "zookeper_port":"zk port",
-            "message_size":999999
-       },
+            "message_size":900000
+        },
       "pipelines":{
       
          "flow_internals":{

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/3cb7dbe3/spot-oa/oa/flow/flow_oa.py
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/flow_oa.py b/spot-oa/oa/flow/flow_oa.py
index 1fbd503..50ecf9a 100644
--- a/spot-oa/oa/flow/flow_oa.py
+++ b/spot-oa/oa/flow/flow_oa.py
@@ -284,17 +284,17 @@ class OA(object):
 
     def _get_oa_details(self):
 
-	self._logger.info("Getting OA Flow suspicious details/chord diagram")
-	# start suspicious connects details process.
-	p_sp = Process(target=self._get_suspicious_details)
-	p_sp.start()
+        self._logger.info("Getting OA Flow suspicious details/chord diagram")
+        # start suspicious connects details process.
+        p_sp = Process(target=self._get_suspicious_details)
+        p_sp.start()
 
-	# start chord diagram process.
-	p_ch = Process(target=self._get_chord_details)
-	p_ch.start()
+        # start chord diagram process.
+        p_ch = Process(target=self._get_chord_details)
+        p_ch.start()
 
-	p_sp.join()
-	p_ch.join()
+        p_sp.join()
+        p_ch.join()
 
 	
     def _get_suspicious_details(self,bar=None):
@@ -385,6 +385,44 @@ class OA(object):
                     self._engine.query(ch_query.format(self._db,self._table_name,yr,mn,dy,ip,ips_filter),chord_file,delimiter="\\t")
 
      
- 
+    def _ingest_summary(self):
+        
+        # get date parameters.
+        yr = self._date[:4]
+        mn = self._date[4:6]
+        dy = self._date[6:]
 
+        # get ingest summary.           
+        ingest_summary_qry = ("SELECT tryear, trmonth, trday, trhour, trminute, COUNT(*) flows"
+                              " FROM onidb.flow "
+                              " WHERE "
+                              " y={0} "
+                              " AND m={1} "
+                              " AND d={2} "
+                              " AND unix_tstamp IS NOT NULL "
+                              " GROUP BY tryear, trmonth, trday, trhour, trminute;")
+
+        ingest_summary_qry = ingest_summary_qry.format(yr,mn,dy)
+
+        results_file = "{0}/results_{1}.csv".format(self._data_path,self._date)
+        self._engine.query(ingest_summary_qry,output_file=results_file,delimiter=",")
+        
+        result_rows = []        
+        with open(results_file, 'rb') as rf:
+            csv_reader = csv.reader(rf, delimiter = ",")
+            result_rows = list(csv_reader)
+        
+        result_rows = iter(result_rows)
+        next(result_rows)
+        ingest_summary_results2 = [ ["{0}-{1}-{2} {3}:{4}".format(yr,mn,dy,row[3],row[4]), row[5]] for row in result_rows ]
+        ingest_summay_file = "{0}/is_{1}.csv".format(self._data_path,self._date)
+
+        write_format =  'a' if os.path.isfile(ingest_summay_file) else 'w+'
+        with open(ingest_summay_file, write_format) as u_file:
+            writer = csv.writer(u_file, quoting=csv.QUOTE_NONE, delimiter=",")
+            writer.writerows(ingest_summary_results2)
+
+        rm_big_file = "rm {0}".format(results_file)
+        os.remove(results_file)
+       
 


[39/50] [abbrv] incubator-spot git commit: fixup! Adding unit test cases to UI (#160) (#161)

Posted by ev...@apache.org.
fixup! Adding unit test cases to UI (#160) (#161)



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

Branch: refs/heads/master
Commit: ee98df816ae3b3b2cabde25f2ebbe5904bf6384a
Parents: 2827768
Author: daortizh <di...@intel.com>
Authored: Mon Dec 5 14:44:20 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Mon Dec 5 14:44:20 2016 -0600

----------------------------------------------------------------------
 .../js/components/DetailsTablePanel.react.js    |  2 +-
 .../IncidentProgressionPanel.react.js           |  2 +-
 spot-oa/ui/dns/js/stores/SuspiciousStore.js     | 24 ++++++++-------
 .../js/components/DetailsTablePanel.react.js    |  2 +-
 spot-oa/ui/flow/js/stores/SuspiciousStore.js    | 23 ++++++++-------
 .../ui/js/components/DetailsGridMixin.react.js  |  2 +-
 .../ExecutiveThreatBriefingPanel.react.js       |  2 +-
 .../js/components/SuspiciousGridMixin.react.js  |  4 +--
 spot-oa/ui/proxy/js/stores/SuspiciousStore.js   | 31 +++++++++++---------
 spot-oa/ui/proxy/js/stores/TimelineStore.js     |  4 +++
 10 files changed, 54 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/ee98df81/spot-oa/ui/dns/js/components/DetailsTablePanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/dns/js/components/DetailsTablePanel.react.js b/spot-oa/ui/dns/js/components/DetailsTablePanel.react.js
index fcc0262..c6098cd 100755
--- a/spot-oa/ui/dns/js/components/DetailsTablePanel.react.js
+++ b/spot-oa/ui/dns/js/components/DetailsTablePanel.react.js
@@ -45,7 +45,7 @@ var DetailsTablePanel = React.createClass({
   _render_dns_qry_type_cell: false,
   _onChange: function ()
   {
-    this.setState(DetailsStore.getData());
+    this.replaceState(DetailsStore.getData());
   }
 });
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/ee98df81/spot-oa/ui/dns/js/components/IncidentProgressionPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/dns/js/components/IncidentProgressionPanel.react.js b/spot-oa/ui/dns/js/components/IncidentProgressionPanel.react.js
index babca3b..ff29adb 100755
--- a/spot-oa/ui/dns/js/components/IncidentProgressionPanel.react.js
+++ b/spot-oa/ui/dns/js/components/IncidentProgressionPanel.react.js
@@ -28,7 +28,7 @@ const IncidentProgressionPanel = React.createClass({
     if (!storeData.loading) {
         state.error = storeData.error;
 
-        if (storeData.data.length) {
+        if (storeData.data && storeData.data.length) {
           let filterName = IncidentProgressionStore.getFilterName();
 
           state.data = {

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/ee98df81/spot-oa/ui/dns/js/stores/SuspiciousStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/dns/js/stores/SuspiciousStore.js b/spot-oa/ui/dns/js/stores/SuspiciousStore.js
index bde067d..2ae19a8 100755
--- a/spot-oa/ui/dns/js/stores/SuspiciousStore.js
+++ b/spot-oa/ui/dns/js/stores/SuspiciousStore.js
@@ -47,21 +47,23 @@ var SuspiciousStore = assign(new RestStore(DnsConstants.API_SUSPICIOUS), {
     {
         state = assign(
             {},
-            unfilteredData,
-            {
-                data: unfilteredData.data.filter(function (item)
-                {
-                    return filterName===IP_FILTER ? item[filterName]==filter : item[filterName].indexOf(filter)>=0;
-                })
-            }
+            unfilteredData
         );
+
+        if (unfilteredData.data) {
+            state.data = unfilteredData.data.filter(function (item) {
+                return filterName===IP_FILTER ? item[filterName]==filter : item[filterName].indexOf(filter)>=0;
+            });
+        }
     }
 
-    state.data = state.data.filter(function (item) {
-        return item.dns_sev=="0";
-    });
+    if (state.data) {
+        state.data = state.data.filter(function (item) {
+            return item.dns_sev=="0";
+        });
 
-    if (state.data.length>SpotConstants.MAX_SUSPICIOUS_ROWS) state.data = state.data.slice(0, SpotConstants.MAX_SUSPICIOUS_ROWS);
+        if (state.data.length>SpotConstants.MAX_SUSPICIOUS_ROWS) state.data = state.data.slice(0, SpotConstants.MAX_SUSPICIOUS_ROWS);
+    }
 
     return state;
   },

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/ee98df81/spot-oa/ui/flow/js/components/DetailsTablePanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/components/DetailsTablePanel.react.js b/spot-oa/ui/flow/js/components/DetailsTablePanel.react.js
index bc5e1f0..07aca01 100755
--- a/spot-oa/ui/flow/js/components/DetailsTablePanel.react.js
+++ b/spot-oa/ui/flow/js/components/DetailsTablePanel.react.js
@@ -20,7 +20,7 @@ var DetailsTablePanel = React.createClass({
   // Event handlers
   _onChange: function ()
   {
-    this.setState(DetailsStore.getData());
+    this.replaceState(DetailsStore.getData());
   }
 });
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/ee98df81/spot-oa/ui/flow/js/stores/SuspiciousStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/stores/SuspiciousStore.js b/spot-oa/ui/flow/js/stores/SuspiciousStore.js
index 49a7e7d..4053915 100755
--- a/spot-oa/ui/flow/js/stores/SuspiciousStore.js
+++ b/spot-oa/ui/flow/js/stores/SuspiciousStore.js
@@ -47,20 +47,23 @@ var SuspiciousStore = assign(new RestStore(NetflowConstants.API_SUSPICIOUS), {
         else {
             state = assign(
                 {},
-                unfilteredData,
-                {
-                    data: unfilteredData.data.filter(function (item) {
-                        return item['srcIP'] == filter || item['dstIP'] == filter;
-                    })
-                }
+                unfilteredData
             );
+
+            if (unfilteredData.data) {
+                state.data = unfilteredData.data.filter(function (item) {
+                    return item['srcIP'] == filter || item['dstIP'] == filter;
+                });
+            }
         }
 
-        state.data = state.data.filter(function (item) {
-            return item.sev == '0';
-        });
+        if (state.data) {
+            state.data = state.data.filter(function (item) {
+                return item.sev == '0';
+            });
 
-        if (state.data.length > SpotConstants.MAX_SUSPICIOUS_ROWS) state.data = state.data.slice(0, SpotConstants.MAX_SUSPICIOUS_ROWS);
+            if (state.data.length > SpotConstants.MAX_SUSPICIOUS_ROWS) state.data = state.data.slice(0, SpotConstants.MAX_SUSPICIOUS_ROWS);
+        }
 
         return state;
     },

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/ee98df81/spot-oa/ui/js/components/DetailsGridMixin.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/components/DetailsGridMixin.react.js b/spot-oa/ui/js/components/DetailsGridMixin.react.js
index 441c524..2ebb61c 100755
--- a/spot-oa/ui/js/components/DetailsGridMixin.react.js
+++ b/spot-oa/ui/js/components/DetailsGridMixin.react.js
@@ -15,7 +15,7 @@ var DetailsGridMixin = {
     // Event handler
     _onChange: function ()
     {
-        this.setState(this.store.getData());
+        this.replaceState(this.store.getData());
     }
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/ee98df81/spot-oa/ui/js/components/ExecutiveThreatBriefingPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/components/ExecutiveThreatBriefingPanel.react.js b/spot-oa/ui/js/components/ExecutiveThreatBriefingPanel.react.js
index e83efed..6687325 100755
--- a/spot-oa/ui/js/components/ExecutiveThreatBriefingPanel.react.js
+++ b/spot-oa/ui/js/components/ExecutiveThreatBriefingPanel.react.js
@@ -51,7 +51,7 @@ var ExecutiveThreatBriefingPanel = React.createClass({
     },
     _onChange: function ()
     {
-        this.setState(this.props.store.getData());
+        this.replaceState(this.props.store.getData());
     },
     _onSelect: function (comment)
     {

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/ee98df81/spot-oa/ui/js/components/SuspiciousGridMixin.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/components/SuspiciousGridMixin.react.js b/spot-oa/ui/js/components/SuspiciousGridMixin.react.js
index 71b8376..a8a9708 100755
--- a/spot-oa/ui/js/components/SuspiciousGridMixin.react.js
+++ b/spot-oa/ui/js/components/SuspiciousGridMixin.react.js
@@ -16,7 +16,7 @@ var SuspiciousGridMixin = {
         this.store.addChangeDataListener(this._onChange);
     },
     componentDidUpdate: function () {
-        if (this.state.loading || this.state.data.length===0) return;
+        if (this.state.loading || !this.state.data || this.state.data.length===0) return;
 
         $(ReactDOM.findDOMNode(this)).popover({
             trigger: 'hover',
@@ -60,7 +60,7 @@ var SuspiciousGridMixin = {
 
         state = this.store.getData();
 
-        this.setState(state);
+        this.replaceState(state);
     },
     _onClickRow: function (item) {
         this.selectItems(item);

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/ee98df81/spot-oa/ui/proxy/js/stores/SuspiciousStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/stores/SuspiciousStore.js b/spot-oa/ui/proxy/js/stores/SuspiciousStore.js
index 4877771..c548427 100755
--- a/spot-oa/ui/proxy/js/stores/SuspiciousStore.js
+++ b/spot-oa/ui/proxy/js/stores/SuspiciousStore.js
@@ -44,24 +44,27 @@ var SuspiciousStore = assign(new RestStore(ProxyConstants.API_SUSPICIOUS), {
         else {
             state = assign(
                 {},
-                this._data,
-                {
-                    data: this._data.data.filter((item) => {
-                        return filterName === URI_FILTER ?
-                                                    // Only look on URI field
-                                                    item[URI_FILTER].indexOf(filter) >= 0 :
-                                                    // Look on clientip and URI fields
-                                                    item.clientip == filter || item.fulluri.indexOf(filter) >= 0;
-                    })
-                }
+                this._data
             );
+
+            if (state.data) {
+                state.data = state.data.filter((item) => {
+                    return filterName === URI_FILTER ?
+                                                // Only look on URI field
+                                                item[URI_FILTER].indexOf(filter) >= 0 :
+                                                // Look on clientip and URI fields
+                                                item.clientip == filter || item.fulluri.indexOf(filter) >= 0;
+                });
+            }
         }
 
-        state.data = state.data.filter(function (item) {
-            return item.uri_sev == "0";
-        });
+        if (state.data) {
+            state.data = state.data.filter(function (item) {
+                return item.uri_sev == "0";
+            });
 
-        if (state.data.length > SpotConstants.MAX_SUSPICIOUS_ROWS) state.data = state.data.slice(0, SpotConstants.MAX_SUSPICIOUS_ROWS);
+            if (state.data.length > SpotConstants.MAX_SUSPICIOUS_ROWS) state.data = state.data.slice(0, SpotConstants.MAX_SUSPICIOUS_ROWS);
+        }
 
         return state;
     },

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/ee98df81/spot-oa/ui/proxy/js/stores/TimelineStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/stores/TimelineStore.js b/spot-oa/ui/proxy/js/stores/TimelineStore.js
index d9cf282..61f2bb9 100755
--- a/spot-oa/ui/proxy/js/stores/TimelineStore.js
+++ b/spot-oa/ui/proxy/js/stores/TimelineStore.js
@@ -43,6 +43,10 @@ SpotDispatcher.register(function (action) {
             TimelineStore.setDate(action.date);
 
             break;
+        case SpotConstants.RELOAD_COMMENTS:
+            TimelineStore.clearFilter();
+            TimelineStore.resetData();
+            break;
         case SpotConstants.SELECT_COMMENT:
             TimelineStore.setFilter(action.comment.hash);
 


[37/50] [abbrv] incubator-spot git commit: Merge pull request #155 from Open-Network-Insight/ingest_summary

Posted by ev...@apache.org.
Merge pull request #155 from Open-Network-Insight/ingest_summary

Ingest summary

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

Branch: refs/heads/master
Commit: bcd39a9a6bd2e51c155962f60e9049f3107a5ee5
Parents: 584f739 3e12813
Author: Everardo Lopez Sandoval <ev...@intel.com>
Authored: Fri Dec 2 10:57:23 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Fri Dec 2 10:57:23 2016 -0600

----------------------------------------------------------------------
 spot-oa/oa/flow/flow_oa.py | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/bcd39a9a/spot-oa/oa/flow/flow_oa.py
----------------------------------------------------------------------


[31/50] [abbrv] incubator-spot git commit: Merge pull request #148 from Open-Network-Insight/dns_rm_file_message

Posted by ev...@apache.org.
Merge pull request #148 from Open-Network-Insight/dns_rm_file_message

Remove original pcap file after the split

Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/6bcf4088
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/6bcf4088
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/6bcf4088

Branch: refs/heads/master
Commit: 6bcf4088f9ecba13cacd4d721734ec40a98e157f
Parents: ef20216 484a19b
Author: Nathanael Smith <na...@gmail.com>
Authored: Wed Nov 30 15:31:13 2016 -0800
Committer: GitHub <no...@github.com>
Committed: Wed Nov 30 15:31:13 2016 -0800

----------------------------------------------------------------------
 spot-ingest/pipelines/dns/collector.py | 47 ++++++++++++++---------------
 1 file changed, 22 insertions(+), 25 deletions(-)
----------------------------------------------------------------------



[45/50] [abbrv] incubator-spot git commit: Fixed missing iterator bug (#165)

Posted by ev...@apache.org.
Fixed missing iterator bug (#165)



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

Branch: refs/heads/master
Commit: 55be285b6f8925a7c9eba36b1a9352090a431e64
Parents: 83d157a
Author: daortizh <di...@intel.com>
Authored: Wed Dec 7 16:59:49 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Wed Dec 7 16:59:49 2016 -0600

----------------------------------------------------------------------
 .../js/components/DetailsTablePanel.react.js    |  4 ++--
 .../dns/js/components/SuspiciousPanel.react.js  |  2 +-
 .../js/components/DetailsTablePanel.react.js    |  2 +-
 .../flow/js/components/SuspiciousPanel.react.js |  2 +-
 .../ui/js/components/GridPanelMixin.react.js    | 20 +++++++++++---------
 .../js/components/SuspiciousPanel.react.js      |  2 +-
 6 files changed, 17 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/55be285b/spot-oa/ui/dns/js/components/DetailsTablePanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/dns/js/components/DetailsTablePanel.react.js b/spot-oa/ui/dns/js/components/DetailsTablePanel.react.js
index c6098cd..7e40621 100755
--- a/spot-oa/ui/dns/js/components/DetailsTablePanel.react.js
+++ b/spot-oa/ui/dns/js/components/DetailsTablePanel.react.js
@@ -6,9 +6,9 @@ var DetailsStore = require('../stores/DetailsStore');
 var DetailsTablePanel = React.createClass({
   mixins: [GridPanelMixin],
   emptySetMessage: 'Please select one row from Suspicious DNS',
-  getInitialState: function ()
+  getDefaultProps: function ()
   {
-    return DetailsStore.getData();
+    return {iterator: DetailsStore.ITERATOR};
   },
   componentDidMount: function ()
   {

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/55be285b/spot-oa/ui/dns/js/components/SuspiciousPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/dns/js/components/SuspiciousPanel.react.js b/spot-oa/ui/dns/js/components/SuspiciousPanel.react.js
index 6cc2a2f..9456671 100755
--- a/spot-oa/ui/dns/js/components/SuspiciousPanel.react.js
+++ b/spot-oa/ui/dns/js/components/SuspiciousPanel.react.js
@@ -8,7 +8,7 @@ var SuspiciousStore = require('../stores/SuspiciousStore');
 var SuspiciousPanel = React.createClass({
   mixins: [GridPanelMixin, SuspiciousGridMixin],
   store: SuspiciousStore,
-  getInitialState: function () {
+  getDefaultProps: function () {
     return {iterator: SuspiciousStore.ITERATOR};
   },
   _render_dns_qry_name_cell: function (query, item, idx)

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/55be285b/spot-oa/ui/flow/js/components/DetailsTablePanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/components/DetailsTablePanel.react.js b/spot-oa/ui/flow/js/components/DetailsTablePanel.react.js
index 07aca01..b98907d 100755
--- a/spot-oa/ui/flow/js/components/DetailsTablePanel.react.js
+++ b/spot-oa/ui/flow/js/components/DetailsTablePanel.react.js
@@ -6,7 +6,7 @@ var DetailsStore = require('../stores/DetailsStore');
 var DetailsTablePanel = React.createClass({
   mixins: [GridPanelMixin],
   emptySetMessage: 'Please select one row from Suspicious Connects',
-  getInitialState: function () {
+  getDefaultProps: function () {
       return {iterator: DetailsStore.ITERATOR};
   },
   componentDidMount: function ()

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/55be285b/spot-oa/ui/flow/js/components/SuspiciousPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/components/SuspiciousPanel.react.js b/spot-oa/ui/flow/js/components/SuspiciousPanel.react.js
index 3cb2b2c..f2f0c60 100755
--- a/spot-oa/ui/flow/js/components/SuspiciousPanel.react.js
+++ b/spot-oa/ui/flow/js/components/SuspiciousPanel.react.js
@@ -8,7 +8,7 @@ var SuspiciousStore = require('../stores/SuspiciousStore');
 var SuspiciousPanel = React.createClass({
     mixins: [GridPanelMixin, SuspiciousGridMixin],
     store: SuspiciousStore,
-    getInitialState: function () {
+    getDefaultProps: function () {
         return {iterator: SuspiciousStore.ITERATOR};
     },
     _renderGeoCell: function (keyPrefix, geo, domain) {

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/55be285b/spot-oa/ui/js/components/GridPanelMixin.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/components/GridPanelMixin.react.js b/spot-oa/ui/js/components/GridPanelMixin.react.js
index 149cb7f..99df28f 100755
--- a/spot-oa/ui/js/components/GridPanelMixin.react.js
+++ b/spot-oa/ui/js/components/GridPanelMixin.react.js
@@ -9,17 +9,19 @@ var GridPanelMixin = {
   },
   render: function ()
   {
-    var content, gridHeaders, gridBody, iterator, selectedRows, key, eventHandlers;
+    var state, content, gridHeaders, gridBody, iterator, selectedRows, key, eventHandlers;
 
-    if (this.state.error)
+    state = this.state || {};
+
+    if (state.error)
     {
       content = (
         <div className="text-center text-danger">
-          {this.state.error}
+          {state.error}
         </div>
       );
     }
-    else if (this.state.loading)
+    else if (state.loading)
     {
       content = (
         <div className="spot-loader">
@@ -27,7 +29,7 @@ var GridPanelMixin = {
         </div>
       );
     }
-    else if (!this.state.data || this.state.data.length===0)
+    else if (!state.data || state.data.length===0)
     {
         content = (
             <div className="text-center">
@@ -37,9 +39,9 @@ var GridPanelMixin = {
     }
     else
     {
-      iterator = this.state.iterator || Object.keys(this.state.headers);
+      iterator = this.props.iterator || Object.keys(state.headers);
 
-      selectedRows = this.state.selectedRows || [];
+      selectedRows = state.selectedRows || [];
 
       gridHeaders = [];
       iterator.forEach(key => {
@@ -47,12 +49,12 @@ var GridPanelMixin = {
         if (this['_render_' + key + '_cell']===false) return;
 
         gridHeaders.push(
-          <th key={'th_' + key} className={'text-center ' + key}>{this.state.headers[key]}</th>
+          <th key={'th_' + key} className={'text-center ' + key}>{state.headers[key]}</th>
         );
       });
 
       gridBody = [];
-      this.state.data.forEach((item, index) => {
+      state.data.forEach((item, index) => {
         var key, cells, className, cellRenderer, cellContent;
 
         cells = [];

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/55be285b/spot-oa/ui/proxy/js/components/SuspiciousPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/components/SuspiciousPanel.react.js b/spot-oa/ui/proxy/js/components/SuspiciousPanel.react.js
index c57ba2b..cdc48ed 100755
--- a/spot-oa/ui/proxy/js/components/SuspiciousPanel.react.js
+++ b/spot-oa/ui/proxy/js/components/SuspiciousPanel.react.js
@@ -9,7 +9,7 @@ var SuspiciousStore = require('../stores/SuspiciousStore');
 var SuspiciousPanel = React.createClass({
     mixins: [GridPanelMixin, SuspiciousMixin],
     store: SuspiciousStore,
-    getInitialState: function () {
+    getDefaultProps: function () {
         return {iterator: SuspiciousStore.ITERATOR};
     },
     _renderCatCell: function (keyPrefix, reps) {


[43/50] [abbrv] incubator-spot git commit: Ui data store fix (#164)

Posted by ev...@apache.org.
Ui data store fix (#164)

* fixup! Adding unit test cases to UI (#160)


Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/831ff7cf
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/831ff7cf
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/831ff7cf

Branch: refs/heads/master
Commit: 831ff7cf2f03ab0b8f4eca4b28055e2687fe0264
Parents: 39a376c
Author: daortizh <di...@intel.com>
Authored: Mon Dec 5 17:49:31 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Mon Dec 5 17:49:31 2016 -0600

----------------------------------------------------------------------
 spot-oa/ui/flow/js/components/IngestSummaryPanel.react.js | 4 ++--
 spot-oa/ui/flow/js/stores/IngestSummaryStore.js           | 3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/831ff7cf/spot-oa/ui/flow/js/components/IngestSummaryPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/components/IngestSummaryPanel.react.js b/spot-oa/ui/flow/js/components/IngestSummaryPanel.react.js
index c9fb97f..77af5dd 100755
--- a/spot-oa/ui/flow/js/components/IngestSummaryPanel.react.js
+++ b/spot-oa/ui/flow/js/components/IngestSummaryPanel.react.js
@@ -221,14 +221,14 @@ var IngestSummaryPanel = React.createClass({
   },
   componentDidUpdate: function ()
   {
-    if (!this.state.loading && !this.state.error)
+    if (!this.state.loading && !this.state.error && this.state.data)
     {
       this.buildGraph();
     }
   },
   buildGraph: initialDraw,
   _onChange: function () {
-    this.setState(IngestSummaryStore.getData());
+    this.replaceState(IngestSummaryStore.getData());
   }
 });
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/831ff7cf/spot-oa/ui/flow/js/stores/IngestSummaryStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/stores/IngestSummaryStore.js b/spot-oa/ui/flow/js/stores/IngestSummaryStore.js
index 532c4b1..9e4ccb5 100755
--- a/spot-oa/ui/flow/js/stores/IngestSummaryStore.js
+++ b/spot-oa/ui/flow/js/stores/IngestSummaryStore.js
@@ -90,7 +90,7 @@ var IngestSummaryStore = assign(new RestStore(NetflowConstants.API_INGEST_SUMMAR
         if (data.error) {
             requestErrors.push(data);
         }
-        else {
+        else if (data.data) {
             parse = d3.time.format("%Y-%m-%d %H:%M").parse; // Date formatting parser
             startDate = DateUtils.parseDate(this.getRestFilter(START_DATE_FILTER));
             endDate = DateUtils.parseDate(this.getRestFilter(END_DATE_FILTER));
@@ -121,6 +121,7 @@ var IngestSummaryStore = assign(new RestStore(NetflowConstants.API_INGEST_SUMMAR
                 return a.date - b.date;
             });
 
+            if (!this._data.data) this._data.data = [];
             this._data.data.push(data.data);
         }
 


[22/50] [abbrv] incubator-spot git commit: Merge pull request #145 from Open-Network-Insight/dns_multiprocessing_resources_lack

Posted by ev...@apache.org.
Merge pull request #145 from Open-Network-Insight/dns_multiprocessing_resources_lack

adding join to avoid overflow of processes, 

Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/084f9885
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/084f9885
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/084f9885

Branch: refs/heads/master
Commit: 084f9885598a34de21a41ef8ef393de903ddc3b8
Parents: 9763e2a 90a0a31
Author: Nathanael Smith <na...@gmail.com>
Authored: Tue Nov 29 08:51:55 2016 -0800
Committer: GitHub <no...@github.com>
Committed: Tue Nov 29 08:51:55 2016 -0800

----------------------------------------------------------------------
 spot-ingest/pipelines/dns/worker.py | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------



[42/50] [abbrv] incubator-spot git commit: sparklda_install

Posted by ev...@apache.org.
sparklda_install

removed MPI mentions from installation script and installation documentation


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

Branch: refs/heads/master
Commit: be742b1f789c1a46288ae5b85a052021e197bbaf
Parents: 39a376c
Author: nlsegerl <na...@intel.com>
Authored: Mon Dec 5 15:36:33 2016 -0800
Committer: nlsegerl <na...@intel.com>
Committed: Mon Dec 5 15:36:33 2016 -0800

----------------------------------------------------------------------
 spot-ml/INSTALL.md    | 5 -----
 spot-ml/install_ml.sh | 2 +-
 2 files changed, 1 insertion(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/be742b1f/spot-ml/INSTALL.md
----------------------------------------------------------------------
diff --git a/spot-ml/INSTALL.md b/spot-ml/INSTALL.md
index 810dedc..505f35a 100644
--- a/spot-ml/INSTALL.md
+++ b/spot-ml/INSTALL.md
@@ -12,13 +12,8 @@ The spot-ml routines must be built into a jar stored at `target/scala-2.10/spot-
 Names and language that we will use from the configuration variables for Spot (that are set in the file [spot.conf])
 
 - MLNODE The node from which the spot-ml routines are invoked
-- NODES The list of MPI worker nodes that execute the topic modelling analysis
 - HUSER An HDFS user path that will be the base path for the solution; this is usually the same user that you created to run the solution
-- LPATH The local path for the ML intermediate and final results, dynamically created and populated when the pipeline runs
 - HPATH Location for storing intermediate results of the analysis on HDFS.
-- MPI_CMD : command for executing MPI on your system, eg. `mpiexec` or `mpiexec.hydra` This will vary with your MPI installation!
-- MPI_PREP_CMD : a command that must be run before executing MPI on your system, such as sourcing a file of environment variables or exporting a path. May be empty. Will vary with your MPI installation.
-- PROCESS_COUNT : Number of processes executing in MPI.
 
 ### Prepare data for input 
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/be742b1f/spot-ml/install_ml.sh
----------------------------------------------------------------------
diff --git a/spot-ml/install_ml.sh b/spot-ml/install_ml.sh
index ef92345..2f66816 100755
--- a/spot-ml/install_ml.sh
+++ b/spot-ml/install_ml.sh
@@ -6,7 +6,7 @@ source /etc/spot.conf
 for d in "${NODES[@]}" 
 do
     rsync -v -a --include='target' --include='target/scala-2.10' --include='target/scala-2.10/spot-ml-assembly-1.1.jar' \
-       --include='spot-lda-c' --include='spot-lda-c/*'  --include 'top-1m.csv' --include='*.sh' \
+      --include 'top-1m.csv' --include='*.sh' \
       --exclude='*' .  $d:${LUSER}/ml
 done
 


[24/50] [abbrv] incubator-spot git commit: Update flow_oa.py

Posted by ev...@apache.org.
Update flow_oa.py

Renamed header for srcIP and dstIP reputation columns to match the names on the UI

Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/5d82f14a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/5d82f14a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/5d82f14a

Branch: refs/heads/master
Commit: 5d82f14aa5b8061bdfe2b395d7e96181eff664d5
Parents: fb8e0b6
Author: LedaLima <ga...@intel.com>
Authored: Tue Nov 29 13:06:47 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Tue Nov 29 13:06:47 2016 -0600

----------------------------------------------------------------------
 spot-oa/oa/flow/flow_oa.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/5d82f14a/spot-oa/oa/flow/flow_oa.py
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/flow_oa.py b/spot-oa/oa/flow/flow_oa.py
index 1fbd503..401a369 100644
--- a/spot-oa/oa/flow/flow_oa.py
+++ b/spot-oa/oa/flow/flow_oa.py
@@ -232,7 +232,7 @@ class OA(object):
         # add new headers (gtiSrcRep/gtiDstRep).
         self._logger.info("Adding reputation headers")
         flow_headers_rep = self._flow_scores[0]
-        flow_headers_rep.extend(["srcIp_rep","dstIp_rep"])
+        flow_headers_rep.extend(["srcIP_rep","dstIP_rep"])
         
         # read configuration.
         self._logger.info("Reading reputation configuration file: {0}".format(reputation_conf_file))


[38/50] [abbrv] incubator-spot git commit: Adding unit test cases to UI (#160)

Posted by ev...@apache.org.
Adding unit test cases to UI (#160)

* Fixed: Remove Panel Restore handler bug

* Unit Test for js/components/SpotStore.js

* Unit Test for js/stores/RestStore.js

* JsonStore unit test. Improved RestStore, JsonStore is now extending RestStore. fixinf minor bugs to support Store improvements

* CategoryLayout unit test and improvements

* DateUtils unit test

* SpotUtils unit test

* Unit Test for EdInActions.js

* Unit Test for js/actions/SpotActions

* Unit Test for js/actions/StoryboardActions

* Removed useless methods from js/dispatchers/SpotDispatcher


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

Branch: refs/heads/master
Commit: 282776870d7122c23e8ca790ee1ebf5699c79bad
Parents: bcd39a9
Author: daortizh <di...@intel.com>
Authored: Mon Dec 5 12:11:28 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Mon Dec 5 12:11:28 2016 -0600

----------------------------------------------------------------------
 .../flow/js/components/TimelinePanel.react.js   |   2 +-
 .../ui/js/actions/__tests__/EdInActions.test.js | 102 +++++++
 .../ui/js/actions/__tests__/SpotActions.test.js |  87 ++++++
 .../actions/__tests__/StoryboardActions.test.js |  26 ++
 spot-oa/ui/js/dispatchers/SpotDispatcher.js     |  15 --
 spot-oa/ui/js/stores/JsonStore.js               | 109 +++-----
 spot-oa/ui/js/stores/RestStore.js               |  13 +-
 spot-oa/ui/js/stores/SpotStore.js               |   2 +-
 .../ui/js/stores/__tests__/JsonStore.test.js    | 120 +++++++++
 .../ui/js/stores/__tests__/RestStore.test.js    | 269 +++++++++++++++++++
 .../ui/js/stores/__tests__/SpotStore.test.js    |  75 ++++++
 spot-oa/ui/js/utils/CategoryLayout.js           |   7 +-
 .../js/utils/__tests__/CategoryLayout.test.js   |  94 +++++++
 spot-oa/ui/js/utils/__tests__/DateUtils.test.js |  72 +++++
 spot-oa/ui/js/utils/__tests__/SpotUtils.test.js | 107 ++++++++
 .../proxy/js/components/TimelinePanel.react.js  |  13 +-
 16 files changed, 1001 insertions(+), 112 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/28277687/spot-oa/ui/flow/js/components/TimelinePanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/components/TimelinePanel.react.js b/spot-oa/ui/flow/js/components/TimelinePanel.react.js
index 6762b78..2beab68 100755
--- a/spot-oa/ui/flow/js/components/TimelinePanel.react.js
+++ b/spot-oa/ui/flow/js/components/TimelinePanel.react.js
@@ -22,7 +22,7 @@ const TimelineChart = React.createClass({
         if (storeData.error) {
             state.error = storeData.error;
         }
-        else if (!storeData.loading && storeData.data.length) {
+        else if (!storeData.loading && storeData.data) {
             state = this._getStateFromStoreData(storeData.data);
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/28277687/spot-oa/ui/js/actions/__tests__/EdInActions.test.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/actions/__tests__/EdInActions.test.js b/spot-oa/ui/js/actions/__tests__/EdInActions.test.js
new file mode 100644
index 0000000..68775c8
--- /dev/null
+++ b/spot-oa/ui/js/actions/__tests__/EdInActions.test.js
@@ -0,0 +1,102 @@
+jest.mock('../../dispatchers/SpotDispatcher');
+jest.mock('../SpotActions');
+jest.mock('../../utils/SpotUtils');
+
+const SpotDispatcher = require('../../dispatchers/SpotDispatcher');
+const SpotActions = require('../SpotActions');
+const SpotConstants = require('../../constants/SpotConstants');
+const SpotUtils = require('../../utils/SpotUtils');
+
+const EdInActions = require('../EdInActions');
+
+test('setFilter', () => {
+    SpotDispatcher.dispatch.mockClear();
+
+    EdInActions.setFilter('foo');
+
+    expect(SpotUtils.setUrlParam).toHaveBeenCalled();
+    expect(SpotUtils.setUrlParam.mock.calls[0][0]).toBe('filter');
+    expect(SpotUtils.setUrlParam.mock.calls[0][1]).toBe('foo');
+
+    expect(SpotDispatcher.dispatch).toHaveBeenCalled();
+    expect(SpotDispatcher.dispatch.mock.calls[0][0]).toBeInstanceOf(Object);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].actionType).toBe(SpotConstants.UPDATE_FILTER);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].filter).toBe('foo');
+});
+
+test('reloadSuspicious', () => {
+    SpotDispatcher.dispatch.mockClear();
+
+    EdInActions.reloadSuspicious();
+
+    expect(SpotActions.toggleMode).toHaveBeenCalled();
+    expect(SpotActions.toggleMode.mock.calls[0][0]).toBe(SpotConstants.DETAILS_PANEL);
+    expect(SpotActions.toggleMode.mock.calls[0][1]).toBe(SpotConstants.DETAILS_MODE);
+
+    expect(SpotDispatcher.dispatch).toHaveBeenCalled();
+    expect(SpotDispatcher.dispatch.mock.calls[0][0]).toBeInstanceOf(Object);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].actionType).toBe(SpotConstants.RELOAD_SUSPICIOUS);
+});
+
+test('reloadDetails', () => {
+    SpotDispatcher.dispatch.mockClear();
+
+    EdInActions.reloadDetails();
+
+    expect(SpotDispatcher.dispatch).toHaveBeenCalled();
+    expect(SpotDispatcher.dispatch.mock.calls[0][0]).toBeInstanceOf(Object);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].actionType).toBe(SpotConstants.RELOAD_DETAILS);
+});
+
+test('reloadVisualDetails', () => {
+    SpotDispatcher.dispatch.mockClear();
+
+    EdInActions.reloadVisualDetails();
+
+    expect(SpotDispatcher.dispatch).toHaveBeenCalled();
+    expect(SpotDispatcher.dispatch.mock.calls[0][0]).toBeInstanceOf(Object);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].actionType).toBe(SpotConstants.RELOAD_DETAILS_VISUAL);
+});
+
+test('highlightThreat',() => {
+    SpotDispatcher.dispatch.mockClear();
+
+    EdInActions.highlightThreat('anId');
+
+    expect(SpotDispatcher.dispatch).toHaveBeenCalled();
+    expect(SpotDispatcher.dispatch.mock.calls[0][0]).toBeInstanceOf(Object);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].actionType).toBe(SpotConstants.HIGHLIGHT_THREAT);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].threat).toBe('anId');
+});
+
+test('unhighlightThreat', () => {
+    SpotDispatcher.dispatch.mockClear();
+
+    EdInActions.unhighlightThreat();
+
+    expect(SpotDispatcher.dispatch).toHaveBeenCalled();
+    expect(SpotDispatcher.dispatch.mock.calls[0][0]).toBeInstanceOf(Object);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].actionType).toBe(SpotConstants.UNHIGHLIGHT_THREAT);
+});
+
+test('selectThreat', () => {
+    SpotDispatcher.dispatch.mockClear();
+
+    EdInActions.selectThreat('anId');
+
+    expect(SpotDispatcher.dispatch).toHaveBeenCalled();
+    expect(SpotDispatcher.dispatch.mock.calls[0][0]).toBeInstanceOf(Object);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].actionType).toBe(SpotConstants.SELECT_THREAT);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].threat).toBe('anId');
+});
+
+test('selectIp', () => {
+    SpotDispatcher.dispatch.mockClear();
+
+    EdInActions.selectIp('anIp');
+
+    expect(SpotDispatcher.dispatch).toHaveBeenCalled();
+    expect(SpotDispatcher.dispatch.mock.calls[0][0]).toBeInstanceOf(Object);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].actionType).toBe(SpotConstants.SELECT_IP);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].ip).toBe('anIp');
+});

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/28277687/spot-oa/ui/js/actions/__tests__/SpotActions.test.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/actions/__tests__/SpotActions.test.js b/spot-oa/ui/js/actions/__tests__/SpotActions.test.js
new file mode 100644
index 0000000..296261c
--- /dev/null
+++ b/spot-oa/ui/js/actions/__tests__/SpotActions.test.js
@@ -0,0 +1,87 @@
+jest.mock('../../dispatchers/SpotDispatcher');
+jest.mock('../../utils/SpotUtils');
+
+const $ = require('jquery');
+const SpotActions = require('../SpotActions');
+const SpotConstants = require('../../constants/SpotConstants');
+const SpotDispatcher = require('../../dispatchers/SpotDispatcher');
+const SpotUtils = require('../../utils/SpotUtils');
+
+test('setDate (default)', () => {
+    SpotDispatcher.dispatch.mockClear();
+
+    const link = $('<a />').attr('data-href', '/foo/bar#date=${date}').appendTo($('body'));
+
+    SpotActions.setDate('1985-01-12');
+
+    expect(SpotUtils.setUrlParam).toHaveBeenCalled();
+    expect(SpotUtils.setUrlParam.mock.calls[0][0]).toBe('date');
+    expect(SpotUtils.setUrlParam.mock.calls[0][1]).toBe('1985-01-12');
+
+    expect(SpotDispatcher.dispatch).toHaveBeenCalledTimes(2);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0]).toBeInstanceOf(Object);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].actionType).toBe(SpotConstants.UPDATE_FILTER);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].filter).toBe('');
+
+    expect(SpotDispatcher.dispatch.mock.calls[1][0]).toBeInstanceOf(Object);
+    expect(SpotDispatcher.dispatch.mock.calls[1][0].actionType).toBe(SpotConstants.UPDATE_DATE);
+    expect(SpotDispatcher.dispatch.mock.calls[1][0].date).toBe('1985-01-12');
+    expect(SpotDispatcher.dispatch.mock.calls[1][0].name).toBe('date');
+
+    expect(link.attr('href')).toBe('/foo/bar#date=1985-01-12');
+});
+
+test('setDate (custom name)', () => {
+    SpotDispatcher.dispatch.mockClear();
+    SpotUtils.setUrlParam.mockClear();
+
+    const link = $('<a />').attr('data-href', '/foo/bar#start_date=${start_date}').appendTo($('body'));
+
+    SpotActions.setDate('1985-01-12', 'start_date');
+
+    expect(SpotUtils.setUrlParam).toHaveBeenCalled();
+    expect(SpotUtils.setUrlParam.mock.calls[0][0]).toBe('start_date');
+    expect(SpotUtils.setUrlParam.mock.calls[0][1]).toBe('1985-01-12');
+
+    expect(SpotDispatcher.dispatch).toHaveBeenCalledTimes(2);
+    expect(SpotDispatcher.dispatch.mock.calls[1][0]).toBeInstanceOf(Object);
+    expect(SpotDispatcher.dispatch.mock.calls[1][0].actionType).toBe(SpotConstants.UPDATE_DATE);
+    expect(SpotDispatcher.dispatch.mock.calls[1][0].date).toBe('1985-01-12');
+    expect(SpotDispatcher.dispatch.mock.calls[1][0].name).toBe('start_date');
+
+    expect(link.attr('href')).toBe('/foo/bar#start_date=1985-01-12');
+});
+
+test('expandPanel', () => {
+    SpotDispatcher.dispatch.mockClear();
+
+    SpotActions.expandPanel('aPanel');
+
+    expect(SpotDispatcher.dispatch).toHaveBeenCalled();
+    expect(SpotDispatcher.dispatch.mock.calls[0][0]).toBeInstanceOf(Object);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].actionType).toBe(SpotConstants.EXPAND_PANEL);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].panel).toBe('aPanel');
+});
+
+test('restorePanel', () => {
+    SpotDispatcher.dispatch.mockClear();
+
+    SpotActions.restorePanel('aPanel');
+
+    expect(SpotDispatcher.dispatch).toHaveBeenCalled();
+    expect(SpotDispatcher.dispatch.mock.calls[0][0]).toBeInstanceOf(Object);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].actionType).toBe(SpotConstants.RESTORE_PANEL);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].panel).toBe('aPanel');
+});
+
+test('toggleMode', () => {
+    SpotDispatcher.dispatch.mockClear();
+
+    SpotActions.toggleMode('aPanel', 'aMode');
+
+    expect(SpotDispatcher.dispatch).toHaveBeenCalled();
+    expect(SpotDispatcher.dispatch.mock.calls[0][0]).toBeInstanceOf(Object);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].actionType).toBe(SpotConstants.TOGGLE_MODE_PANEL);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].panel).toBe('aPanel');
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].mode).toBe('aMode');
+});

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/28277687/spot-oa/ui/js/actions/__tests__/StoryboardActions.test.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/actions/__tests__/StoryboardActions.test.js b/spot-oa/ui/js/actions/__tests__/StoryboardActions.test.js
new file mode 100644
index 0000000..7162e96
--- /dev/null
+++ b/spot-oa/ui/js/actions/__tests__/StoryboardActions.test.js
@@ -0,0 +1,26 @@
+jest.mock('../../dispatchers/SpotDispatcher');
+
+const SpotConstants = require('../../constants/SpotConstants');
+const SpotDispatcher = require('../../dispatchers/SpotDispatcher');
+const StoryboardActions = require('../StoryboardActions');
+
+test('reloadComments', () => {
+    SpotDispatcher.dispatch.mockClear();
+
+    StoryboardActions.reloadComments();
+
+    expect(SpotDispatcher.dispatch).toHaveBeenCalled();
+    expect(SpotDispatcher.dispatch.mock.calls[0][0]).toBeInstanceOf(Object);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].actionType).toBe(SpotConstants.RELOAD_COMMENTS);
+});
+
+test('selectComment', () => {
+    SpotDispatcher.dispatch.mockClear();
+
+    StoryboardActions.selectComment('aComment');
+
+    expect(SpotDispatcher.dispatch).toHaveBeenCalled();
+    expect(SpotDispatcher.dispatch.mock.calls[0][0]).toBeInstanceOf(Object);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].actionType).toBe(SpotConstants.SELECT_COMMENT);
+    expect(SpotDispatcher.dispatch.mock.calls[0][0].comment).toBe('aComment');
+});

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/28277687/spot-oa/ui/js/dispatchers/SpotDispatcher.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/dispatchers/SpotDispatcher.js b/spot-oa/ui/js/dispatchers/SpotDispatcher.js
index 5e69467..20d5d20 100755
--- a/spot-oa/ui/js/dispatchers/SpotDispatcher.js
+++ b/spot-oa/ui/js/dispatchers/SpotDispatcher.js
@@ -3,19 +3,4 @@ var Dispatcher = require('flux').Dispatcher;
 // Create dispatcher instance$
 var SpotDispatcher = new Dispatcher();
 
-// Convenience method to handle dispatch requests$
-SpotDispatcher.handleServerAction = function(action) {
-  this.dispatch({
-    source: 'SERVER_ACTION',
-    action: action
-  });
-}
-
-SpotDispatcher.handleAction = function(action) {
-  this.dispatch({
-    source: 'VIEW_ACTION',
-    action: action
-  });
-}
-
 module.exports = SpotDispatcher;

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/28277687/spot-oa/ui/js/stores/JsonStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/JsonStore.js b/spot-oa/ui/js/stores/JsonStore.js
index 7c79e4d..3a3aefc 100755
--- a/spot-oa/ui/js/stores/JsonStore.js
+++ b/spot-oa/ui/js/stores/JsonStore.js
@@ -1,87 +1,44 @@
-var EventEmitter = require('events').EventEmitter;
-var assign = require('object-assign');
+const $ = require('jquery');
 
-var CHANGE_DATA_EVENT = 'change_data';
+const RestStore = require('./RestStore');
 
-var JsonStore = function (endpoint) {
-    this.setEndpoint(endpoint);
-    this._filters = {};
-    this._data = {loading: false};
+const JsonStore = function () {
+    RestStore.apply(this, arguments);
 };
 
-assign(JsonStore.prototype, EventEmitter.prototype, {
-    defaultErrorMessage: 'Oops, something went wrong!!',
-    errorMessages: {},
-    setRestFilter: function (name, value)
-    {
-    this._filters[name] = value;
-    },
-    getRestFilter: function (name)
-    {
-        return this._filters[name];
-    },
-    removeRestFilter: function (name)
-    {
-        delete this._filters[name];
-    },
-        setEndpoint: function (endpoint) {
-            this.endpoint = endpoint;
-    },
-    resetData: function ()
-    {
-        this._data = {loading: false};
+JsonStore.prototype = new RestStore();
 
-        this.emitChangeData();
-    },
-    setData: function (data)
-    {
-        this._data = data;
-        this.emitChangeData();
-    },
-    getData: function ()
-    {
-        return this._data;
-    },
-    emitChangeData: function ()
-    {
-        this.emit(CHANGE_DATA_EVENT);
-    },
-    addChangeDataListener: function (callback) {
-        this.on(CHANGE_DATA_EVENT, callback);
-    },
-    removeChangeDataListener: function (callback) {
-        this.removeListener(CHANGE_DATA_EVENT, callback);
-    },
-    reload: function ()
-    {
-        var url, name;
-        this.setData({loading: true});
+JsonStore.prototype.reload = function ()
+{
+    var url, name;
+    this.setData({loading: true});
 
-        url = this.endpoint;
+    url = this.endpoint;
 
-        for (name in this._filters)
+    for (name in this._filters)
+    {
+        url = url.replace('${'+name+'}', this._filters[name]);
+    }
+    url = url.replace(/:/g, '_');
+
+    $.ajax(url, {
+        method: 'GET',
+        context: this,
+        contentType: 'application/json',
+        success: function (response) {
+            this.setData({
+              loading: false,
+              data: response
+            });
+        },
+        error: function (response)
         {
-            url = url.replace('${'+name+'}', this._filters[name]);
+            this.setData({
+                loading:false,
+                error: this.errorMessages[response.status] || this.defaultErrorMessage
+            });
         }
-        url = url.replace(/:/g, '_');
-
-        $.ajax(url, {
-            method: 'GET',
-            context: this,
-            contentType: 'application/json',
-            success: function (response) {
-
-                this.setData({
-                  loading: false,
-                  data: response
-                });
-            },
-            error: function (response)
-            {
-                this.setData({error: this.errorMessages[response.status] || this.defaultErrorMessage});
-            }
-        });
-    }
-});
+    });
+};
 
 module.exports = JsonStore;

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/28277687/spot-oa/ui/js/stores/RestStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/RestStore.js b/spot-oa/ui/js/stores/RestStore.js
index 6d5fd70..5aee412 100755
--- a/spot-oa/ui/js/stores/RestStore.js
+++ b/spot-oa/ui/js/stores/RestStore.js
@@ -9,9 +9,7 @@ var RestStore = function (endpoint, data) {
     this.setEndpoint(endpoint);
     this._filters = {};
     this._data = assign({
-            loading: false,
-            headers: [],
-            data: []
+            loading: false
         }, data
     );
 
@@ -35,7 +33,7 @@ assign(RestStore.prototype, EventEmitter.prototype, {
         this.endpoint = endpoint;
     },
     resetData: function () {
-        this._data = {loading: false, headers: [], data: [], error: undefined};
+        this._data = {loading: false};
 
         this.emitChangeData();
     },
@@ -59,7 +57,7 @@ assign(RestStore.prototype, EventEmitter.prototype, {
     reload: function () {
         var url, name;
 
-        this.setData({loading: true, headers: [], data: [], error: undefined});
+        this.setData({loading: true});
 
         url = this.endpoint;
 
@@ -102,15 +100,12 @@ assign(RestStore.prototype, EventEmitter.prototype, {
                 this.setData({
                     loading: false,
                     headers: headers,
-                    data: csv,
-                    error: undefined
+                    data: csv
                 });
             },
             error: function (response) {
                 this.setData({
                     loading: false,
-                    headers: [],
-                    data: [],
                     error: this.errorMessages[response.status] || this.defaultErrorMessage
                 });
             }

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/28277687/spot-oa/ui/js/stores/SpotStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/SpotStore.js b/spot-oa/ui/js/stores/SpotStore.js
index 3ea9a2d..6ff4d21 100755
--- a/spot-oa/ui/js/stores/SpotStore.js
+++ b/spot-oa/ui/js/stores/SpotStore.js
@@ -49,7 +49,7 @@ var SpotStore = assign({}, EventEmitter.prototype, {
   },
   removePanelRestoreListener: function (callback)
   {
-    this.removeListener(PANEL_EXPAND_EVENT, callback);
+    this.removeListener(PANEL_RESTORE_EVENT, callback);
   },
   emitPanelRestore: function (panel)
   {

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/28277687/spot-oa/ui/js/stores/__tests__/JsonStore.test.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/__tests__/JsonStore.test.js b/spot-oa/ui/js/stores/__tests__/JsonStore.test.js
new file mode 100644
index 0000000..7041c96
--- /dev/null
+++ b/spot-oa/ui/js/stores/__tests__/JsonStore.test.js
@@ -0,0 +1,120 @@
+jest.mock('jquery');
+const $ = require('jquery');
+
+const Store = require('../JsonStore');
+
+test('Reload data (Success)', () => {
+    const instance = new Store('/${date}/my-endpoint-${id}-${time}');
+
+    const handler = jest.fn();
+
+    instance.addChangeDataListener(handler);
+
+    const okResponse = JSON.stringify({
+        headers: {
+            header1:"header1",
+            header2:"header2",
+            header3:"header3"
+        },
+        data:[
+            {
+                header1:"data1-1",
+                header2:"data1-2",
+                header3:"data1-3"
+            },
+            {
+                header1:"data2-1",
+                header2:"data2-2",
+                header3:"data2-3"
+            }
+        ]
+    });
+    $.ajax = jest.fn((url, options) => {
+        options.success.call(options.context, okResponse);
+    });
+
+    instance.setRestFilter('date', '20161004');
+    instance.setRestFilter('id', 'UUID');
+    instance.setRestFilter('time', '22:00');
+    instance.reload();
+
+    expect($.ajax).toHaveBeenCalled();
+    expect(handler).toHaveBeenCalledTimes(2);
+
+    // Make sure server request is being made correctly
+    expect($.ajax.mock.calls[0][0]).toBe('/20161004/my-endpoint-UUID-22_00');
+    const reqParams = $.ajax.mock.calls[0][1];
+    expect(reqParams.method).toBe('GET');
+    expect(reqParams.context).toBe(instance);
+    expect(reqParams.contentType).toBe('application/json');
+
+    // Testing server response
+    const dataFromServer = instance.getData();
+
+    expect(dataFromServer).toBeInstanceOf(Object);
+    expect(Object.keys(dataFromServer).length).toBe(2);
+    expect(dataFromServer.loading).toBe(false);
+    expect(dataFromServer.data).toBe(okResponse);
+});
+
+test('Reload data (Error)', () => {
+    const instance = new Store('/${date}/my-endpoint-${id}-${time}');
+
+    const handler = jest.fn();
+
+    instance.addChangeDataListener(handler);
+
+    const error = {status: 500};
+    $.ajax = jest.fn((url, options) => {
+        options.error.call(options.context, error);
+    });
+
+    instance.reload();
+
+    expect(handler).toHaveBeenCalledTimes(2);
+
+    // Testing server error
+    const errorFromServer = instance.getData();
+
+    expect(errorFromServer).toBeInstanceOf(Object);
+    expect(Object.keys(errorFromServer).length).toBe(2);
+    expect(errorFromServer.loading).toBe(false);
+    expect(errorFromServer.headers).toBeUndefined();
+    expect(errorFromServer.data).toBeUndefined();
+    expect(errorFromServer.error).toBe(instance.defaultErrorMessage);
+});
+
+test('Reload data (Custom Error)', () => {
+    const instance = new Store('/${date}/my-endpoint-${id}-${time}');
+
+    const customError = 'No data has been found';
+    instance.errorMessages['404'] = customError;
+
+    const error = {status: 404};
+    $.ajax = jest.fn((url, options) => {
+        options.error.call(options.context, error);
+    });
+
+    instance.reload();
+
+    // Testing server error
+    const errorFromServer = instance.getData();
+
+    expect(errorFromServer.error).toBe(customError);
+});
+
+test('Reload data (Loading notification)', () => {
+    const instance = new Store('/${date}/my-endpoint-${id}-${time}');
+
+    instance.setData = jest.fn();
+
+    const okResponse = 'header1,header2,header3\ndata1-1,data1-2,data1-3\ndata2-1,data2-2,data2-3';
+    $.ajax = jest.fn((url, options) => {
+        options.success.call(options.context, okResponse);
+    });
+
+    instance.reload();
+
+    expect(instance.setData).toHaveBeenCalledTimes(2);
+    expect(instance.setData.mock.calls[0][0].loading).toBe(true);
+});

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/28277687/spot-oa/ui/js/stores/__tests__/RestStore.test.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/__tests__/RestStore.test.js b/spot-oa/ui/js/stores/__tests__/RestStore.test.js
new file mode 100644
index 0000000..4d2558e
--- /dev/null
+++ b/spot-oa/ui/js/stores/__tests__/RestStore.test.js
@@ -0,0 +1,269 @@
+jest.mock('jquery');
+const $ = require('jquery');
+
+const Store = require('../RestStore');
+
+test('Create instance. Empty data', () => {
+    const instance = new Store('/my-endpoint');
+
+    expect(instance.endpoint).toBe('/my-endpoint');
+
+    const storeState = instance.getData();
+    expect(storeState).toBeInstanceOf(Object);
+    expect(storeState.loading).toBe(false);
+    expect(storeState.headers).toBeUndefined();
+    expect(storeState.data).toBeUndefined();
+    expect(instance.defaultErrorMessage).toBe('Oops, something went wrong!!');
+    expect(instance.errorMessages).toBeInstanceOf(Object);
+    expect(Object.keys(instance.errorMessages).length).toBe(0);
+    expect(instance.headers).toBeInstanceOf(Object);
+    expect(Object.keys(instance.headers).length).toBe(0);
+});
+
+test('Create instance. Default to loading', () => {
+    const instance = new Store('/my-endpoint', {
+        loading: true
+    });
+
+    expect(instance.endpoint).toBe('/my-endpoint');
+
+    const storeState = instance.getData();
+    expect(storeState).toBeInstanceOf(Object);
+    expect(storeState.loading).toBe(true);
+    expect(storeState.headers).toBeUndefined();
+    expect(storeState.data).toBeUndefined();
+});
+
+test('Create instance. Default to known data', () => {
+    const instance = new Store('/my-endpoint', {
+        headers: ['First', 'Second', 'Third'],
+        data: [1 ,2, 3]
+    });
+
+    expect(instance.endpoint).toBe('/my-endpoint');
+
+    const storeState = instance.getData();
+    expect(storeState).toBeInstanceOf(Object);
+    expect(storeState.loading).toBe(false);
+    expect(storeState.headers).toBeInstanceOf(Object);
+    expect(Object.keys(storeState.headers).length).toBe(3);
+    expect(storeState.data).toBeInstanceOf(Array);
+    expect(storeState.data.length).toBe(3);
+});
+
+test('Filters', () => {
+    const instance = new Store('/my-endpoint');
+
+    instance.setRestFilter('foo', 'bar');
+
+    expect(instance.getRestFilter('foo')).toBe('bar');
+
+    instance.removeRestFilter('foo');
+
+    expect(instance.getRestFilter('foo')).toBeUndefined();
+});
+
+test('Endpoint', () => {
+    const instance = new Store('/my-endpoint');
+
+    instance.setEndpoint('/new-endpoint.json');
+
+    expect(instance.endpoint).toBe('/new-endpoint.json');
+});
+
+test('Data', () => {
+    const instance = new Store('/my-endpoint');
+
+    instance.setData({
+        loading: true,
+        headers: {
+            header1: 'Header 1',
+            header2: 'Header 2'
+        },
+        data: [
+            {header1: 'val1.1', header2: 'val1.2'},
+            {header1: 'val2.1', header2: 'val2.2'}
+        ]
+    });
+
+    let storeState = instance.getData();
+    expect(storeState.loading).toBe(true);
+    expect(Object.keys(storeState.headers).length).toBe(2);
+    expect(storeState.data.length).toBe(2);
+
+    instance.resetData();
+
+    storeState = instance.getData();
+    expect(storeState.loading).toBe(false);
+    expect(storeState.headers).toBeUndefined();
+    expect(storeState.data).toBeUndefined();
+});
+
+test('Data listeners', () => {
+    const instance = new Store('/my-endpoint');
+
+    const handler = jest.fn();
+
+    instance.addChangeDataListener(handler);
+
+    instance.resetData();
+    expect(handler).toHaveBeenCalledTimes(1);
+
+    instance.setData('Some data');
+    expect(handler).toHaveBeenCalledTimes(2);
+
+    instance.removeChangeDataListener(handler);
+
+    instance.setData('More data');
+    expect(handler).toHaveBeenCalledTimes(2);
+});
+
+test('Reload data (Success)', () => {
+    const instance = new Store('/${date}/my-endpoint-${id}-${time}');
+
+    const handler = jest.fn();
+
+    instance.addChangeDataListener(handler);
+
+    const okResponse = 'header1,header2,header3\ndata1-1,data1-2,data1-3\ndata2-1,data2-2,data2-3';
+    $.ajax = jest.fn((url, options) => {
+        options.success.call(options.context, okResponse);
+    });
+
+    instance.setRestFilter('date', '20161004');
+    instance.setRestFilter('id', 'UUID');
+    instance.setRestFilter('time', '22:00');
+    instance.reload();
+
+    expect($.ajax).toHaveBeenCalled();
+    expect(handler).toHaveBeenCalledTimes(2);
+
+    // Make sure server request is being made correctly
+    expect($.ajax.mock.calls[0][0]).toBe('/20161004/my-endpoint-UUID-22_00');
+    const reqParams = $.ajax.mock.calls[0][1];
+    expect(reqParams.method).toBe('GET');
+    expect(reqParams.context).toBe(instance);
+    expect(reqParams.contentType).toBe('application/csv');
+
+    // Testing server response
+    const dataFromServer = instance.getData();
+
+    expect(dataFromServer.loading).toBe(false);
+
+    expect(dataFromServer.headers).toBeInstanceOf(Object);
+    expect(Object.keys(dataFromServer.headers).length).toBe(3);
+    expect(dataFromServer.headers.header1).toBe('header1');
+    expect(dataFromServer.headers.header2).toBe('header2');
+    expect(dataFromServer.headers.header3).toBe('header3');
+
+    expect(dataFromServer.data).toBeInstanceOf(Array);
+    expect(dataFromServer.data.length).toBe(2);
+
+    expect(dataFromServer.data[0].header1).toBe('data1-1');
+    expect(dataFromServer.data[0].header2).toBe('data1-2');
+    expect(dataFromServer.data[0].header3).toBe('data1-3');
+
+    expect(dataFromServer.data[1].header1).toBe('data2-1');
+    expect(dataFromServer.data[1].header2).toBe('data2-2');
+    expect(dataFromServer.data[1].header3).toBe('data2-3');
+});
+
+test('Reload data (Error)', () => {
+    const instance = new Store('/${date}/my-endpoint-${id}-${time}');
+
+    const handler = jest.fn();
+
+    instance.addChangeDataListener(handler);
+
+    const error = {status: 500};
+    $.ajax = jest.fn((url, options) => {
+        options.error.call(options.context, error);
+    });
+
+    instance.reload();
+
+    expect(handler).toHaveBeenCalledTimes(2);
+
+    // Testing server error
+    const errorFromServer = instance.getData();
+
+    expect(errorFromServer.loading).toBe(false);
+    expect(errorFromServer.headers).toBeUndefined();
+    expect(errorFromServer.data).toBeUndefined();
+    expect(errorFromServer.error).toBe(instance.defaultErrorMessage);
+});
+
+test('Reload data (Custom Error)', () => {
+    const instance = new Store('/${date}/my-endpoint-${id}-${time}');
+
+    const customError = 'No data has been found';
+    instance.errorMessages['404'] = customError;
+
+    const error = {status: 404};
+    $.ajax = jest.fn((url, options) => {
+        options.error.call(options.context, error);
+    });
+
+    instance.reload();
+
+    // Testing server error
+    const errorFromServer = instance.getData();
+
+    expect(errorFromServer.error).toBe(customError);
+});
+
+test('Reload data (Loading notification)', () => {
+    const instance = new Store('/${date}/my-endpoint-${id}-${time}');
+
+    instance.setData = jest.fn();
+
+    const okResponse = 'header1,header2,header3\ndata1-1,data1-2,data1-3\ndata2-1,data2-2,data2-3';
+    $.ajax = jest.fn((url, options) => {
+        options.success.call(options.context, okResponse);
+    });
+
+    instance.reload();
+
+    expect(instance.setData).toHaveBeenCalledTimes(2);
+    expect(instance.setData.mock.calls[0][0].loading).toBe(true);
+});
+
+const d3 = require('d3');
+
+test('Custom parser', () => {
+    const instance = new Store('/custom-parser-endpoint');
+    instance._parser = d3.dsv('|', 'text/plain');
+
+    const handler = jest.fn();
+
+    const okResponse = 'header1|header2|header3\ndata1-1|data1-2|data1-3\ndata2-1|data2-2|data2-3';
+    $.ajax = jest.fn((url, options) => {
+        options.success.call(options.context, okResponse);
+    });
+
+    instance.reload();
+
+    expect($.ajax).toHaveBeenCalled();
+
+    // Testing server response
+    const dataFromServer = instance.getData();
+
+    expect(dataFromServer.loading).toBe(false);
+
+    expect(dataFromServer.headers).toBeInstanceOf(Object);
+    expect(Object.keys(dataFromServer.headers).length).toBe(3);
+    expect(dataFromServer.headers.header1).toBe('header1');
+    expect(dataFromServer.headers.header2).toBe('header2');
+    expect(dataFromServer.headers.header3).toBe('header3');
+
+    expect(dataFromServer.data).toBeInstanceOf(Array);
+    expect(dataFromServer.data.length).toBe(2);
+
+    expect(dataFromServer.data[0].header1).toBe('data1-1');
+    expect(dataFromServer.data[0].header2).toBe('data1-2');
+    expect(dataFromServer.data[0].header3).toBe('data1-3');
+
+    expect(dataFromServer.data[1].header1).toBe('data2-1');
+    expect(dataFromServer.data[1].header2).toBe('data2-2');
+    expect(dataFromServer.data[1].header3).toBe('data2-3');
+});

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/28277687/spot-oa/ui/js/stores/__tests__/SpotStore.test.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/__tests__/SpotStore.test.js b/spot-oa/ui/js/stores/__tests__/SpotStore.test.js
new file mode 100644
index 0000000..dec8b10
--- /dev/null
+++ b/spot-oa/ui/js/stores/__tests__/SpotStore.test.js
@@ -0,0 +1,75 @@
+const SpotStore = require('../SpotStore');
+
+test('Date handlers are working OK', () => {
+    const handler = jest.fn();
+
+    // MAke sure handlers are being called
+    SpotStore.addChangeDateListener(handler);
+
+    SpotStore.setDate('1985-01-12');
+    expect(SpotStore.getDate()).toBe('1985-01-12');
+    expect(handler).toHaveBeenCalledTimes(1);
+
+    // Make sure removed handlers are not being called anymore
+    SpotStore.removeChangeDateListener(handler);
+
+    SpotStore.setDate('1985-01-12');
+    expect(handler).toHaveBeenCalledTimes(1);
+});
+
+test('PanelExpand handlers are working OK', () => {
+    const handler = jest.fn();
+
+    // MAke sure handlers are being called
+    SpotStore.addPanelExpandListener(handler);
+
+    SpotStore.emitPanelExpand('Foo Panel');
+
+    expect(handler).toHaveBeenCalledTimes(1);
+    expect(handler).toHaveBeenCalledWith('Foo Panel');
+
+    // Make sure removed handlers are not being called anymore
+
+    SpotStore.removePanelExpandListener(handler);
+
+    SpotStore.emitPanelExpand('Foo Panel');
+    expect(handler).toHaveBeenCalledTimes(1);
+});
+
+test('PanelRestore handlers are working OK', () => {
+    const handler = jest.fn();
+
+    // MAke sure handlers are being called
+    SpotStore.addPanelRestoreListener(handler);
+
+    SpotStore.emitPanelRestore('Foo Panel');
+
+    expect(handler).toHaveBeenCalledTimes(1);
+    expect(handler).toHaveBeenCalledWith('Foo Panel');
+
+    // Make sure removed handlers are not being called anymore
+
+    SpotStore.removePanelRestoreListener(handler);
+
+    SpotStore.emitPanelRestore('Foo Panel');
+    expect(handler).toHaveBeenCalledTimes(1);
+});
+
+test('ToggleMode handlers are working OK', () => {
+    const handler = jest.fn();
+
+    // MAke sure handlers are being called
+    SpotStore.addPanelToggleModeListener(handler);
+
+    SpotStore.emitPanelToggleMode('Foo Panel', 'Unit Test Mode');
+
+    expect(handler).toHaveBeenCalledTimes(1);
+    expect(handler).toHaveBeenCalledWith('Foo Panel', 'Unit Test Mode');
+
+    // Make sure removed handlers are not being called anymore
+
+    SpotStore.removePanelToggleModeListener(handler);
+
+    SpotStore.emitPanelToggleMode('Foo Panel', 'Unit Test Mode');
+    expect(handler).toHaveBeenCalledTimes(1);
+});

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/28277687/spot-oa/ui/js/utils/CategoryLayout.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/utils/CategoryLayout.js b/spot-oa/ui/js/utils/CategoryLayout.js
index f913889..cdad575 100755
--- a/spot-oa/ui/js/utils/CategoryLayout.js
+++ b/spot-oa/ui/js/utils/CategoryLayout.js
@@ -37,8 +37,8 @@ class CategoryLayout {
     nodes(rawNodes) {
         let catKeys, categories = {};
 
-        if (this._categories || this._categoriesFn) {
-            catKeys = this._categories || this._categoriesFn();
+        if (this._categories) {
+            catKeys = this._categories;
         }
         else {
             catKeys = [];
@@ -100,8 +100,7 @@ class CategoryLayout {
 
     categories(categories) {
         if (categories) {
-            this._categories = categories instanceof Array ? categories : null;
-            this._categoriesFn = categories instanceof Function ? categories : null;
+            this._categories = categories instanceof Function ? categories() : categories instanceof Array ? categories : null;
 
             return this;
         }

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/28277687/spot-oa/ui/js/utils/__tests__/CategoryLayout.test.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/utils/__tests__/CategoryLayout.test.js b/spot-oa/ui/js/utils/__tests__/CategoryLayout.test.js
new file mode 100644
index 0000000..e6020ef
--- /dev/null
+++ b/spot-oa/ui/js/utils/__tests__/CategoryLayout.test.js
@@ -0,0 +1,94 @@
+const CategoryLayout = require('../CategoryLayout');
+
+test('Default layout properties', () => {
+    const instance = new CategoryLayout();
+
+    const size = instance.size();
+    expect(size[0]).toBe(1);
+    expect(size[1]).toBe(1);
+
+    const obj1 = {id: 'key1'}, obj2 = {id: 'key2'};
+    // Expect links to be always the same direction not matter how linked nodes are being provided
+    var link = instance.link()(obj1, obj2);
+    expect(link.source).toBe(obj2);
+    expect(link.target).toBe(obj1);
+    link = instance.link()(obj2, obj1);
+    expect(link.source).toBe(obj2);
+    expect(link.target).toBe(obj1);
+
+    const catAccessor = instance.category();
+    expect(catAccessor({category: 'foo'})).toBe('foo');
+
+    const categories = ['foo', 'bar'];
+    const categoryGenerator = () => ['bar', 'foo'];
+
+    instance.categories(categories);
+    expect(instance.categories()[0]).toBe('foo');
+    expect(instance.categories()[1]).toBe('bar');
+
+    instance.categories(categoryGenerator);
+    expect(instance.categories()[0]).toBe('bar');
+    expect(instance.categories()[1]).toBe('foo');
+
+    const idAccessor = (obj) => obj.id2;
+
+    const idObj = {id: 'id', id2: 'id2'};
+    expect(instance.id()(idObj)).toBe('id');
+
+    instance.id(idAccessor);
+    expect(instance.id()(idObj)).toBe('id2');
+});
+
+const node4 = {id: 'node4'};
+const node3 = {
+    id: 'node3',
+    category: 'Cat3',
+    links: [node4]
+};
+const node2_1 = {
+    id: 'node2.1',
+    category: 'Cat2',
+    links: [node3]
+};
+const node2_2 = {
+    id: 'node2.2',
+    category: 'Cat2',
+    links: [node3]
+};
+const node1 = {
+    id: 'node1',
+    category: 'Cat1',
+    links: [node2_1, node2_2]
+};
+const rawNodes = [node1, node2_1, node2_2, node3];
+
+test('Node initialization', () => {
+    const instance = new CategoryLayout();
+
+    const nodes = instance.nodes(rawNodes);
+
+    // Same for nodes have been returned
+    expect(nodes.length).toBe(4);
+
+    // Nodes have x and y properties
+    nodes.forEach(node => expect(node.x).toBeDefined());
+    nodes.forEach(node => expect(node.y).toBeDefined());
+
+    // Same category nodes share x value but have different y values
+    expect(nodes[1].x).toBe(nodes[2].x);
+    expect(nodes[1].y).not.toBe(nodes[2].y);
+
+    // Nodes are distributed along x axis
+    expect(nodes[0].x).not.toBe(nodes[1].x);
+    expect(nodes[1].x).not.toBe(nodes[3].x);
+    expect(nodes[3].x).not.toBe(nodes[0].x);
+});
+
+test('Links', () => {
+    const instance = new CategoryLayout();
+
+    const nodes = instance.nodes(rawNodes);
+    const links = instance.links(nodes);
+
+    expect(links.length).toBe(4);
+});

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/28277687/spot-oa/ui/js/utils/__tests__/DateUtils.test.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/utils/__tests__/DateUtils.test.js b/spot-oa/ui/js/utils/__tests__/DateUtils.test.js
new file mode 100644
index 0000000..276d17d
--- /dev/null
+++ b/spot-oa/ui/js/utils/__tests__/DateUtils.test.js
@@ -0,0 +1,72 @@
+const DateUtils = require('../DateUtils');
+
+function d2s(date) {
+    return date.toISOString().substr(0, 10);
+}
+
+test('Date calculation', () => {
+    const today = new Date();
+    let calculatedDate;
+
+    // Go to yesterday
+    const yesterday = new Date(
+        today.getFullYear(),
+        today.getMonth(),
+        today.getDate()-1,
+        today.getHours(),
+        today.getMinutes(),
+        today.getSeconds(),
+        today.getMilliseconds()
+    );
+    calculatedDate = DateUtils.calcDate(today, -1, 'day');
+    expect(d2s(calculatedDate)).toBe(d2s(yesterday));
+
+    // Go to last Month
+    const lastMonth = new Date(
+        today.getFullYear(),
+        today.getMonth()-1,
+        today.getDate(),
+        today.getHours(),
+        today.getMinutes(),
+        today.getSeconds(),
+        today.getMilliseconds()
+    );
+
+    calculatedDate = DateUtils.calcDate(today, -1, 'month');
+    expect(d2s(calculatedDate)).toBe(d2s(lastMonth));
+
+    // Go to last Year
+    const lastYear = new Date(
+        today.getFullYear()-1,
+        today.getMonth(),
+        today.getDate(),
+        today.getHours(),
+        today.getMinutes(),
+        today.getSeconds(),
+        today.getMilliseconds()
+    );
+
+    calculatedDate = DateUtils.calcDate(today, -1, 'year');
+    expect(d2s(calculatedDate)).toBe(d2s(lastYear));
+
+    // Going to the future is forbiden, we should get today
+    calculatedDate = DateUtils.calcDate(today, 1, 'day');
+    expect(d2s(calculatedDate)).toBe(d2s(today));
+    calculatedDate = DateUtils.calcDate(today, 1, 'month');
+    expect(d2s(calculatedDate)).toBe(d2s(today));
+    calculatedDate = DateUtils.calcDate(today, 1, 'year');
+    expect(d2s(calculatedDate)).toBe(d2s(today));
+});
+
+test('Date formatting', () => {
+    const today = new Date();
+
+    expect(DateUtils.formatDate(today)).toBe(d2s(today));
+});
+
+test('Date parsing', () => {
+    const today = d2s(new Date());
+
+    const parsedDate = DateUtils.parseDate(today);
+    expect(d2s(parsedDate)).toBe(today);
+});

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/28277687/spot-oa/ui/js/utils/__tests__/SpotUtils.test.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/utils/__tests__/SpotUtils.test.js b/spot-oa/ui/js/utils/__tests__/SpotUtils.test.js
new file mode 100644
index 0000000..74c96e5
--- /dev/null
+++ b/spot-oa/ui/js/utils/__tests__/SpotUtils.test.js
@@ -0,0 +1,107 @@
+const DateUtils = require('../DateUtils');
+const SpotUtils = require('../SpotUtils');
+
+test('Access to current date', () => {
+    const today = new Date();
+
+    expect(SpotUtils.getCurrentDate()).toBe(DateUtils.formatDate(today));
+    const someDate = '1985-01-12';
+    window.location.hash = 'date='+ someDate;
+    expect(SpotUtils.getCurrentDate()).toBe(DateUtils.formatDate(DateUtils.parseDate(someDate)));
+});
+
+test('Multiple dates', () => {
+    window.location.hash = 'start-date=1985-01-12|end-date=2016-11-29';
+
+    expect(SpotUtils.getCurrentDate('start-date')).toBe('1985-01-12');
+    expect(SpotUtils.getCurrentDate('end-date')).toBe('2016-11-29');
+});
+
+test('Date to String', () => {
+    const today = new Date();
+
+    expect(SpotUtils.getDateString(today)).toBe(DateUtils.formatDate(today));
+});
+
+test('Access to current filter', () => {
+    const someFilter = '127.0.0.1';
+    window.location.hash = 'date=1985-01-12|filter='+ someFilter;
+
+    expect(SpotUtils.getCurrentFilter()).toBe(someFilter);
+});
+
+test('URL params', () => {
+    window.location.hash = '';
+
+    const someDate = '1985-01-12';
+    const someFilter = '127.0.0.1';
+
+    SpotUtils.setUrlParam('date', someDate);
+    SpotUtils.setUrlParam('filter', someFilter);
+
+    expect(SpotUtils.getUrlParam('date')).toBe(someDate);
+    expect(SpotUtils.getUrlParam('filter')).toBe(someFilter);
+});
+
+test('Reputation data', () => {
+    //{'3': 'danger', '2': 'warning', '1': 'info', '0': 'default', '-1': 'default'}
+    let unknown = 'unknown:Unknown:-1:CatName1|GroupName1;CatName2|GroupName2';
+    let unverify = 'unverify:Unverified:0';
+    let minimal = 'minimal:Info:1';
+    let warning = 'warning:Medium:2';
+    let danger = 'danger:High:3';
+
+    const rawRep = unknown + '::' + unverify + '::' + minimal + '::' + warning + '::' + danger;
+
+    const rep = SpotUtils.parseReputation(rawRep);
+
+    expect(rep).toBeInstanceOf(Object);
+
+    expect(rep.unknown).toBeInstanceOf(Object);
+    expect(rep.unknown.text).toBe('Unknown');
+    expect(rep.unknown.value).toBe(-1);
+    expect(rep.unknown.cssClass).toBe('default');
+    expect(rep.unknown.categories).toBeInstanceOf(Array);
+    expect(rep.unknown.categories.length).toBe(2);
+    expect(rep.unknown.categories[0].name).toBe('CatName1');
+    expect(rep.unknown.categories[0].group).toBe('GroupName1');
+    expect(rep.unknown.categories[1].name).toBe('CatName2');
+    expect(rep.unknown.categories[1].group).toBe('GroupName2');
+
+    expect(rep.unverify).toBeInstanceOf(Object);
+    expect(rep.unverify.text).toBe('Unverified');
+    expect(rep.unverify.value).toBe(0);
+    expect(rep.unverify.cssClass).toBe('default');
+    expect(rep.unverify.categories).toBeNull();
+
+    expect(rep.minimal).toBeInstanceOf(Object);
+    expect(rep.minimal.text).toBe('Info');
+    expect(rep.minimal.value).toBe(1);
+    expect(rep.minimal.cssClass).toBe('info');
+    expect(rep.minimal.categories).toBeNull();
+
+    expect(rep.warning).toBeInstanceOf(Object);
+    expect(rep.warning.text).toBe('Medium');
+    expect(rep.warning.value).toBe(2);
+    expect(rep.warning.cssClass).toBe('warning');
+    expect(rep.warning.categories).toBeNull();
+
+    expect(rep.danger).toBeInstanceOf(Object);
+    expect(rep.danger.text).toBe('High');
+    expect(rep.danger.value).toBe(3);
+    expect(rep.danger.cssClass).toBe('danger');
+    expect(rep.danger.categories).toBeNull();
+
+    const highestRep = SpotUtils.getHighestReputation(rep);
+    expect(highestRep).toBe(3);
+});
+
+test('Id encoding', () => {
+    const rawId = 'apache.spot.incubating';
+
+    const encodedId = SpotUtils.encodeId(rawId);
+    const id = SpotUtils.decodeId(encodedId);
+
+    expect(encodedId).not.toBe(rawId);
+    expect(id).toBe(rawId);
+});

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/28277687/spot-oa/ui/proxy/js/components/TimelinePanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/components/TimelinePanel.react.js b/spot-oa/ui/proxy/js/components/TimelinePanel.react.js
index 62af32c..64befaa 100755
--- a/spot-oa/ui/proxy/js/components/TimelinePanel.react.js
+++ b/spot-oa/ui/proxy/js/components/TimelinePanel.react.js
@@ -18,14 +18,15 @@ const TimelineChart = React.createClass({
     _onChange() {
         const storeData = TimelineStore.getData();
 
-        if (storeData.loading || storeData.error) {
-            this.setState(storeData);
+        let state = {loading: storeData.loading};
+        if (storeData.error) {
+            state.error = storeData.error;
         }
-        else {
-            const state = this._getStateFromStoreData(storeData.data);
-
-            this.setState(state);
+        else if (!storeData.loading && storeData.data) {
+            state = this._getStateFromStoreData(storeData.data);
         }
+
+        this.replaceState(state);
     },
     _getStateFromStoreData(data)
     {



[25/50] [abbrv] incubator-spot git commit: Fixed: Unselect previos link on network view (#152)

Posted by ev...@apache.org.
Fixed: Unselect previos link on network view (#152)



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

Branch: refs/heads/master
Commit: a4bff60bc551a8c3662408c49500adbf0d45b54b
Parents: 5d82f14
Author: daortizh <di...@intel.com>
Authored: Tue Nov 29 16:40:12 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Tue Nov 29 16:40:12 2016 -0600

----------------------------------------------------------------------
 .../components/PolloNetworkViewMixin.react.js   | 467 ++++++++++---------
 1 file changed, 235 insertions(+), 232 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/a4bff60b/spot-oa/ui/js/components/PolloNetworkViewMixin.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/components/PolloNetworkViewMixin.react.js b/spot-oa/ui/js/components/PolloNetworkViewMixin.react.js
index fa7fcc3..79a996f 100755
--- a/spot-oa/ui/js/components/PolloNetworkViewMixin.react.js
+++ b/spot-oa/ui/js/components/PolloNetworkViewMixin.react.js
@@ -1,232 +1,235 @@
-const Base64 = require('js-base64').Base64;
-const d3Interpolate = require('d3-interpolate');
-const SpotUtils = require('../utils/SpotUtils');
-
-function getRadious(area) {
-    return Math.sqrt(area/Math.PI);
-}
-
-const PolloNetworkViewMixin = {
-    buildChart() {
-        const svgSel = d3.select(this.svg);
-
-        // Enable zoom behaviour
-        this.zoom = d3.behavior.zoom().on("zoom", this.onZoom);
-        this.canvas = svgSel.append('g');
-        svgSel.call(this.zoom);
-
-        // Node related scales
-        const hitsDomain = [1, this.state.data.maxNodes];
-        const ipDomain = [false, true];
-        this.nodeSizeScale = d3.scale.linear().domain(hitsDomain);
-        this.chargeScale = d3.scale.linear().domain(hitsDomain);
-        this.typeScale = d3.scale.ordinal().domain(ipDomain).range(["circle", "diamond"]);
-        this.colorScale = d3.scale.ordinal().domain(ipDomain).range(["#fdb813", "#0071C5"]);
-
-        // Link related scales
-        this.opacityScale = d3.scale.threshold().domain([13]).range([0.1, 1]);
-        this.linkColorScale = d3.scale.linear()
-                                      .domain([16, 13, 12, 2])
-                                      .range([d3.hsl(214, 0.04, 0.34), d3.hsl(216, 0.02, 0.59), d3.hsl(216, 0.69, 0.84), d3.hsl(201, 0.1, 0.72)])
-                                      .interpolate(d3Interpolate.interpolateCubehelix);
-
-        // Create a new force layout
-        this.force = d3.layout.force();
-
-        // Add and update nodes and links on every tick event from the force layout
-        this.force.on('tick', () => {
-            this.drawLinks();
-            this.drawNodes();
-        });
-
-        // Create a tooltip
-        this.tooltip = d3.tip()
-            .attr('class', 'd3-tip')
-            .html(n => `${n.label}<br/> <small class="text-muted">Right click to apply this node as filter</small>`);
-
-        this.canvas.call(this.tooltip);
-    },
-    onZoom: function () {
-        const translate = d3.event.translate;
-        const scale = d3.event.scale;
-
-        this.canvas.attr('transform', `translate(${translate})scale(${scale})`);
-    },
-    draw() {
-        const svgElement = $(this.svg);
-
-        svgElement.width('100%').height('100%');
-
-        const size = [svgElement.width(), svgElement.height()];
-        /*
-         * Calculate the max area a node can have.
-         *
-         * 1. Get the smaller value betwenn width and height of the canvas.
-         * 2. Calculate the area of imaginary square whose edge length equals the previous value.
-         * 3. Set maxNodeArea to the 40% of the available area of our imaginary square
-         */
-        const maxNodeArea = Math.pow(Math.min(size[0], size[1]), 2) * 0.1;
-
-        // The biggest node we can have goes up to the 50% of maxNodeArea
-        this.nodeSizeScale.range([maxNodeArea*0.01, maxNodeArea*0.5]);
-        const sizeDomain = this.nodeSizeScale.domain();
-        this.chargeScale.range([-this.nodeSizeScale(sizeDomain[0]), -this.nodeSizeScale(sizeDomain[1])])
-
-        this.force
-            .stop()
-            .size(size)
-            .charge(-1000)
-            .linkDistance(l => {
-                return [l.source, l.target].reduce((length, n) => {
-                    return length + getRadious(this.nodeSizeScale(n.hits));
-                }, 50);
-            })
-            .chargeDistance(getRadious(this.nodeSizeScale(this.nodeSizeScale.domain()[1])) * 4)
-            .nodes(this.state.data.nodes)
-            .links(this.state.data.links);
-
-        this.force.start();
-
-        setTimeout(() => {
-            this.force.stop()
-                .charge(n => {
-                    return this.chargeScale(n.weight);
-                })
-                .start();
-        }, 1000);
-
-        // Tooltip margins
-        this.tooltip.box = [size[1]*.4, size[0]*.8, size[1]*.8, size[0]*.4];
-    },
-    drawNodes(nodes) {
-        this.nodesSel = {
-            update: this.canvas.selectAll('.node').data(this.state.data.nodes, n => SpotUtils.encodeId(n.id))
-        };
-        this.nodesSel.enter = this.nodesSel.update.enter();
-
-        // Add new nodes
-        this.nodesSel.enter
-            .append('path', '.edge')
-            .classed('node', true)
-            .attr("id", n => SpotUtils.encodeId(n.id))
-            .attr("d", d3.svg.symbol()
-               .size(n => this.nodeSizeScale(n.hits))
-               .type(n => this.typeScale(n.internalIp))
-            )
-            .attr('fill', n => this.colorScale(n.internalIp))
-            .call(this.force.drag)
-            .on('mouseover', (n) => {
-                var direction = '';
-
-                // Decide where should the tooltip be displayed?
-
-                // Vertically
-                if (d3.event.layerY<this.tooltip.box[0]) {
-                    direction = 's';
-                }
-                else if (d3.event.layerY>this.tooltip.box[2]) {
-                    direction = 'n';
-                }
-
-                // Horizontally
-                if (d3.event.layerX>this.tooltip.box[1]) {
-                    direction += 'w';
-                }
-                else if (d3.event.layerX<this.tooltip.box[3]) {
-                    direction += 'e'
-                }
-
-                direction = direction || 'n';
-
-                this.tooltip.direction(direction);
-                this.tooltip.show.call(this, n);
-            })
-            .on("mousedown", n => {
-                d3.event.stopPropagation();
-            })
-            .on("click", n => {
-                this._onClick(n.id);
-            })
-            .on("contextmenu", n => {
-                this.tooltip.hide();
-
-                this._onContextualClick(n.id);
-            })
-            .on('mouseout', () => {
-                this.tooltip.hide();
-            });
-
-        this.nodesSel.update
-            .attr('transform', n => `translate(${n.x},${n.y})`)
-            .transition()
-                .attr("d", d3.svg.symbol()
-                   .size(n => this.nodeSizeScale(n.hits))
-                   .type(n => this.typeScale(n.internalIp))
-                );
-    },
-    drawLinks(links) {
-        this.linksSel = {
-            update: this.canvas.selectAll('.edge').data(this.state.data.links, l => SpotUtils.encodeId(l.id))
-        };
-        this.linksSel.enter = this.linksSel.update.enter();
-
-        // Add new links
-        this.linksSel.enter
-             .append('line')
-             .classed('edge', true)
-             .attr("id", l => SpotUtils.encodeId(l.id))
-             .style('stroke', l => this.linkColorScale(l.score))
-             .style('stroke-opacity', l => this.opacityScale(l.score));
-
-        // Update links
-        this.linksSel.update
-            .attr("x1", l => l.source.x)
-            .attr("y1", l => l.source.y)
-            .attr("x2", l => l.target.x)
-            .attr("y2", l => l.target.y);
-    },
-    highlightNodes(ids) {
-        ids = ids instanceof Array ? ids : [ids];
-
-        this.canvas.selectAll('.node').classed('node-faded', true);
-
-        ids.forEach(id => {
-            id = SpotUtils.encodeId(id);
-            this.canvas.select(`#${id}.node`).classed("node-faded", false);
-        })
-    },
-    highlightEdge(id) {
-        id = SpotUtils.encodeId(id);
-        this.canvas.selectAll('.edge').classed('edge-faded', true);
-
-        this.canvas.select(`#${id}.edge`)
-            .classed('edge-faded', false)
-            .classed('highlight', true);
-    },
-    unhighlight() {
-        this.canvas.selectAll('.node').classed('node-faded', false);
-        this.canvas.selectAll('.edge')
-            .classed('edge-faded', false)
-            .classed('highlight', false);
-    },
-    selectNodes(ids) {
-        ids = ids instanceof Array ? ids : [ids];
-
-        this.canvas.selectAll('.node').classed('blink_me', false);
-
-        ids.forEach((id) => {
-            id = SpotUtils.encodeId(id);
-            this.canvas.select(`#${id}.node`).classed('blink_me', true);
-        });
-    },
-    selectEdge(id) {
-        id = SpotUtils.encodeId(id);
-        this.canvas.selectAll('.edge')
-            .classed('blink_me', false)
-            .filter(`#${id}`)
-                .classed('active', true)
-                .classed('blink_me', true);
-    }
-};
-
-module.exports = PolloNetworkViewMixin;
+const Base64 = require('js-base64').Base64;
+const d3Interpolate = require('d3-interpolate');
+const SpotUtils = require('../utils/SpotUtils');
+
+function getRadious(area) {
+    return Math.sqrt(area/Math.PI);
+}
+
+const PolloNetworkViewMixin = {
+    buildChart() {
+        const svgSel = d3.select(this.svg);
+
+        // Enable zoom behaviour
+        this.zoom = d3.behavior.zoom().on("zoom", this.onZoom);
+        this.canvas = svgSel.append('g');
+        svgSel.call(this.zoom);
+
+        // Node related scales
+        const hitsDomain = [1, this.state.data.maxNodes];
+        const ipDomain = [false, true];
+        this.nodeSizeScale = d3.scale.linear().domain(hitsDomain);
+        this.chargeScale = d3.scale.linear().domain(hitsDomain);
+        this.typeScale = d3.scale.ordinal().domain(ipDomain).range(["circle", "diamond"]);
+        this.colorScale = d3.scale.ordinal().domain(ipDomain).range(["#fdb813", "#0071C5"]);
+
+        // Link related scales
+        this.opacityScale = d3.scale.threshold().domain([13]).range([0.1, 1]);
+        this.linkColorScale = d3.scale.linear()
+                                      .domain([16, 13, 12, 2])
+                                      .range([d3.hsl(214, 0.04, 0.34), d3.hsl(216, 0.02, 0.59), d3.hsl(216, 0.69, 0.84), d3.hsl(201, 0.1, 0.72)])
+                                      .interpolate(d3Interpolate.interpolateCubehelix);
+
+        // Create a new force layout
+        this.force = d3.layout.force();
+
+        // Add and update nodes and links on every tick event from the force layout
+        this.force.on('tick', () => {
+            this.drawLinks();
+            this.drawNodes();
+        });
+
+        // Create a tooltip
+        this.tooltip = d3.tip()
+            .attr('class', 'd3-tip')
+            .html(n => `${n.label}<br/> <small class="text-muted">Right click to apply this node as filter</small>`);
+
+        this.canvas.call(this.tooltip);
+    },
+    onZoom: function () {
+        const translate = d3.event.translate;
+        const scale = d3.event.scale;
+
+        this.canvas.attr('transform', `translate(${translate})scale(${scale})`);
+    },
+    draw() {
+        const svgElement = $(this.svg);
+
+        svgElement.width('100%').height('100%');
+
+        const size = [svgElement.width(), svgElement.height()];
+        /*
+         * Calculate the max area a node can have.
+         *
+         * 1. Get the smaller value betwenn width and height of the canvas.
+         * 2. Calculate the area of imaginary square whose edge length equals the previous value.
+         * 3. Set maxNodeArea to the 40% of the available area of our imaginary square
+         */
+        const maxNodeArea = Math.pow(Math.min(size[0], size[1]), 2) * 0.1;
+
+        // The biggest node we can have goes up to the 50% of maxNodeArea
+        this.nodeSizeScale.range([maxNodeArea*0.01, maxNodeArea*0.5]);
+        const sizeDomain = this.nodeSizeScale.domain();
+        this.chargeScale.range([-this.nodeSizeScale(sizeDomain[0]), -this.nodeSizeScale(sizeDomain[1])])
+
+        this.force
+            .stop()
+            .size(size)
+            .charge(-1000)
+            .linkDistance(l => {
+                return [l.source, l.target].reduce((length, n) => {
+                    return length + getRadious(this.nodeSizeScale(n.hits));
+                }, 50);
+            })
+            .chargeDistance(getRadious(this.nodeSizeScale(this.nodeSizeScale.domain()[1])) * 4)
+            .nodes(this.state.data.nodes)
+            .links(this.state.data.links);
+
+        this.force.start();
+
+        setTimeout(() => {
+            this.force.stop()
+                .charge(n => {
+                    return this.chargeScale(n.weight);
+                })
+                .start();
+        }, 1000);
+
+        // Tooltip margins
+        this.tooltip.box = [size[1]*.4, size[0]*.8, size[1]*.8, size[0]*.4];
+    },
+    drawNodes(nodes) {
+        this.nodesSel = {
+            update: this.canvas.selectAll('.node').data(this.state.data.nodes, n => SpotUtils.encodeId(n.id))
+        };
+        this.nodesSel.enter = this.nodesSel.update.enter();
+
+        // Add new nodes
+        this.nodesSel.enter
+            .append('path', '.edge')
+            .classed('node', true)
+            .attr("id", n => SpotUtils.encodeId(n.id))
+            .attr("d", d3.svg.symbol()
+               .size(n => this.nodeSizeScale(n.hits))
+               .type(n => this.typeScale(n.internalIp))
+            )
+            .attr('fill', n => this.colorScale(n.internalIp))
+            .call(this.force.drag)
+            .on('mouseover', (n) => {
+                var direction = '';
+
+                // Decide where should the tooltip be displayed?
+
+                // Vertically
+                if (d3.event.layerY<this.tooltip.box[0]) {
+                    direction = 's';
+                }
+                else if (d3.event.layerY>this.tooltip.box[2]) {
+                    direction = 'n';
+                }
+
+                // Horizontally
+                if (d3.event.layerX>this.tooltip.box[1]) {
+                    direction += 'w';
+                }
+                else if (d3.event.layerX<this.tooltip.box[3]) {
+                    direction += 'e'
+                }
+
+                direction = direction || 'n';
+
+                this.tooltip.direction(direction);
+                this.tooltip.show.call(this, n);
+            })
+            .on("mousedown", n => {
+                d3.event.stopPropagation();
+            })
+            .on("click", n => {
+                this._onClick(n.id);
+            })
+            .on("contextmenu", n => {
+                this.tooltip.hide();
+
+                this._onContextualClick(n.id);
+            })
+            .on('mouseout', () => {
+                this.tooltip.hide();
+            });
+
+        this.nodesSel.update
+            .attr('transform', n => `translate(${n.x},${n.y})`)
+            .transition()
+                .attr("d", d3.svg.symbol()
+                   .size(n => this.nodeSizeScale(n.hits))
+                   .type(n => this.typeScale(n.internalIp))
+                );
+    },
+    drawLinks(links) {
+        this.linksSel = {
+            update: this.canvas.selectAll('.edge').data(this.state.data.links, l => SpotUtils.encodeId(l.id))
+        };
+        this.linksSel.enter = this.linksSel.update.enter();
+
+        // Add new links
+        this.linksSel.enter
+             .append('line')
+             .classed('edge', true)
+             .attr("id", l => SpotUtils.encodeId(l.id))
+             .style('stroke', l => this.linkColorScale(l.score))
+             .style('stroke-opacity', l => this.opacityScale(l.score));
+
+        // Update links
+        this.linksSel.update
+            .attr("x1", l => l.source.x)
+            .attr("y1", l => l.source.y)
+            .attr("x2", l => l.target.x)
+            .attr("y2", l => l.target.y);
+    },
+    highlightNodes(ids) {
+        ids = ids instanceof Array ? ids : [ids];
+
+        this.canvas.selectAll('.node').classed('node-faded', true);
+
+        ids.forEach(id => {
+            id = SpotUtils.encodeId(id);
+            this.canvas.select(`#${id}.node`).classed("node-faded", false);
+        })
+    },
+    highlightEdge(id) {
+        id = SpotUtils.encodeId(id);
+        this.canvas.selectAll('.edge').classed('edge-faded', true);
+
+        this.canvas.select(`#${id}.edge`)
+            .classed('edge-faded', false)
+            .classed('highlight', true);
+    },
+    unhighlight() {
+        this.canvas.selectAll('.node').classed('node-faded', false);
+        this.canvas.selectAll('.edge')
+            .classed('edge-faded', false)
+            .classed('highlight', false);
+    },
+    selectNodes(ids) {
+        ids = ids instanceof Array ? ids : [ids];
+
+        this.canvas.selectAll('.node.blink_me').classed('blink_me', false);
+
+        ids.forEach((id) => {
+            id = SpotUtils.encodeId(id);
+            this.canvas.select(`#${id}.node`).classed('blink_me', true);
+        });
+    },
+    selectEdge(id) {
+        id = SpotUtils.encodeId(id);
+
+        this.canvas.selectAll('.edge.blink_me,.edge.active').classed('blink_me', false).classed('active', false);
+
+        this.canvas.selectAll('.edge')
+            .classed('blink_me', false)
+            .filter(`#${id}`)
+                .classed('active', true)
+                .classed('blink_me', true);
+    }
+};
+
+module.exports = PolloNetworkViewMixin;


[16/50] [abbrv] incubator-spot git commit: Remove original pcap file after the split

Posted by ev...@apache.org.
Remove original pcap file after the split


Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/484a19b4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/484a19b4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/484a19b4

Branch: refs/heads/master
Commit: 484a19b4f6c8f8070779df2c92c3ec9a637e4726
Parents: ea52d12
Author: elopezsa <ev...@intel.com>
Authored: Mon Nov 28 10:42:50 2016 -0600
Committer: elopezsa <ev...@intel.com>
Committed: Mon Nov 28 10:42:50 2016 -0600

----------------------------------------------------------------------
 spot-ingest/pipelines/dns/collector.py | 47 ++++++++++++++---------------
 1 file changed, 22 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/484a19b4/spot-ingest/pipelines/dns/collector.py
----------------------------------------------------------------------
diff --git a/spot-ingest/pipelines/dns/collector.py b/spot-ingest/pipelines/dns/collector.py
index 496011c..6bb0bbb 100755
--- a/spot-ingest/pipelines/dns/collector.py
+++ b/spot-ingest/pipelines/dns/collector.py
@@ -13,12 +13,10 @@ from common.kafka_client import KafkaTopic
 
 class Collector(object):
 
-    def __init__(self,hdfs_app_path,kafka_topic,conf_type):
-        
-        self._initialize_members(hdfs_app_path,kafka_topic,conf_type)
+    def __init__(self, hdfs_app_path, kafka_topic, conf_type):
+        self._initialize_members(hdfs_app_path, kafka_topic, conf_type)
 
-    def _initialize_members(self,hdfs_app_path,kafka_topic,conf_type):
-    
+    def _initialize_members(self, hdfs_app_path, kafka_topic, conf_type):
         # getting parameters.
         self._logger = logging.getLogger('SPOT.INGEST.DNS')
         self._hdfs_app_path = hdfs_app_path
@@ -33,50 +31,48 @@ class Collector(object):
         self._conf = conf["pipelines"][conf_type]
 
         # set configuration.
-        self._collector_path = self._conf['collector_path']        
+        self._collector_path = self._conf['collector_path']
         self._dsource = 'dns'
         self._hdfs_root_path = "{0}/{1}".format(hdfs_app_path, self._dsource)
 
         # set configuration.
         self._pkt_num = self._conf['pkt_num']
         self._pcap_split_staging = self._conf['pcap_split_staging']
-        self._supported_files = self._conf['supported_files']  
+        self._supported_files = self._conf['supported_files']
 
-        # create collector watcher        
-        self._watcher = FileWatcher(self._collector_path,self._supported_files)
+        # create collector watcher
+        self._watcher = FileWatcher(self._collector_path, self._supported_files)
 
-        # Multiprocessing. 
+        # Multiprocessing.
         self._processes = conf["collector_processes"]
         self._ingestion_interval = conf["ingestion_interval"]
         self._pool = Pool(processes=self._processes)
 
     def start(self):
 
-        self._logger.info("Starting DNS ingest")    
+        self._logger.info("Starting DNS ingest")
         self._watcher.start()
 
         try:
             while True:
-                self._ingest_files_pool()              
+                self._ingest_files_pool()
                 time.sleep(self._ingestion_interval)
 
         except KeyboardInterrupt:
-            self._logger.info("Stopping DNS collector...")  
-            Util.remove_kafka_topic(self._kafka_topic.Zookeeper,self._kafka_topic.Topic,self._logger)          
+            self._logger.info("Stopping DNS collector...")
+            Util.remove_kafka_topic(self._kafka_topic.Zookeeper, self._kafka_topic.Topic, self._logger)
             self._watcher.stop()
             self._pool.terminate()
-            self._pool.close()            
+            self._pool.close()
             self._pool.join()
             SystemExit("Ingest finished...")
 
 
-    def _ingest_files_pool(self):            
-       
+    def _ingest_files_pool(self):
         if self._watcher.HasFiles:
-            
-            for x in range(0,self._processes):
+            for x in range(0, self._processes):
                 file = self._watcher.GetNextFile()
-                resutl = self._pool.apply_async(ingest_file,args=(file,self._pkt_num,self._pcap_split_staging,self._kafka_topic.Partition,self._hdfs_root_path ,self._kafka_topic.Topic,self._kafka_topic.BootstrapServers,))
+                resutl = self._pool.apply_async(ingest_file, args=(file, self._pkt_num, self._pcap_split_staging, self._kafka_topic.Partition, self._hdfs_root_path, self._kafka_topic.Topic, self._kafka_topic.BootstrapServers, ))
                 #resutl.get() # to debug add try and catch.
                 if  not self._watcher.HasFiles: break    
         return True
@@ -93,10 +89,14 @@ def ingest_file(file,pkt_num,pcap_split_staging, partition,hdfs_root_path,topic,
 
         # split file.
         name = file_name.split('.')[0]
-        split_cmd="editcap -c {0} {1} {2}/{3}_spot.pcap".format(pkt_num,file,pcap_split_staging,name)
+        split_cmd = "editcap -c {0} {1} {2}/{3}_spot.pcap".format(pkt_num,file,pcap_split_staging,name)
         logger.info("Splitting file: {0}".format(split_cmd))
         Util.execute_cmd(split_cmd,logger)
 
+        logger.info("Removing file: {0}".format(org_file))
+        rm_big_file = "rm {0}".format(org_file)
+        Util.execute_cmd(rm_big_file,logger)    
+
         for currdir,subdir,files in os.walk(pcap_split_staging):
             for file in files:
                 if file.endswith(".pcap") and "{0}_spot".format(name) in file:
@@ -122,10 +122,7 @@ def ingest_file(file,pkt_num,pcap_split_staging, partition,hdfs_root_path,topic,
                         logger.info("File {0} has been successfully sent to Kafka Topic to: {1}".format(file,topic))
 
 
-        logger.info("Removing file: {0}".format(org_file))
-        rm_big_file = "rm {0}".format(org_file)
-        Util.execute_cmd(rm_big_file,logger)
-    
+  
     except Exception as err:
         
         logger.error("There was a problem, please check the following error message:{0}".format(err.message))


[19/50] [abbrv] incubator-spot git commit: Merge pull request #143 from Open-Network-Insight/spot_flow_nb_additional_info

Posted by ev...@apache.org.
Merge pull request #143 from Open-Network-Insight/spot_flow_nb_additional_info

Spot flow nb additional info

Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/9763e2a2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/9763e2a2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/9763e2a2

Branch: refs/heads/master
Commit: 9763e2a2ad459cd3c5cc7f1ac92122f5c41a8ef6
Parents: c2b1c47 9597dd1
Author: LedaLima <ga...@intel.com>
Authored: Mon Nov 28 11:23:18 2016 -0800
Committer: GitHub <no...@github.com>
Committed: Mon Nov 28 11:23:18 2016 -0800

----------------------------------------------------------------------
 .../Threat_Investigation_master.ipynb           | 96 +++++++++++---------
 1 file changed, 55 insertions(+), 41 deletions(-)
----------------------------------------------------------------------



[28/50] [abbrv] incubator-spot git commit: Adding ingest folder path

Posted by ev...@apache.org.
Adding ingest folder path


Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/8b508e11
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/8b508e11
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/8b508e11

Branch: refs/heads/master
Commit: 8b508e11cf4770ad7fb187898533c2084aecc8b9
Parents: 3cb7dbe
Author: elopezsa <ev...@intel.com>
Authored: Wed Nov 30 11:29:18 2016 -0600
Committer: elopezsa <ev...@intel.com>
Committed: Wed Nov 30 11:29:18 2016 -0600

----------------------------------------------------------------------
 spot-oa/oa/flow/flow_oa.py | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/8b508e11/spot-oa/oa/flow/flow_oa.py
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/flow_oa.py b/spot-oa/oa/flow/flow_oa.py
index 50ecf9a..eb3aaf0 100644
--- a/spot-oa/oa/flow/flow_oa.py
+++ b/spot-oa/oa/flow/flow_oa.py
@@ -404,7 +404,7 @@ class OA(object):
 
         ingest_summary_qry = ingest_summary_qry.format(yr,mn,dy)
 
-        results_file = "{0}/results_{1}.csv".format(self._data_path,self._date)
+        results_file = "{0}/results_{1}.csv".format(self._ingest_summary_path,self._date)
         self._engine.query(ingest_summary_qry,output_file=results_file,delimiter=",")
         
         result_rows = []        
@@ -414,13 +414,16 @@ class OA(object):
         
         result_rows = iter(result_rows)
         next(result_rows)
-        ingest_summary_results2 = [ ["{0}-{1}-{2} {3}:{4}".format(yr,mn,dy,row[3],row[4]), row[5]] for row in result_rows ]
-        ingest_summay_file = "{0}/is_{1}.csv".format(self._data_path,self._date)
+
+        ingest_summary_results = [ ["date","flows"] ]
+        ingest_summary_results.extend([ ["{0}/{1}/{2} {3}:{4}".format(mn,dy,yr,row[3].zfill(2) ,row[4].zfill(2)), row[5]] for row in result_rows ])
+        ingest_summay_file = "{0}/is_{1}.csv".format(self._ingest_summary_path,self._date)
+
 
         write_format =  'a' if os.path.isfile(ingest_summay_file) else 'w+'
         with open(ingest_summay_file, write_format) as u_file:
             writer = csv.writer(u_file, quoting=csv.QUOTE_NONE, delimiter=",")
-            writer.writerows(ingest_summary_results2)
+            writer.writerows(ingest_summary_results)
 
         rm_big_file = "rm {0}".format(results_file)
         os.remove(results_file)


[30/50] [abbrv] incubator-spot git commit: Merge pull request #153 from Open-Network-Insight/ingest_summary

Posted by ev...@apache.org.
Merge pull request #153 from Open-Network-Insight/ingest_summary

Adding ingest summary functionality to OA module

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

Branch: refs/heads/master
Commit: ef20216c43f98b40392a36f4c7edf667ae0ae180
Parents: 056abbc 7374c4c
Author: Everardo Lopez Sandoval <ev...@intel.com>
Authored: Wed Nov 30 16:40:25 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Wed Nov 30 16:40:25 2016 -0600

----------------------------------------------------------------------
 spot-ingest/README.md      | 21 ++++++++++----
 spot-oa/oa/flow/flow_oa.py | 62 ++++++++++++++++++++++++++++++++++-------
 2 files changed, 68 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/ef20216c/spot-oa/oa/flow/flow_oa.py
----------------------------------------------------------------------


[11/50] [abbrv] incubator-spot git commit: Cleaned notebook previous executions

Posted by ev...@apache.org.
Cleaned notebook previous executions


Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/8f9f05a0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/8f9f05a0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/8f9f05a0

Branch: refs/heads/master
Commit: 8f9f05a088e306e1a6aca7e50ff6d20a0f55d838
Parents: 54c9131
Author: LedaLima <ll...@mtolarin-mobl4.amr.corp.intel.com>
Authored: Tue Nov 22 16:15:45 2016 -0600
Committer: LedaLima <ll...@mtolarin-mobl4.amr.corp.intel.com>
Committed: Tue Nov 22 16:15:45 2016 -0600

----------------------------------------------------------------------
 .../Threat_Investigation_master.ipynb           | 20 ++++++--------------
 1 file changed, 6 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/8f9f05a0/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
index 820395a..3fd5d65 100644
--- a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
+++ b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
@@ -2,19 +2,11 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": null,
    "metadata": {
     "collapsed": false
    },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "No iploc.csv file was found, Map View map won't be created\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "import struct, socket\n",
     "import numpy as np\n",
@@ -59,7 +51,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": null,
    "metadata": {
     "collapsed": false
    },
@@ -129,7 +121,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": null,
    "metadata": {
     "collapsed": true
    },
@@ -271,7 +263,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": null,
    "metadata": {
     "collapsed": false
    },
@@ -769,7 +761,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 10,
+   "execution_count": null,
    "metadata": {
     "collapsed": false
    },


[32/50] [abbrv] incubator-spot git commit: fix db for ingest summary

Posted by ev...@apache.org.
fix db for ingest summary


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

Branch: refs/heads/master
Commit: 3fe41bbd9d2f4aa648fa133d2d0691e9cd615f47
Parents: 7374c4c
Author: elopezsa <ev...@intel.com>
Authored: Wed Nov 30 17:40:26 2016 -0600
Committer: elopezsa <ev...@intel.com>
Committed: Wed Nov 30 17:40:26 2016 -0600

----------------------------------------------------------------------
 spot-oa/oa/flow/flow_oa.py | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/3fe41bbd/spot-oa/oa/flow/flow_oa.py
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/flow_oa.py b/spot-oa/oa/flow/flow_oa.py
index d40515d..cace445 100644
--- a/spot-oa/oa/flow/flow_oa.py
+++ b/spot-oa/oa/flow/flow_oa.py
@@ -395,15 +395,15 @@ class OA(object):
 
         # get ingest summary.           
         ingest_summary_qry = ("SELECT tryear, trmonth, trday, trhour, trminute, COUNT(*) flows"
-                              " FROM onidb.flow "
+                              " FROM {0}.flow "
                               " WHERE "
-                              " y={0} "
-                              " AND m={1} "
-                              " AND d={2} "
+                              " y={1} "
+                              " AND m={2} "
+                              " AND d={3} "
                               " AND unix_tstamp IS NOT NULL "
                               " GROUP BY tryear, trmonth, trday, trhour, trminute;")
 
-        ingest_summary_qry = ingest_summary_qry.format(yr,mn,dy)
+        ingest_summary_qry = ingest_summary_qry.format(self._db, yr, mn, dy)
 
         results_file = "{0}/results_{1}.csv".format(self._ingest_summary_path,self._date)
         self._engine.query(ingest_summary_qry,output_file=results_file,delimiter=",")


[21/50] [abbrv] incubator-spot git commit: Removed saved connection from list after clicking 'save' button

Posted by ev...@apache.org.
Removed saved connection from list after clicking 'save' button


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

Branch: refs/heads/master
Commit: ad8839fe66cc7f2b2264b904906ec80156baf233
Parents: 9763e2a
Author: LedaLima <ga...@intel.com>
Authored: Mon Nov 28 17:13:38 2016 -0600
Committer: LedaLima <ga...@intel.com>
Committed: Mon Nov 28 17:13:38 2016 -0600

----------------------------------------------------------------------
 .../Threat_Investigation_master.ipynb           | 31 ++++++++------------
 1 file changed, 12 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/ad8839fe/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
index acab173..a0a7d26 100644
--- a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
+++ b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
@@ -148,29 +148,21 @@
     "    \n",
     "    if os.path.isfile(threats_file) and not file_is_empty(threats_file):\n",
     "        with open(threats_file, 'r') as th:\n",
-    "            t_read = csv.reader(th, delimiter='|')\n",
-    "            t_read.next()\n",
+    "            t_read = csv.DictReader(th, delimiter='|') \n",
     "            for row in t_read: \n",
-    "                if row[0] != '' : c_ips.append(row[0]) \n",
+    "                if row['ip'] != '' : c_ips.append(row['ip']) \n",
     "\n",
     "    with open(sconnect, 'r') as f:\n",
-    "        reader = csv.reader(f, delimiter=',')\n",
-    "        reader.next()\n",
+    "        reader = csv.DictReader(f, delimiter=',') \n",
     "        #Internal Netflows use case:\n",
-    "        for row in reader:\n",
-    "            #sev,tstart,srcIP,dstIP,sport,dport,proto,flag,ipkt,ibyt,lda_score,rank,            \n",
-    "            # 0 ,  1   ,  2  ,  3  ,  4  ,  5  ,  6  ,  7 ,  8 , 9  ,     10  , 11 ,\n",
-    "            #srcIpInternal,destIpInternal,srcGeo,dstGeo,  \n",
-    "            #      12     ,       13     ,  14  ,  15  ,\n",
-    "            #srcDomain,dstDomain,srcIP_rep,dstIP_rep\n",
-    "            #    16   ,   17    ,   18    ,   19     \n",
-    "            if row[0] == '1':\n",
+    "        for row in reader: \n",
+    "            if row['sev'] == '1':\n",
     "                srcIP = ''\n",
     "                dstIP = '' \n",
-    "                if row[2] not in external_ips and row[2] not in c_ips: \n",
-    "                    external_ips.append(row[2])\n",
-    "                if row[3] not in external_ips and row[3] not in c_ips: \n",
-    "                    external_ips.append(row[3])\n",
+    "                if row['srcIP'] not in external_ips and row['srcIP'] not in c_ips: \n",
+    "                    external_ips.append(row['srcIP'])\n",
+    "                if row['dstIP'] not in external_ips and row['dstIP'] not in c_ips: \n",
+    "                    external_ips.append(row['dstIP'])\n",
     "\n",
     "    if len(external_ips) == 0:\n",
     "        display(widgets.Box((widgets.HTML(value=\"There are no connections scored as High risk.\\\n",
@@ -247,8 +239,7 @@
     "    \n",
     "    def save_threat_summary(b):\n",
     "        clear_output()        \n",
-    "        removeWidget(1)\n",
-    "        display(Javascript(\"$(\\\"option[data-value='\" + anchor +\"']\\\").remove();\"))   \n",
+    "        removeWidget(1) \n",
     "        response = \"\"\n",
     "        response += generate_attack_map_file(anchor, top_inbound_b, top_outbound_b, top_twoway_b)\n",
     "        response += generate_stats(anchor, inbound, outbound, twoway, threat_name)\n",
@@ -256,8 +247,10 @@
     "        response += details_inbound(anchor, top_inbound_b, top_outbound_b, top_twoway_b)\n",
     "        response += add_threat(anchor, tc_txt_title.value, tc_txa_summary.value.replace('\\n', '\\\\n'))\n",
     "        response += \"Story board successfully created for {0}\".format(anchor)\n",
+    "        start_investigation()\n",
     "        display(widgets.Box((widgets.HTML(value=response, width='100%'),)))\n",
     "        \n",
+    "        \n",
     "    tc_btn_save.on_click(save_threat_summary)"
    ]
   },


[07/50] [abbrv] incubator-spot git commit: Moved accordion below the textbox in Threat Inv Notebook

Posted by ev...@apache.org.
Moved accordion below the textbox in Threat Inv Notebook


Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/6d54aef3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/6d54aef3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/6d54aef3

Branch: refs/heads/master
Commit: 6d54aef307e53dcd82112d8177b67f44142bec1d
Parents: ed6c8ee
Author: LedaLima <ll...@miguelag-mobl1.amr.corp.intel.com>
Authored: Tue Nov 22 11:07:31 2016 -0600
Committer: LedaLima <ll...@miguelag-mobl1.amr.corp.intel.com>
Committed: Tue Nov 22 11:07:31 2016 -0600

----------------------------------------------------------------------
 .../Threat_Investigation_master.ipynb           | 21 ++++++--------------
 1 file changed, 6 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/6d54aef3/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
index b381965..63bd366 100644
--- a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
+++ b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
@@ -46,16 +46,14 @@
     "if os.path.isfile(iploc):\n",
     "    iplist = np.loadtxt(iploc,dtype=np.uint32,delimiter=',',usecols={0}, converters={0: lambda s: np.uint32(s.replace('\"',''))})\n",
     "else:\n",
-    "    print \"No iploc.csv file was found, Map View map won't be created\"\n",
-    "    \n",
-    "print cpath"
+    "    print \"No iploc.csv file was found, Map View map won't be created\""
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
-    "collapsed": true
+    "collapsed": false
    },
    "outputs": [],
    "source": [
@@ -93,12 +91,6 @@
     "result_summary_box.children = [result_title, result_summary_container, result_button_container]\n",
     " \n",
     "resultTableBox = widgets.HBox()\n",
-    "# result_bytes_title = widgets.HTML(height='25px', width='100%')\n",
-    "# result_conns_title = widgets.HTML(height='25px', width='100%')\n",
-    "result_conns_box = widgets.Box() #this one has the scroll\n",
-    "result_bytes_box = widgets.Box() #this one has the scroll\n",
-    "# result_conns = widgets.HTML(width='100%')\n",
-    "# result_bytes = widgets.HTML(width='100%')\n",
     "result_box_css = (\n",
     "    (None, 'overflow', 'hidden'),\n",
     "    (None, 'width', '100%'),\n",
@@ -120,8 +112,7 @@
     ")  \n",
     "\n",
     "topBox.children = [threatBox]\n",
-    "bottomBox.children = [resultSummaryBox,resultTableBox]\n",
-    "resultTableBox.children = [result_conns_box, result_bytes_box]"
+    "bottomBox.children = [resultSummaryBox,resultTableBox]"
    ]
   },
   {
@@ -241,7 +232,7 @@
     "\n",
     "\n",
     "def display_threat_box(ip):\n",
-    "#     clear_output()\n",
+    "    clear_output()\n",
     "    result_title.value=\"<h4 class='spot-text-wrapper spot-text-xlg' data-toggle='tooltip'>Threat summary for \" + anchor +\"</h4>\"\n",
     "    tc_txt_title = widgets.Text(value='', placeholder='Threat Title', width='100%')\n",
     "    tc_txa_summary = widgets.Textarea(value='', height=100, width='95%')\n",
@@ -522,7 +513,7 @@
     "            (None, 'margin-bottom', '10px'),\n",
     "        )\n",
     "\n",
-    "        display(result_tabs)\n",
+    "        resultTableBox.children = [result_tabs,]\n",
     "         \n",
     "    if rowct > 0:\n",
     "        for result in srcdict:\n",
@@ -777,7 +768,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython2",
-   "version": "2.7.6"
+   "version": "2.7.10"
   }
  },
  "nbformat": 4,


[09/50] [abbrv] incubator-spot git commit: Update Threat_Investigation_master.ipynb

Posted by ev...@apache.org.
Update Threat_Investigation_master.ipynb

Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/409e1d3a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/409e1d3a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/409e1d3a

Branch: refs/heads/master
Commit: 409e1d3a69b42f84353864a4d2758d41f5d39409
Parents: 25cd935
Author: LedaLima <ga...@intel.com>
Authored: Tue Nov 22 11:41:58 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Tue Nov 22 11:41:58 2016 -0600

----------------------------------------------------------------------
 spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/409e1d3a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
index adfeab9..2022afc 100644
--- a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
+++ b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
@@ -503,7 +503,7 @@
     "        result_tabs.set_title(0,\"Top source IP per connections\")\n",
     "        result_tabs.set_title(1,\"Top destination IP per connections\")\n",
     "        result_tabs.set_title(2,\"Top source IP per bytes transferred\")\n",
-    "        result_tabs.set_title(3,\"Top source IP per bytes transferred\")\n",
+    "        result_tabs.set_title(3,\"Top destination IP per bytes transferred\")\n",
     "        \n",
     "        result_tabs._css = (\n",
     "            (None, 'margin-top', '10px'),\n",


[50/50] [abbrv] incubator-spot git commit: renaming docker link to spot

Posted by ev...@apache.org.
renaming docker link to spot


Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/8830127b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/8830127b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/8830127b

Branch: refs/heads/master
Commit: 8830127b1cf2b55684ee4727f1e8a3231d74dddd
Parents: 6586bb0
Author: elopezsa <ev...@intel.com>
Authored: Thu Dec 8 10:52:09 2016 -0600
Committer: elopezsa <ev...@intel.com>
Committed: Thu Dec 8 10:52:09 2016 -0600

----------------------------------------------------------------------
 README.md | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/8830127b/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index b215a10..f089cb7 100644
--- a/README.md
+++ b/README.md
@@ -52,11 +52,7 @@ While inspecting specific, unique flows of data that may be important for indivi
 2. Run the container: `docker run -it -p 8889:8889 opennetworkinsight/oni-demo`
 3. visit [http://localhost:8889/files/ui/flow/suspicious.html#date=2016-07-08](http://localhost:8889/files/ui/proxy/suspicious.html#date=2016-07-08) in your browser to get started
 
-For the full instructions visit the [opennetworkinsight](https://hub.docker.com/r/opennetworkinsight/oni-demo/) on Docker hub
-
-*Running the standalone demo*
-
-pull the code from [oni-demo repo](https://github.com/Open-Network-Insight/oni-demo) and install it yourself
+For the full instructions visit the [spot](https://hub.docker.com/r/opennetworkinsight/oni-demo/) on Docker hub
 
 ## **Getting Started**
 


[10/50] [abbrv] incubator-spot git commit: Fixed bug where the selected IP was always displaying instead of the other IPs

Posted by ev...@apache.org.
Fixed bug where the selected IP was always displaying instead of the other IPs


Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/54c9131f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/54c9131f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/54c9131f

Branch: refs/heads/master
Commit: 54c9131fe9e38dceb70c528ac2b1071f0dc104ca
Parents: 409e1d3
Author: LedaLima <ll...@miguelag-mobl1.amr.corp.intel.com>
Authored: Tue Nov 22 11:54:50 2016 -0600
Committer: LedaLima <ll...@miguelag-mobl1.amr.corp.intel.com>
Committed: Tue Nov 22 11:54:50 2016 -0600

----------------------------------------------------------------------
 .../Threat_Investigation_master.ipynb           | 24 +++++++++++++-------
 1 file changed, 16 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/54c9131f/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
index 2022afc..820395a 100644
--- a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
+++ b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
@@ -2,11 +2,19 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 6,
    "metadata": {
     "collapsed": false
    },
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "No iploc.csv file was found, Map View map won't be created\n"
+     ]
+    }
+   ],
    "source": [
     "import struct, socket\n",
     "import numpy as np\n",
@@ -51,7 +59,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 7,
    "metadata": {
     "collapsed": false
    },
@@ -121,7 +129,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 8,
    "metadata": {
     "collapsed": true
    },
@@ -263,7 +271,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 9,
    "metadata": {
     "collapsed": false
    },
@@ -482,10 +490,10 @@
     "                        }       \n",
     "                    rowct +=1  \n",
     "        \n",
-    "        src = df.loc[df['srcip'] == anchor]\n",
+    "        src = df.loc[df['dstip'] == anchor]\n",
     "        src_per_conns = src.sort_values('conns',0,False)\n",
     "        src_per_bytes = src.sort_values('maxbytes',0,False)\n",
-    "        dst = df.loc[df['dstip'] == anchor]\n",
+    "        dst = df.loc[df['srcip'] == anchor]\n",
     "        dst_per_conns = dst.sort_values('conns',0,False)\n",
     "        dst_per_bytes = dst.sort_values('maxbytes',0,False)\n",
     "\n",
@@ -761,7 +769,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 10,
    "metadata": {
     "collapsed": false
    },


[05/50] [abbrv] incubator-spot git commit: Using accordion widgets for summary tables

Posted by ev...@apache.org.
Using accordion widgets for summary tables


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

Branch: refs/heads/master
Commit: ed6c8ee0f923c006b1028d33871e36b3bd348f8e
Parents: 78bd693
Author: Diego Ortiz Huerta <di...@intel.com>
Authored: Fri Nov 18 12:45:59 2016 -0800
Committer: Diego Ortiz Huerta <di...@intel.com>
Committed: Fri Nov 18 12:45:59 2016 -0800

----------------------------------------------------------------------
 .../Threat_Investigation_master.ipynb           | 32 +++++++++++---------
 1 file changed, 17 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/ed6c8ee0/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
index 33a7096..b381965 100644
--- a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
+++ b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
@@ -500,6 +500,7 @@
     "        dst = df.loc[df['dstip'] == anchor]\n",
     "        dst_per_conns = dst.sort_values('conns',0,False)\n",
     "        dst_per_bytes = dst.sort_values('maxbytes',0,False)\n",
+    "\n",
     "        children = []\n",
     "        children += (display_conn_results(['srcip','conns','sport','dport'], src_per_conns, \n",
     "                                          top_results),)\n",
@@ -509,12 +510,18 @@
     "                                           top_results),)\n",
     "        children += (display_bytes_results(['dstip','maxbytes','sport','dport'], dst_per_bytes, \n",
     "                                           top_results),)\n",
-    "               \n",
-    "        result_tabs = widgets.Tab(children=children, width='100%')\n",
+    "\n",
+    "        result_tabs = widgets.Accordion(children=children, width='100%', selected_index=-1)\n",
     "        result_tabs.set_title(0,\"Top source IP per connections\")\n",
     "        result_tabs.set_title(1,\"Top destination IP per connections\")\n",
     "        result_tabs.set_title(2,\"Top source IP per bytes transferred\")\n",
     "        result_tabs.set_title(3,\"Top source IP per bytes transferred\")\n",
+    "        \n",
+    "        result_tabs._css = (\n",
+    "            (None, 'margin-top', '10px'),\n",
+    "            (None, 'margin-bottom', '10px'),\n",
+    "        )\n",
+    "\n",
     "        display(result_tabs)\n",
     "         \n",
     "    if rowct > 0:\n",
@@ -530,20 +537,15 @@
     "\n",
     "# ========Prints the list of tables =====\n",
     "\n",
-    "def display_conn_results(cols, dataframe, top):\n",
-    "    table= dataframe[:top].to_html(columns=cols, index=False)\n",
-    "#     result_conns_box.children += (widgets.HTML(height='25px', width='100%', value=title),\n",
-    "#                                   widgets.HTML(value=table, width='100%'), separator,)\n",
-    "    return widgets.HTML(value=table, width='100%')\n",
-    "    \n",
-    "    \n",
-    "    \n",
+    "def display_conn_results(cols, dataframe, top):    \n",
+    "    return display_as_html_table(cols, dataframe, top)\n",
     "    \n",
     "def display_bytes_results(cols, dataframe, top):\n",
-    "    table = dataframe[:top].to_html(columns=cols, index=False)\n",
-    "    return  widgets.HTML(value=table, width='100%') \n",
-    "    \n",
-    "             \n",
+    "    return display_as_html_table(cols, dataframe, top)\n",
+    "\n",
+    "def display_as_html_table(cols, dataframe, top):\n",
+    "    table = dataframe[:top].to_html(classes='table table-striped table-bordered table-hover', columns=cols, index=False)\n",
+    "    return widgets.HTML(value=table, width='100%')\n",
     "            \n",
     "#=========== Adds GEO IP information to the outbound, inbound and twoway connections==============================# \n",
     "def add_geospatial_info():\n",
@@ -775,7 +777,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython2",
-   "version": "2.7.10"
+   "version": "2.7.6"
   }
  },
  "nbformat": 4,


[08/50] [abbrv] incubator-spot git commit: Added back functions to filter inbound, outbound and twoway connections

Posted by ev...@apache.org.
Added back functions to filter inbound, outbound and twoway connections


Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/25cd935b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/25cd935b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/25cd935b

Branch: refs/heads/master
Commit: 25cd935be68ec53d54f2112568db73d2f0c124bd
Parents: 6d54aef
Author: LedaLima <ll...@miguelag-mobl1.amr.corp.intel.com>
Authored: Tue Nov 22 11:31:14 2016 -0600
Committer: LedaLima <ll...@miguelag-mobl1.amr.corp.intel.com>
Committed: Tue Nov 22 11:31:14 2016 -0600

----------------------------------------------------------------------
 .../Threat_Investigation_master.ipynb           | 47 ++++++++++++++------
 1 file changed, 33 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/25cd935b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
index 63bd366..adfeab9 100644
--- a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
+++ b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
@@ -104,9 +104,6 @@
     "    (None, 'width', '50%'),\n",
     ")\n",
     "\n",
-    "result_conns_box._css = result_content_box_css\n",
-    "result_bytes_box._css = result_content_box_css\n",
-    "\n",
     "threat_button_container._css = (\n",
     "    (None, 'padding-top', '30px'), \n",
     ")  \n",
@@ -493,13 +490,13 @@
     "        dst_per_bytes = dst.sort_values('maxbytes',0,False)\n",
     "\n",
     "        children = []\n",
-    "        children += (display_conn_results(['srcip','conns','sport','dport'], src_per_conns, \n",
+    "        children += (display_results(['srcip','conns','sport','dport'], src_per_conns, \n",
     "                                          top_results),)\n",
-    "        children += (display_conn_results(['dstip','conns','sport','dport'], dst_per_conns, \n",
+    "        children += (display_results(['dstip','conns','sport','dport'], dst_per_conns, \n",
     "                                          top_results),)\n",
-    "        children += (display_bytes_results(['srcip','maxbytes','sport','dport'], src_per_bytes, \n",
+    "        children += (display_results(['srcip','maxbytes','sport','dport'], src_per_bytes, \n",
     "                                           top_results),)\n",
-    "        children += (display_bytes_results(['dstip','maxbytes','sport','dport'], dst_per_bytes, \n",
+    "        children += (display_results(['dstip','maxbytes','sport','dport'], dst_per_bytes, \n",
     "                                           top_results),)\n",
     "\n",
     "        result_tabs = widgets.Accordion(children=children, width='100%', selected_index=-1)\n",
@@ -525,14 +522,25 @@
     "        for result in dstdict:\n",
     "            if result not in srcdict:\n",
     "                inbound[result] = dstdict[result]   \n",
+    "                \n",
+    "    global top_inbound_b\n",
+    "    global top_outbound_b\n",
+    "    global top_twoway_b\n",
+    "    if len(inbound) > 0:\n",
+    "        top_inbound_b = get_top_bytes(inbound,top_results)\n",
+    "        top_inbound_conns = get_top_conns(inbound,top_results)\n",
+    "        top_inbound_b.update(top_inbound_conns) # merge the two dictionaries\n",
+    "    if len(outbound) > 0:\n",
+    "        top_outbound_b = get_top_bytes(outbound,top_results)\n",
+    "        top_outbound_conns = get_top_conns(outbound,top_results)\n",
+    "        top_outbound_b.update(top_outbound_conns) # merge the two dictionaries\n",
+    "    if len(twoway) > 0:        \n",
+    "        top_twoway_b = get_top_bytes(twoway,top_results)\n",
+    "        top_twoway_conns = get_top_conns(twoway,top_results)\n",
+    "        top_twoway_b.update(top_twoway_conns) # merge the two dictionaries\n",
     "\n",
-    "# ========Prints the list of tables =====\n",
-    "\n",
-    "def display_conn_results(cols, dataframe, top):    \n",
-    "    return display_as_html_table(cols, dataframe, top)\n",
-    "    \n",
-    "def display_bytes_results(cols, dataframe, top):\n",
-    "    return display_as_html_table(cols, dataframe, top)\n",
+    "def display_results(cols, dataframe, top):    \n",
+    "    return display_as_html_table(cols, dataframe, top) \n",
     "\n",
     "def display_as_html_table(cols, dataframe, top):\n",
     "    table = dataframe[:top].to_html(classes='table table-striped table-bordered table-hover', columns=cols, index=False)\n",
@@ -730,7 +738,18 @@
     "    threat_fw.write(content)\n",
     "    threat_fw.close()\n",
     "    return \"\"\n",
+    "\n",
     "    \n",
+    "def get_top_bytes(conns_dict, top):\n",
+    "    topbytes = sorted(conns_dict.iteritems(), key=lambda (x,y): y['maxbytes'], reverse=True)\n",
+    "    topbytes = topbytes[0:top]\n",
+    "    return dict(topbytes)\n",
+    "\n",
+    "\n",
+    "def get_top_conns(conns_dict, top):    \n",
+    "    topconns = sorted(conns_dict.iteritems(), key=lambda (x,y): y['conns'], reverse=True)\n",
+    "    topconns = topconns[0:top]\n",
+    "    return dict(topconns)\n",
     "    \n",
     "def file_is_empty(path):\n",
     "    return os.stat(path).st_size==0\n",


[35/50] [abbrv] incubator-spot git commit: Keep font size for internal ips on netflow's suspicious frame (#156)

Posted by ev...@apache.org.
Keep font size for internal ips on netflow's suspicious frame (#156)



Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/1f8e46e9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/1f8e46e9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/1f8e46e9

Branch: refs/heads/master
Commit: 1f8e46e964ce89f3ad3ba31117808a7935e9ea3d
Parents: 88a2dda
Author: daortizh <di...@intel.com>
Authored: Thu Dec 1 11:34:56 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Thu Dec 1 11:34:56 2016 -0600

----------------------------------------------------------------------
 spot-oa/ui/css/bootstrap-spot-theme.less        |  7 ++++++
 spot-oa/ui/css/bootstrap-spot.min.css           |  1 +
 .../flow/js/components/SuspiciousPanel.react.js | 26 ++++++--------------
 3 files changed, 15 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/1f8e46e9/spot-oa/ui/css/bootstrap-spot-theme.less
----------------------------------------------------------------------
diff --git a/spot-oa/ui/css/bootstrap-spot-theme.less b/spot-oa/ui/css/bootstrap-spot-theme.less
index b6c325d..05f4b55 100644
--- a/spot-oa/ui/css/bootstrap-spot-theme.less
+++ b/spot-oa/ui/css/bootstrap-spot-theme.less
@@ -142,6 +142,13 @@
 }
 
 /*****************************************
+ **            Spot Suspicious          **
+ *****************************************/
+.spot-grid-panel .label {
+  font-size: 100%;
+}
+
+/*****************************************
  **          Spot Network View          **
  *****************************************/
 .edge {

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/1f8e46e9/spot-oa/ui/css/bootstrap-spot.min.css
----------------------------------------------------------------------
diff --git a/spot-oa/ui/css/bootstrap-spot.min.css b/spot-oa/ui/css/bootstrap-spot.min.css
index 4e5b8f8..6d05096 100644
--- a/spot-oa/ui/css/bootstrap-spot.min.css
+++ b/spot-oa/ui/css/bootstrap-spot.min.css
@@ -1463,6 +1463,7 @@ td.visible-print,th.visible-print{display:table-cell!important}
 .d3-tip.ne:after{content:"\25E3";margin:-5px 0 0;top:100%;left:-4px}
 .d3-tip.se:after{content:"\25E4";top:-4px;left:-4px}
 .d3-tip.sw:after{content:"\25E5";margin:0 0 0 -5px;top:-4px;left:100%}
+.spot-grid-panel .label{font-size:100%}
 .edge{stroke-width:3px;transition:stroke .5s linear}
 .edge.active,.edge.highlight{stroke:#f7a706!important;stroke-opacity:1!important}
 .edge-faded,.faded,.node-faded{stroke-opacity:.2!important}

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/1f8e46e9/spot-oa/ui/flow/js/components/SuspiciousPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/components/SuspiciousPanel.react.js b/spot-oa/ui/flow/js/components/SuspiciousPanel.react.js
index 4857534..3cb2b2c 100755
--- a/spot-oa/ui/flow/js/components/SuspiciousPanel.react.js
+++ b/spot-oa/ui/flow/js/components/SuspiciousPanel.react.js
@@ -24,13 +24,11 @@ var SuspiciousPanel = React.createClass({
       </span>
         );
     },
-    _renderIpCell: function (keyPrefix, ip, isInternal) {
-        var internalCssCls;
-
-        internalCssCls = isInternal ? 'label label-info' : '';
+    _renderIpCell: function (keyPrefix, repClassName, ip, isInternal) {
+        const cssClassName = isInternal ? 'label label-info' : `text-${repClassName}`;
 
         return (
-            <span key={keyPrefix + '_label'} className={internalCssCls}>{ip} </span>
+            <span key={keyPrefix} className={cssClassName}>{ip}</span>
         );
     },
     /**
@@ -50,13 +48,8 @@ var SuspiciousPanel = React.createClass({
         reps = SpotUtils.parseReputation(item.srcIP_rep);
         highestRep = SpotUtils.getHighestReputation(reps);
 
-        srcIpContent = this._renderIpCell('src_' + idx, item.srcIP, +item.srcIpInternal);
-
-        return (
-            <p key={'srcIP_' + idx} className={'srcIP text-' + SpotUtils.CSS_RISK_CLASSES[highestRep]}>
-                {srcIpContent}
-            </p>
-        );
+        const repClassName = SpotUtils.CSS_RISK_CLASSES[highestRep];
+        return this._renderIpCell('src_' + idx, repClassName, item.srcIP, +item.srcIpInternal);
     },
     /**
      *  Renders the destination IP cell.
@@ -73,13 +66,8 @@ var SuspiciousPanel = React.createClass({
         reps = SpotUtils.parseReputation(item.dstIP_rep);
         highestRep = SpotUtils.getHighestReputation(reps);
 
-        dstIpContent = this._renderIpCell('dst_' + idx, item.dstIP, +item.destIpInternal);
-
-        return (
-            <p key={'dstIP_' + idx} className={'srcIP text-' + SpotUtils.CSS_RISK_CLASSES[highestRep]}>
-                {dstIpContent}
-            </p>
-        );
+        const repClassName = SpotUtils.CSS_RISK_CLASSES[highestRep];
+        return this._renderIpCell('dst_' + idx, repClassName, item.dstIP, +item.destIpInternal);
     },
     _renderInfoCell: function (keyPrefix, isInternal, geo, domain, reps) {
         if (isInternal) return [];


[46/50] [abbrv] incubator-spot git commit: Fixed: Network view panel not clearing correctly (#166)

Posted by ev...@apache.org.
Fixed: Network view panel not clearing correctly (#166)



Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/508c63e3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/508c63e3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/508c63e3

Branch: refs/heads/master
Commit: 508c63e33e9f61116465eff0969cff53bc5b1e1b
Parents: 55be285
Author: daortizh <di...@intel.com>
Authored: Wed Dec 7 17:00:01 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Wed Dec 7 17:00:01 2016 -0600

----------------------------------------------------------------------
 spot-oa/ui/dns/js/components/NetworkViewPanel.react.js   | 2 +-
 spot-oa/ui/flow/js/components/NetworkViewPanel.react.js  | 2 +-
 spot-oa/ui/js/components/PolloNetworkViewMixin.react.js  | 5 +++++
 spot-oa/ui/proxy/js/components/NetworkViewPanel.react.js | 6 +++---
 4 files changed, 10 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/508c63e3/spot-oa/ui/dns/js/components/NetworkViewPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/dns/js/components/NetworkViewPanel.react.js b/spot-oa/ui/dns/js/components/NetworkViewPanel.react.js
index b6bca9c..50bb81d 100755
--- a/spot-oa/ui/dns/js/components/NetworkViewPanel.react.js
+++ b/spot-oa/ui/dns/js/components/NetworkViewPanel.react.js
@@ -116,7 +116,7 @@ const NetworkViewPanel = React.createClass({
             state.data.maxNodes = SpotConstants.MAX_SUSPICIOUS_ROWS;
         }
 
-        this.setState(state);
+        this.replaceState(state);
     },
     _onHighlight() {
         const threat = SuspiciousStore.getHighlightedThreat();

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/508c63e3/spot-oa/ui/flow/js/components/NetworkViewPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/components/NetworkViewPanel.react.js b/spot-oa/ui/flow/js/components/NetworkViewPanel.react.js
index 6b52579..398aef8 100755
--- a/spot-oa/ui/flow/js/components/NetworkViewPanel.react.js
+++ b/spot-oa/ui/flow/js/components/NetworkViewPanel.react.js
@@ -117,7 +117,7 @@ const NetworkViewPanel = React.createClass({
             state.data.maxNodes = SpotConstants.MAX_SUSPICIOUS_ROWS;
         }
 
-        this.setState(state);
+        this.replaceState(state);
     },
     _onHighlight() {
         const threat = SuspiciousStore.getHighlightedThreat();

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/508c63e3/spot-oa/ui/js/components/PolloNetworkViewMixin.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/components/PolloNetworkViewMixin.react.js b/spot-oa/ui/js/components/PolloNetworkViewMixin.react.js
index f1dcab3..df74c04 100755
--- a/spot-oa/ui/js/components/PolloNetworkViewMixin.react.js
+++ b/spot-oa/ui/js/components/PolloNetworkViewMixin.react.js
@@ -34,6 +34,11 @@ const PolloNetworkViewMixin = {
 
         // Add and update nodes and links on every tick event from the force layout
         this.force.on('tick', () => {
+            if (this.state.loading) {
+                this.force.stop();
+                return;
+            }
+
             this.drawLinks();
             this.drawNodes();
         });

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/508c63e3/spot-oa/ui/proxy/js/components/NetworkViewPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/components/NetworkViewPanel.react.js b/spot-oa/ui/proxy/js/components/NetworkViewPanel.react.js
index 9994844..d74e670 100755
--- a/spot-oa/ui/proxy/js/components/NetworkViewPanel.react.js
+++ b/spot-oa/ui/proxy/js/components/NetworkViewPanel.react.js
@@ -249,9 +249,9 @@ var NetworkViewPanel = React.createClass({
         // Flatern data. In Store?
         var state, data, refs;
 
-        state = assign({}, {data: {}}, SuspiciousStore.getData());
+        state = assign({}, SuspiciousStore.getData());
 
-        if (!state.loading)
+        if (!state.loading && state.data)
         {
             data = {
                 id: 'spot_proxy',
@@ -358,7 +358,7 @@ var NetworkViewPanel = React.createClass({
             state.root = data;
         }
 
-        this.setState(state);
+        this.replaceState(state);
     },
     flatten: function (root) {
         var nodes = [];


[23/50] [abbrv] incubator-spot git commit: Merge pull request #150 from Open-Network-Insight/spot_oa_documentation

Posted by ev...@apache.org.
Merge pull request #150 from Open-Network-Insight/spot_oa_documentation

Updated spot documentation according to latest functionality changes

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

Branch: refs/heads/master
Commit: fb8e0b6b7e848827343a957f4db7a6f2266d07c9
Parents: 084f988 535bbcb
Author: LedaLima <ga...@intel.com>
Authored: Tue Nov 29 10:27:57 2016 -0800
Committer: GitHub <no...@github.com>
Committed: Tue Nov 29 10:27:57 2016 -0800

----------------------------------------------------------------------
 spot-oa/README.md                               |  2 +-
 spot-oa/context/README.md                       | 12 +++----
 spot-oa/oa/INSTALL.md                           |  2 +-
 spot-oa/oa/components/README.md                 |  2 +-
 spot-oa/oa/dns/README.md                        |  2 +-
 spot-oa/oa/flow/README.md                       | 38 ++++++++++----------
 spot-oa/oa/flow/ipynb_templates/EdgeNotebook.md |  4 ++-
 .../flow/ipynb_templates/ThreatInvestigation.md | 20 ++++++++---
 8 files changed, 48 insertions(+), 34 deletions(-)
----------------------------------------------------------------------



[18/50] [abbrv] incubator-spot git commit: Merge pull request #121 from Open-Network-Insight/spot_oa_hive_module

Posted by ev...@apache.org.
Merge pull request #121 from Open-Network-Insight/spot_oa_hive_module

Created a new module for OA to query using hive

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

Branch: refs/heads/master
Commit: c2b1c47ee1c78012c1fcf395dc30d7bd1c9f3c5e
Parents: 0ee9318 a8246f3
Author: LedaLima <ga...@intel.com>
Authored: Mon Nov 28 09:50:17 2016 -0800
Committer: GitHub <no...@github.com>
Committed: Mon Nov 28 09:50:17 2016 -0800

----------------------------------------------------------------------
 spot-oa/oa/components/data/hive.py | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
----------------------------------------------------------------------



[20/50] [abbrv] incubator-spot git commit: Updated spot documentation according to latest functionality changes

Posted by ev...@apache.org.
Updated spot documentation according to latest functionality changes


Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/535bbcb1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/535bbcb1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/535bbcb1

Branch: refs/heads/master
Commit: 535bbcb1be41d07677bc833610d5c2dd66522dee
Parents: ea52d12
Author: LedaLima <ll...@llimagar-mac01.local>
Authored: Mon Nov 28 15:14:39 2016 -0600
Committer: LedaLima <ll...@llimagar-mac01.local>
Committed: Mon Nov 28 15:14:39 2016 -0600

----------------------------------------------------------------------
 spot-oa/README.md                               |  2 +-
 spot-oa/context/README.md                       | 12 +++----
 spot-oa/oa/INSTALL.md                           |  2 +-
 spot-oa/oa/components/README.md                 |  2 +-
 spot-oa/oa/dns/README.md                        |  2 +-
 spot-oa/oa/flow/README.md                       | 38 ++++++++++----------
 spot-oa/oa/flow/ipynb_templates/EdgeNotebook.md |  4 ++-
 .../flow/ipynb_templates/ThreatInvestigation.md | 20 ++++++++---
 8 files changed, 48 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/535bbcb1/spot-oa/README.md
----------------------------------------------------------------------
diff --git a/spot-oa/README.md b/spot-oa/README.md
index 69cf65c..9c2a3fc 100644
--- a/spot-oa/README.md
+++ b/spot-oa/README.md
@@ -10,7 +10,7 @@ Some of the technologies used are:
  - [Bootstrap](http://getbootstrap.com/)
  - [ReactJS](https://facebook.github.io/react/)  
 
-* For more specific requirements, please refer to each specific pipeline readme file before running OA.
+* For more specific requirements, please refer to each specific pipeline readme file before running OA.*
 ----------
 
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/535bbcb1/spot-oa/context/README.md
----------------------------------------------------------------------
diff --git a/spot-oa/context/README.md b/spot-oa/context/README.md
index 7622975..e4869d2 100644
--- a/spot-oa/context/README.md
+++ b/spot-oa/context/README.md
@@ -23,18 +23,18 @@ This file is required by the following modules:
    
 Schema with zero-indexed columns:
 
-        0. IP Range start (long)
-        1. IP Range end (long)
+        0. IP Range start (string)
+        1. IP Range end (string)
         2. Country code (string)
-        3. Country (String)
+        3. Country (string)
         4. State (string)
         5. City (string)
-        6. Latitude (float)
-        7. Longitude (float)
+        6. Latitude (string)
+        7. Longitude (string)
         8. Owner or Register (string)
         9. Domain name (string)        
 
-The schema is based on the GeoIP database by [MAXMIND](https://www.maxmind.com). Either users acquire MAXMIND database or any other database or even create their own, it should always comply the schema above.
+The schema is based on the GeoIP database by [MAXMIND](https://www.maxmind.com). Either users acquire MAXMIND database or any other database or even create their own, it should always comply the schema above. This includes enclosing every field in double quotes.
 
 Ip ranges are defined by Ips converted into integers. To calculate the integer value from an IP first you need to split the string by "." into four values or octets. Then apply the following formula: (1st octet * 256^3) + (2nd octet * 256^2) + (3th octet * 256) + (4th octet).
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/535bbcb1/spot-oa/oa/INSTALL.md
----------------------------------------------------------------------
diff --git a/spot-oa/oa/INSTALL.md b/spot-oa/oa/INSTALL.md
index d779aed..22ebdbd 100644
--- a/spot-oa/oa/INSTALL.md
+++ b/spot-oa/oa/INSTALL.md
@@ -81,7 +81,7 @@ In order to execute this process there are a few prerequisites:
             
             
  3. The spot-setup project contains scripts to install the hive database and also includes the main configuration file for this tool.
-     The main file is called spot.conf and it which contains different variables that the user can set up to customize their installation. Some variables are
+     The main file is called spot.conf which contains different variables that the user can set up to customize their installation. Some variables
      must be updated in order to have spot-ml and spot-oa working.
      
      To run the OA process it's required to install spot-setup. If it's already installed just make sure the following configuration are set up in spot.conf file.

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/535bbcb1/spot-oa/oa/components/README.md
----------------------------------------------------------------------
diff --git a/spot-oa/oa/components/README.md b/spot-oa/oa/components/README.md
index aaa04de..3353493 100644
--- a/spot-oa/oa/components/README.md
+++ b/spot-oa/oa/components/README.md
@@ -30,7 +30,7 @@ This document will explain the necessary steps to configure the spot-oa componen
 _Data source module._
 
 This module needs to be configured correctly to avoid errors during the spot-oa execution. Here you need to select the correct database engine to obtain the correct results while creating additional details files.
-Currently spot-oa is prepared to work with Impala, but you can always configure any other database engine and make the corresponding updates in the code.
+Currently spot-oa includes the modules to work with either Hive or Impala. By default is set to work with Impala, but you can always configure any other database engine, create the corresponding python module and make the corresponding changes in the code.
 
 **Configuration**
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/535bbcb1/spot-oa/oa/dns/README.md
----------------------------------------------------------------------
diff --git a/spot-oa/oa/dns/README.md b/spot-oa/oa/dns/README.md
index 3906563..aab8673 100644
--- a/spot-oa/oa/dns/README.md
+++ b/spot-oa/oa/dns/README.md
@@ -96,7 +96,7 @@ Before running DNS OA users need to configure components for the first time. It
 - dns_scores_bu.csv: The backup file of suspicious connects in case user wants to roll back any changes made during analysis. Schema is same as dns_scores.csv.
 
 
-- dendro-\<DNS query name>.csv: One file for each source IP. This file includes information about all the queries made to a particular DNS query name. 
+- dendro-\<DNS query name>.csv: One file for each source IP. This file includes information about all the queries made to a particular DNS query name. The number of retrieved rows is limited by the value of "\_details\_limit" parameter
 
 		Schema with zero-indexed columns:
 		

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/535bbcb1/spot-oa/oa/flow/README.md
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/README.md b/spot-oa/oa/flow/README.md
index 242a622..4b3dbc1 100644
--- a/spot-oa/oa/flow/README.md
+++ b/spot-oa/oa/flow/README.md
@@ -58,20 +58,22 @@ Before running Flow OA users need to configure components for the first time. It
         4.   sport:          int
         5.   dport:          int
         6.   proto:          string
-        7.   flag:           string
-        8.   ipkt:           bigint
-        9.   ibyt:           bigint
-        10.  lda_score:      double
-        11.  rank:           int
-        12.  srcIpInternal:  bit
-        13.  destIpInternal: bit
-        14.  srcGeo:         string
-        15.  dstGeo:         string
-        16.  srcDomain:      string
-        17.  dstDomain:      string
-        18.  srcIP_rep:      string
-        29.  dstIP_rep:      string
-       
+        7.   ipkt:           bigint
+        8.   ibyt:           bigint
+        9.   opkt:           bigint
+        10.  obyt:           bigint
+        11.  score:          double
+        12.  rank:           int
+        13.  srcIpInternal:  bit
+        14.  destIpInternal: bit
+        15.  srcGeo:         string
+        16.  dstGeo:         string
+        17.  srcDomain:      string
+        18.  dstDomain:      string
+        19.  srcIP_rep:      string
+        20.  dstIP_rep:      string
+
+
 - flow_scores_bu.csv. Backup file for flow_scores.csv in case user needs to roll back the scoring or the changes made during analysis. Schema it's same as flow_scores.csv.
 
 - edge-\<source IP>-\<destination IP>-\<HH>-\<MM>.tsv. Edge files. One for each suspicious connection containing the details for each comunication occurred during the same specific minute between source IP and destination IP.
@@ -91,15 +93,13 @@ Before running Flow OA users need to configure components for the first time. It
         11. output:     int
         12. rip:        string
 
-- chord-\<client ip>.tsv. Chord files. One for each distinct client ip. These files contain details of packets and data transferred between the client ip and every other IP it connected to.
+- chord-\<client ip>.tsv. Chord files. One for each distinct client ip. These files contain the sum of input packets and bytes transferred between the client ip and every other IP it connected to.
 
         Schema with zero-indexed columns:
         0.  srcip:      string
         1.  dstip:      string
-        2.  maxbyte:    bigint
-        3.  avgbyte:    double
-        4.  maxpkt:     bigint
-        5.  avgpkt:     double
+        2.  ibytes:     bigint
+        3.  ipkts:      double
         
 ### flow_config.json
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/535bbcb1/spot-oa/oa/flow/ipynb_templates/EdgeNotebook.md
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/ipynb_templates/EdgeNotebook.md b/spot-oa/oa/flow/ipynb_templates/EdgeNotebook.md
index f879cc0..272e2bc 100644
--- a/spot-oa/oa/flow/ipynb_templates/EdgeNotebook.md
+++ b/spot-oa/oa/flow/ipynb_templates/EdgeNotebook.md
@@ -67,7 +67,7 @@ Each of these lists will populate a listbox widget and then they will be display
 
 `apply_css_to_select(select)` - Defines a set of css styles that can be applied to any listbox widget. 
 
-`update_sconnects(list_control,source):` -   
+`update_sconnects(b):` -   
 This function is executed on the onclick event of the \u2018Assign\u2019 button. The notebook will first try to get the value from the 'Quick IP Scoring' textbox ignoring the selections from the listboxes; in case the textbox is empty, it will then
  get the selected values from each of the listboxes to look them up in the `flow_scores.csv` file. 
 A binary search on the file is then performed:  
@@ -82,6 +82,8 @@ The scored rows will also be appended to the `flow_scores_fb.csv` file, which wi
 
 `set_rules():` - Predefined function where the user can define custom rules to be initally applied to the dataset. By default this function is commented out.
 
+`create_feedback_file(scored_rows):` - Appends the updated rows to the _flow_scores_fb.csv_ everytime a connection is scored. This file is used as feedback for the ML process.
+
 `apply_rules(rops,rvals,risk):` - This function applies the rules defined by `set_rules()` and updates the `flow_scores.csv` file following a similar process to the `update_sconnects()` function. By default this function is commented out.
 
 `attack_heuristics():` - This function is executed at the start, and loads the data from `flow_scores.csv` into a pandas dataframe grouped by `srcIp` column,

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/535bbcb1/spot-oa/oa/flow/ipynb_templates/ThreatInvestigation.md
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/ipynb_templates/ThreatInvestigation.md b/spot-oa/oa/flow/ipynb_templates/ThreatInvestigation.md
index 561f7a9..fdbcad0 100644
--- a/spot-oa/oa/flow/ipynb_templates/ThreatInvestigation.md
+++ b/spot-oa/oa/flow/ipynb_templates/ThreatInvestigation.md
@@ -174,7 +174,7 @@ This is not a function, but more like global code to set up styles and widgets t
 `start_investigation():` - This function cleans the notebook from previous executions, then loops through the _flow_scores.csv_ file to get the 'srcIp' and 'dstIP' values from connections scored as high risk (sev = 1), ignoring IPs
 already saved in the _threats.csv_ file. 
 
-`display_controls():` - This function will display the ipython widgets with the listbox of high risk IP's and the "Search" button.
+`display_controls(threat_list):` - This function will display the ipython widgets with the listbox of high risk IP's and the "Search" button.
 
 `search_ip()` - This function is triggered by the onclick event of the "Search" button after selecting an IP from the listbox. This will perform a query to the _flow_ table to find all connections involving the selected IP.
  The results are stored in the _ir-\<ip>.tsv_ file. If the file is not empty, this will immediately execute the following functions:  
@@ -187,9 +187,15 @@ already saved in the _threats.csv_ file.
 - All unique \u2018inbound\u2019 connected IP's (Where the internal sought IP appears only as destination, or the opposite if the IP is external)  
 - All unique \u2018outbound\u2019 connected IP's (Where the internal sought IP appears only as source, or the opposite if the IP is external)
 - All unique \u2018two way\u2019 connected IP's (Where the sought IP appears as both source and destination)
-This function will also call the _get_top_bytes()_ and _get_top_conns()_ functions to create sub dictionaries for each type of connection. 
+This function will also call the _get_top_bytes()_ and _get_top_conns()_ functions to create sub dictionaries for each type of connection and use those to generate the storyboard.
+To aid on the analysis, this function displays four html tables each containing the following data:
+- Top n source IP by connections
+- Top n source IP per bytes transfered
+- Top n destination IP by connections
+- Top n destination IP per bytes transfered
 
-`display_threat_box(anchor):` - Displays the widgets for "Title", "Comments" textboxes and the "Save" button on the notebook, so the user can add comments related to the threat and save them to continue with the analysis.  
+
+`display_threat_box(ip):` - Displays the widgets for "Title", "Comments" textboxes and the "Save" button on the notebook, so the user can add comments related to the threat and save them to continue with the analysis.  
 
 `add_network_context()` - This function depends on the existence of the _networkcontext\_1.csv_ file, otherwise this step will be skipped.
 This function will loop through all dictionaries updating each IP with its context depending on the ranges defined in the networkcontext.
@@ -204,6 +210,12 @@ This function will loop through all dictionaries updating each IP with its conte
 - details_inbound()
 - add_threat() 
 
+`display_results(cols, dataframe, top)` - 
+*cols*: List of columns to display from the dataframe
+*dataframe*: Dataframe to display
+*top*: Number of top rows to display.
+This function will create a formatted html table to display the provided dataframe.
+
 `generate_attack_map_file(ip, inbound, outbound, twoway): `- This function depends on the existence of the _iploc.csv_ file. Using the geospatial info previously added to the dictionaries, this function will create the _globe.json_ file. If the iploc file doesn't exist, this function will be skipped.
 
 `generate_stats(ip, inbound, outbound, twoway, threat_name):` - This function reads through each of the dictionaries to group the connections by type. The results are stored in the _stats-&lt;ip&gt;.json_ file. 
@@ -211,7 +223,7 @@ This function will loop through all dictionaries updating each IP with its conte
 `generate_dendro(ip, inbound, outbound, twoway, date):` - This function groups the results from all three dictionaries into a json file, adding additionals level if the dictionaries include network context for each IP. 
 The results are stored in the _threat-dendro-&lt;ip&gt;.json_ file.
 
-`details_inbound(ip, inbound):` -  This function executes a query to the _flow_ table looking for all additional information between the shought IP (threat) and the IP's in the 'top_n' dictionaries. The results will be stored in the _sbdet-&lt;ip&gt;.tsv_ file.
+`details_inbound(anchor, inbound, outbond, twoway):` -  This function executes a query to the _flow_ table looking for all additional information between the shought IP (threat) and the IP's in the 'top_n' dictionaries. The results will be stored in the _sbdet-&lt;ip&gt;.tsv_ file.
  
 `add_threat(ip,threat_title):`- Creates or updates the _threats.csv_ file, appending the IP and Title from the web form. This will serve as the menu for the Story Board.
 


[29/50] [abbrv] incubator-spot git commit: Adding ingest summary call to OA

Posted by ev...@apache.org.
Adding ingest summary call to OA


Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/7374c4c5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/7374c4c5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/7374c4c5

Branch: refs/heads/master
Commit: 7374c4c55823839ee6b59fcf142afba8699c7ad9
Parents: 8b508e1
Author: elopezsa <ev...@intel.com>
Authored: Wed Nov 30 16:13:43 2016 -0600
Committer: elopezsa <ev...@intel.com>
Committed: Wed Nov 30 16:13:43 2016 -0600

----------------------------------------------------------------------
 spot-oa/oa/flow/flow_oa.py | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/7374c4c5/spot-oa/oa/flow/flow_oa.py
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/flow_oa.py b/spot-oa/oa/flow/flow_oa.py
index eb3aaf0..d40515d 100644
--- a/spot-oa/oa/flow/flow_oa.py
+++ b/spot-oa/oa/flow/flow_oa.py
@@ -66,6 +66,7 @@ class OA(object):
         self._add_reputation()        
         self._create_flow_scores_csv()
         self._get_oa_details()
+        self._ingest_summary()
 
         ##################
         end = time.time()


[41/50] [abbrv] incubator-spot git commit: Spark lda only (#159)

Posted by ev...@apache.org.
Spark lda only (#159)

* Juliasantos/spark lda (#132)

* changes requested to spark/lda-c, wrapped both so there is no if/else in individual flow/dns/proxy, etc.

adjusted topicConcentration to 1.001 and documentConcentration to 0.02

spark LDA works on unit tests and simple suspicious connects smoke tests

changes
* normalization of the topic matrix that comes out of Spark LDA

* transposition of the same topic matrix (previous access was off because LDA returns matrix in column-major order not row-major order)

* set default  alpha and beta to have much tighter document and topic concentration

ml_ops and ml_test use sparkLDA by default in this branch

* Removing unnecessary collect at SpotSparkLDAWrapper -> document results.

* Reverting experimental change.

* Removed .show().

* Changing document dictionary to use data frame and avoid collect.

* Removing dead code

* Main change: removed parameter for optimization leaving EMLDAOptimizer as default. Also changing variable names for SpotLDASchema to make more sense.

* Updating schema to match with constant name WordNumber = 'word_number'

Removed MPI LDA path from suspicious connects analyses.

Removed MPI settings from spot.conf

put lda in a package, cleaned up some argument names and eliminated default values for some scala methods


Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/39a376c8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/39a376c8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/39a376c8

Branch: refs/heads/master
Commit: 39a376c815122b9039b04f2aa9382dd9f7b0612d
Parents: f9b8e11
Author: NathanSegerlind <na...@intel.com>
Authored: Mon Dec 5 15:24:23 2016 -0800
Committer: Ricardo Barona <ri...@intel.com>
Committed: Mon Dec 5 17:24:23 2016 -0600

----------------------------------------------------------------------
 spot-ml/ml_ops.sh                               |  22 +-
 spot-ml/ml_test.sh                              |  82 ++++++
 .../org/apache/spot/SuspiciousConnects.scala    |   4 +-
 .../spot/SuspiciousConnectsArgumentParser.scala |  78 ++---
 .../dns/model/DNSSuspiciousConnectsModel.scala  |  39 +--
 .../org/apache/spot/lda/SpotLDAWrapper.scala    | 192 ++++++++++++
 .../apache/spot/lda/SpotLDAWrapperSchema.scala  |  22 ++
 .../model/FlowSuspiciousConnectsModel.scala     |  40 +--
 .../proxy/ProxySuspiciousConnectsModel.scala    |  55 ++--
 .../spot/spotldacwrapper/SpotLDACInput.scala    |   6 -
 .../spot/spotldacwrapper/SpotLDACOutput.scala   |   7 -
 .../spot/spotldacwrapper/SpotLDACSchema.scala   |  21 --
 .../spot/spotldacwrapper/SpotLDACWrapper.scala  | 292 -------------------
 .../org/apache/spot/SpotLDACWrapperTest.scala   | 189 ------------
 .../apache/spot/SpotLDACWrapperTest.scala.tmp   | 166 -----------
 .../org/apache/spot/SpotLDAWrapperTest.scala    | 140 +++++++++
 spot-setup/spot.conf                            |  11 -
 17 files changed, 514 insertions(+), 852 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-ml/ml_ops.sh
----------------------------------------------------------------------
diff --git a/spot-ml/ml_ops.sh b/spot-ml/ml_ops.sh
index 8faef3b..244bcc4 100755
--- a/spot-ml/ml_ops.sh
+++ b/spot-ml/ml_ops.sh
@@ -78,13 +78,6 @@ rm -f ${LPATH}/*.{dat,beta,gamma,other,pkl} # protect the flow_scores.csv file
 
 hdfs dfs -rm -R -f ${HDFS_SCORED_CONNECTS}
 
-# Add -p <command> to execute pre MPI command.
-# Pre MPI command can be configured in /etc/spot.conf
-# In this script, after the line after --mpicmd ${MPI_CMD} add:
-# --mpiprep ${MPI_PREP_CMD}
-
-${MPI_PREP_CMD}
-
 time spark-submit --class "org.apache.spot.SuspiciousConnects" \
   --master yarn-client \
   --driver-memory ${SPK_DRIVER_MEM} \
@@ -103,20 +96,11 @@ time spark-submit --class "org.apache.spot.SuspiciousConnects" \
   --input ${RAWDATA_PATH}  \
   --dupfactor ${DUPFACTOR} \
   --feedback ${FEEDBACK_PATH} \
-  --model ${LPATH}/model.dat \
-  --topicdoc ${LPATH}/final.gamma \
-  --topicword ${LPATH}/final.beta \
-  --lpath ${LPATH} \
-  --ldapath ${LDAPATH} \
-  --luser ${LUSER} \
-  --mpicmd ${MPI_CMD}  \
-  --proccount ${PROCESS_COUNT} \
-  --topiccount ${TOPIC_COUNT} \
-  --nodes ${nodes} \
+  --ldatopiccount ${TOPIC_COUNT} \
   --scored ${HDFS_SCORED_CONNECTS} \
-  --tempmodel ${HDFS_MODEL} \
   --threshold ${TOL} \
-  --maxresults ${MAXRESULTS}
+  --maxresults ${MAXRESULTS} \
+  --ldamaxiterations 20
 
 wait
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-ml/ml_test.sh
----------------------------------------------------------------------
diff --git a/spot-ml/ml_test.sh b/spot-ml/ml_test.sh
new file mode 100755
index 0000000..653d276
--- /dev/null
+++ b/spot-ml/ml_test.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+
+# parse and validate arguments
+
+DSOURCE=$1
+RAWDATA_PATH=$2
+
+# read in variables (except for date) from etc/.conf file
+
+source /etc/spot.conf
+
+# third argument if present will override default TOL from conf file
+
+TOL=1.1
+MAXRESULTS=20
+
+LPATH=${LUSER}/ml/${DSOURCE}/test
+HPATH=${HUSER}/${DSOURCE}/test/scored_results
+# prepare parameters pipeline stages
+
+
+FEEDBACK_PATH=${LPATH}/${DSOURCE}_scores.csv
+DUPFACTOR=1000
+
+HDFS_WORDCOUNTS=${HPATH}/word_counts
+
+# paths for intermediate files
+HDFS_DOCRESULTS=${HPATH}/doc_results.csv
+LOCAL_DOCRESULTS=${LPATH}/doc_results.csv
+
+HDFS_WORDRESULTS=${HPATH}/word_results.csv
+LOCAL_WORDRESULTS=${LPATH}/word_results.csv
+
+HDFS_SCORED_CONNECTS=${HPATH}/scores
+HDFS_MODEL=${HPATH}/model
+
+LDA_OUTPUT_DIR=test/${DSOURCE}
+
+TOPIC_COUNT=20
+
+nodes=${NODES[0]}
+for n in "${NODES[@]:1}" ; do nodes+=",${n}"; done
+
+hdfs dfs -rm -R -f ${HDFS_WORDCOUNTS}
+wait
+
+mkdir -p ${LPATH}
+rm -f ${LPATH}/*.{dat,beta,gamma,other,pkl} # protect the flow_scores.csv file
+
+hdfs dfs -rm -R -f ${HDFS_SCORED_CONNECTS}
+
+time spark-submit --class "org.apache.spot.SuspiciousConnects" \
+  --master yarn-client \
+  --driver-memory ${SPK_DRIVER_MEM} \
+  --conf spark.driver.maxResultSize=${SPK_DRIVER_MAX_RESULTS} \
+  --conf spark.driver.maxPermSize=512m \
+  --conf spark.driver.cores=1 \
+  --conf spark.dynamicAllocation.enabled=true \
+  --conf spark.dynamicAllocation.minExecutors=1 \
+  --conf spark.dynamicAllocation.maxExecutors=${SPK_EXEC} \
+  --conf spark.executor.cores=${SPK_EXEC_CORES} \
+  --conf spark.executor.memory=${SPK_EXEC_MEM} \
+  --conf "spark.executor.extraJavaOptions=-XX:MaxPermSize=512M -XX:PermSize=512M" \
+  --conf spark.shuffle.io.preferDirectBufs=false    \
+  --conf spark.kryoserializer.buffer.max=512m \
+  --conf spark.shuffle.service.enabled=true \
+  --conf spark.yarn.am.waitTime=1000000 \
+  --conf spark.yarn.driver.memoryOverhead=${SPK_DRIVER_MEM_OVERHEAD} \
+  --conf spark.yarn.executor.memoryOverhead=${SPAK_EXEC_MEM_OVERHEAD} target/scala-2.10/spot-ml-assembly-1.1.jar \
+  --analysis ${DSOURCE} \
+  --input ${RAWDATA_PATH}  \
+  --dupfactor ${DUPFACTOR} \
+  --feedback ${FEEDBACK_PATH} \
+  --ldatopiccount ${TOPIC_COUNT} \
+  --scored ${HDFS_SCORED_CONNECTS} \
+  --threshold ${TOL} \
+  --maxresults ${MAXRESULTS} \
+  --ldamaxiterations 11
+
+cd ${LPATH}
+hadoop fs -getmerge ${HDFS_SCORED_CONNECTS}/part-* ${DSOURCE}_results.csv && hadoop fs -moveFromLocal \
+    ${DSOURCE}_results.csv  ${HDFS_SCORED_CONNECTS}/${DSOURCE}_results.csv
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-ml/src/main/scala/org/apache/spot/SuspiciousConnects.scala
----------------------------------------------------------------------
diff --git a/spot-ml/src/main/scala/org/apache/spot/SuspiciousConnects.scala b/spot-ml/src/main/scala/org/apache/spot/SuspiciousConnects.scala
index f0ac04d..8751189 100644
--- a/spot-ml/src/main/scala/org/apache/spot/SuspiciousConnects.scala
+++ b/spot-ml/src/main/scala/org/apache/spot/SuspiciousConnects.scala
@@ -19,8 +19,6 @@ import org.apache.spot.proxy.ProxySuspiciousConnectsAnalysis
 
 object SuspiciousConnects {
 
-  val OutputDelimiter = "\t"
-
   /**
     * Execute suspicious connections analysis on network data.
     *
@@ -43,7 +41,7 @@ object SuspiciousConnects {
         val sparkConfig = new SparkConf().setAppName("Spot ML:  " + analysis + " suspicious connects analysis")
         val sparkContext = new SparkContext(sparkConfig)
         val sqlContext = new SQLContext(sparkContext)
-        implicit val outputDelimiter = OutputDelimiter
+        implicit val outputDelimiter = config.outputDelimiter
 
         analysis match {
           case "flow" => FlowSuspiciousConnectsAnalysis.run(config, sparkContext, sqlContext, logger)

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-ml/src/main/scala/org/apache/spot/SuspiciousConnectsArgumentParser.scala
----------------------------------------------------------------------
diff --git a/spot-ml/src/main/scala/org/apache/spot/SuspiciousConnectsArgumentParser.scala b/spot-ml/src/main/scala/org/apache/spot/SuspiciousConnectsArgumentParser.scala
index b1d5cdd..33186c5 100644
--- a/spot-ml/src/main/scala/org/apache/spot/SuspiciousConnectsArgumentParser.scala
+++ b/spot-ml/src/main/scala/org/apache/spot/SuspiciousConnectsArgumentParser.scala
@@ -8,25 +8,17 @@ object SuspiciousConnectsArgumentParser {
 
   case class SuspiciousConnectsConfig(analysis: String = "",
                                       inputPath: String = "",
-                                      scoresFile: String = "",
+                                      feedbackFile: String = "",
                                       duplicationFactor: Int = 1,
-                                      modelFile: String = "",
-                                      topicDocumentFile: String = "",
-                                      topicWordFile: String = "",
-                                      mpiPreparationCmd: String = "",
-                                      mpiCmd: String = "",
-                                      mpiProcessCount: String = "",
                                       topicCount: Int = 20,
-                                      localPath: String = "",
-                                      localUser: String = "",
-                                      ldaPath: String = "",
-                                      nodes: String = "",
                                       hdfsScoredConnect: String = "",
-                                      hdfsModelFile: String = "",
                                       threshold: Double = 1.0d,
                                       maxResults: Int = -1,
                                       outputDelimiter: String = "\t",
-                                      ldaPRGSeed: Option[Long] = None)
+                                      ldaPRGSeed: Option[Long] = None,
+                                      ldaMaxiterations: Int = 20,
+                                      ldaAlpha: Double = 1.02,
+                                      ldaBeta: Double = 1.001)
 
   val parser: scopt.OptionParser[SuspiciousConnectsConfig] = new scopt.OptionParser[SuspiciousConnectsConfig]("LDA") {
 
@@ -41,65 +33,22 @@ object SuspiciousConnectsArgumentParser {
       text("HDFS path to input")
 
     opt[String]("feedback").valueName("<local file>").
-      action((x, c) => c.copy(scoresFile = x)).
+      action((x, c) => c.copy(feedbackFile = x)).
       text("the local path of the file that contains the feedback scores")
 
     opt[Int]("dupfactor").valueName("<non-negative integer>").
       action((x, c) => c.copy(duplicationFactor = x)).
       text("duplication factor controlling how to downgrade non-threatening connects from the feedback file")
 
-    opt[String]("model").required().valueName("<local file>").
-      action((x, c) => c.copy(modelFile = x)).
-      text("Model file location")
 
-    opt[String]("topicdoc").required().valueName("<local file>").
-      action((x, c) => c.copy(topicDocumentFile = x)).
-      text("final.gamma file location")
-
-    opt[String]("topicword").required().valueName("<local file>").
-      action((x, c) => c.copy(topicWordFile = x)).
-      text("final.beta file location")
-
-    opt[String]("mpiprep").valueName("<mpi command>").
-      action((x, c) => c.copy(mpiPreparationCmd = x)).
-      text("MPI preparation command")
-
-    opt[String]("mpicmd").required().valueName("<mpi command>").
-      action((x, c) => c.copy(mpiCmd = x)).
-      text("MPI command")
-
-    opt[String]("proccount").required().valueName("<mpi param>").
-      action((x, c) => c.copy(mpiProcessCount = x)).
-      text("MPI process count")
-
-    opt[String]("topiccount").required().valueName("number of topics in topic model").
+    opt[String]("ldatopiccount").required().valueName("number of topics in topic model").
       action((x, c) => c.copy(topicCount = x.toInt)).
       text("topic count")
 
-    opt[String]("lpath").required().valueName("<local path>").
-      action((x, c) => c.copy(localPath = x)).
-      text("Local Path")
-
-    opt[String]("ldapath").required().valueName("<local path>").
-      action((x, c) => c.copy(ldaPath = x)).
-      text("LDA Path")
-
-    opt[String]("luser").required().valueName("<local path>").
-      action((x, c) => c.copy(localUser = x)).
-      text("Local user path")
-
-    opt[String]("nodes").required().valueName("<input param>").
-      action((x, c) => c.copy(nodes = x)).
-      text("Node list")
-
     opt[String]("scored").required().valueName("<hdfs path>").
       action((x, c) => c.copy(hdfsScoredConnect = x)).
       text("HDFS path for results")
 
-    opt[String]("tempmodel").required().valueName("<hdfs path>").
-      action((x, c) => c.copy(hdfsModelFile = x)).
-      text("HDFS path for model (temporary location)")
-
     opt[Double]("threshold").required().valueName("float64").
       action((x, c) => c.copy(threshold = x)).
       text("probability threshold for declaring anomalies")
@@ -115,5 +64,18 @@ object SuspiciousConnectsArgumentParser {
     opt[String]("prgseed").optional().valueName("long").
       action((x, c) => c.copy(ldaPRGSeed = Some(x.toLong))).
       text("seed for the pseudorandom generator")
+
+    opt[Int]("ldamaxiterations").optional().valueName("int").
+      action((x, c) => c.copy(ldaMaxiterations = x)).
+      text("maximum number of iterations used in LDA")
+
+
+    opt[Double]("ldaalpha").optional().valueName("float64").
+      action((x, c) => c.copy(ldaAlpha = x)).
+      text("document concentration for lda, default 1.02")
+
+    opt[Double]("ldabeta").optional().valueName("float64").
+      action((x, c) => c.copy(ldaBeta = x)).
+      text("topic concentration for lda, default 1.001")
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-ml/src/main/scala/org/apache/spot/dns/model/DNSSuspiciousConnectsModel.scala
----------------------------------------------------------------------
diff --git a/spot-ml/src/main/scala/org/apache/spot/dns/model/DNSSuspiciousConnectsModel.scala b/spot-ml/src/main/scala/org/apache/spot/dns/model/DNSSuspiciousConnectsModel.scala
index aa1cba6..81c214f 100644
--- a/spot-ml/src/main/scala/org/apache/spot/dns/model/DNSSuspiciousConnectsModel.scala
+++ b/spot-ml/src/main/scala/org/apache/spot/dns/model/DNSSuspiciousConnectsModel.scala
@@ -1,19 +1,19 @@
 package org.apache.spot.dns.model
 
+import org.apache.log4j.Logger
 import org.apache.spark.SparkContext
 import org.apache.spark.broadcast.Broadcast
 import org.apache.spark.rdd.RDD
 import org.apache.spark.sql.functions._
 import org.apache.spark.sql.types._
 import org.apache.spark.sql.{DataFrame, Row, SQLContext}
-import org.apache.spot.spotldacwrapper.{SpotLDACInput, SpotLDACOutput}
 import org.apache.spot.SuspiciousConnectsArgumentParser.SuspiciousConnectsConfig
 import org.apache.spot.dns.DNSSchema._
 import org.apache.spot.dns.DNSWordCreation
-import org.apache.spot.utilities.{CountryCodes, DomainProcessor, Quantiles, TopDomains}
+import org.apache.spot.lda.SpotLDAWrapper
+import org.apache.spot.lda.SpotLDAWrapper.{SpotLDAInput, SpotLDAOutput}
 import org.apache.spot.utilities.DomainProcessor.DomainInfo
-import org.apache.log4j.Logger
-import org.apache.spot.spotldacwrapper.SpotLDACWrapper
+import org.apache.spot.utilities.{CountryCodes, DomainProcessor, Quantiles, TopDomains}
 
 
 /**
@@ -153,7 +153,7 @@ object DNSSuspiciousConnectsModel {
 
     val totalDataDF = selectedDF.unionAll(DNSFeedback.loadFeedbackDF(sparkContext,
       sqlContext,
-      config.scoresFile,
+      config.feedbackFile,
       config.duplicationFactor))
 
     val countryCodesBC = sparkContext.broadcast(CountryCodes.CountryCodes)
@@ -178,7 +178,6 @@ object DNSSuspiciousConnectsModel {
     val numberPeriodsCuts = Quantiles.computeQuintiles(domainStatsDF.filter(NumPeriods + " > 0")
       .select(NumPeriods).rdd.map({ case Row(numberPeriods: Int) => numberPeriods.toDouble }))
 
-
     // simplify DNS log entries into "words"
 
     val dnsWordCreator = new DNSWordCreation(frameLengthCuts, timeCuts, subdomainLengthCuts, entropyCuts, numberPeriodsCuts, topDomainsBC)
@@ -186,31 +185,21 @@ object DNSSuspiciousConnectsModel {
     val dataWithWordDF = totalDataDF.withColumn(Word, dnsWordCreator.wordCreationUDF(modelColumns: _*))
 
     // aggregate per-word counts at each IP
-
     val ipDstWordCounts =
       dataWithWordDF.select(ClientIP, Word).map({ case Row(destIP: String, word: String) => (destIP, word) -> 1 })
         .reduceByKey(_ + _)
-        .map({ case ((ipDst, word), count) => SpotLDACInput(ipDst, word, count) })
+        .map({ case ((ipDst, word), count) => SpotLDAInput(ipDst, word, count) })
 
 
-    val SpotLDACOutput(ipToTopicMixDF, wordToPerTopicProb) = SpotLDACWrapper.runLDA(ipDstWordCounts,
-      config.modelFile,
-      config.hdfsModelFile,
-      config.topicDocumentFile,
-      config.topicWordFile,
-      config.mpiPreparationCmd,
-      config.mpiCmd,
-      config.mpiProcessCount,
+    val SpotLDAOutput(ipToTopicMixDF, wordToPerTopicProb) = SpotLDAWrapper.runLDA(sparkContext,
+      sqlContext,
+      ipDstWordCounts,
       config.topicCount,
-      config.localPath,
-      config.ldaPath,
-      config.localUser,
-      config.analysis,
-      config.nodes,
+      logger,
       config.ldaPRGSeed,
-      sparkContext,
-      sqlContext,
-      logger)
+      config.ldaAlpha,
+      config.ldaBeta,
+      config.ldaMaxiterations)
 
     // Since DNS is still broadcasting ip to topic mix, we need to convert data frame to Map[String, Array[Double]]
     val ipToTopicMix = ipToTopicMixDF
@@ -223,6 +212,7 @@ object DNSSuspiciousConnectsModel {
       .collectAsMap
       .toMap
 
+
     new DNSSuspiciousConnectsModel(topicCount,
       ipToTopicMix,
       wordToPerTopicProb,
@@ -231,6 +221,7 @@ object DNSSuspiciousConnectsModel {
       subdomainLengthCuts,
       numberPeriodsCuts,
       entropyCuts)
+
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-ml/src/main/scala/org/apache/spot/lda/SpotLDAWrapper.scala
----------------------------------------------------------------------
diff --git a/spot-ml/src/main/scala/org/apache/spot/lda/SpotLDAWrapper.scala b/spot-ml/src/main/scala/org/apache/spot/lda/SpotLDAWrapper.scala
new file mode 100644
index 0000000..8ae74e8
--- /dev/null
+++ b/spot-ml/src/main/scala/org/apache/spot/lda/SpotLDAWrapper.scala
@@ -0,0 +1,192 @@
+package org.apache.spot.lda
+
+import org.apache.log4j.Logger
+import org.apache.spark.SparkContext
+import org.apache.spark.mllib.clustering.{DistributedLDAModel, EMLDAOptimizer, LDA}
+import org.apache.spark.mllib.linalg.{Matrix, Vector, Vectors}
+import org.apache.spark.rdd.RDD
+import org.apache.spark.sql.functions._
+import org.apache.spark.sql.{DataFrame, Row, SQLContext}
+
+import SpotLDAWrapperSchema._
+
+import scala.collection.immutable.Map
+
+/**
+  * Spark LDA implementation
+  * Contains routines for LDA using Scala Spark implementation from mllib
+  * 1. Creates list of unique documents, words and model based on those two
+  * 2. Processes the model using Spark LDA
+  * 3. Reads Spark LDA results: Topic distributions per document (docTopicDist) and word distributions per topic (wordTopicMat)
+  * 4. Convert wordTopicMat (Matrix) and docTopicDist (RDD) to appropriate formats (maps) originally specified in LDA-C
+  */
+
+object SpotLDAWrapper {
+
+  case class SpotLDAInput(doc: String, word: String, count: Int) extends Serializable
+
+  case class SpotLDAOutput(docToTopicMix: DataFrame, wordResults: Map[String, Array[Double]])
+
+
+  def runLDA(sparkContext: SparkContext,
+             sqlContext: SQLContext,
+             docWordCount: RDD[SpotLDAInput],
+             topicCount: Int,
+             logger: Logger,
+             ldaSeed: Option[Long],
+             ldaAlpha: Double,
+             ldaBeta: Double,
+             maxIterations: Int): SpotLDAOutput = {
+
+    import sqlContext.implicits._
+
+    val docWordCountCache = docWordCount.cache()
+
+    // Forcing an action to cache results.
+    docWordCountCache.count()
+
+    // Create word Map Word,Index for further usage
+    val wordDictionary: Map[String, Int] = {
+      val words = docWordCountCache
+        .map({ case SpotLDAInput(doc, word, count) => word })
+        .distinct
+        .collect
+      words.zipWithIndex.toMap
+    }
+
+    val documentDictionary: DataFrame = docWordCountCache
+      .map({ case SpotLDAInput(doc, word, count) => doc })
+      .distinct
+      .zipWithIndex
+      .toDF(DocumentName, DocumentNumber)
+      .cache
+
+    // Forcing an action to cache results
+    documentDictionary.count()
+
+    //Structure corpus so that the index is the docID, values are the vectors of word occurrences in that doc
+    val ldaCorpus: RDD[(Long, Vector)] =
+      formatSparkLDAInput(docWordCountCache,
+        documentDictionary,
+        wordDictionary,
+        sqlContext)
+
+    docWordCountCache.unpersist()
+
+    //Instantiate optimizer based on input
+    val optimizer = new EMLDAOptimizer
+
+    logger.info(s"Running Spark LDA with params alpha = $ldaAlpha beta = $ldaBeta " +
+      s"Max iterations = $maxIterations Optimizer = em")
+    //Set LDA params from input args
+
+    val lda =
+      new LDA()
+        .setK(topicCount)
+        .setMaxIterations(maxIterations)
+        .setAlpha(ldaAlpha)
+        .setBeta(ldaBeta)
+        .setOptimizer(optimizer)
+
+    // If caller does not provide seed to lda, ie. ldaSeed is empty, lda is seeded automatically set to hash value of class name
+
+    if (ldaSeed.nonEmpty) {
+      lda.setSeed(ldaSeed.get)
+    }
+
+
+    //Create LDA model
+    val ldaModel = lda.run(ldaCorpus)
+
+    //Convert to DistributedLDAModel to expose info about topic distribution
+    val distLDAModel = ldaModel.asInstanceOf[DistributedLDAModel]
+
+    //Get word topic mix: columns = topic (in no guaranteed order), rows = words (# rows = vocab size)
+    val wordTopicMat: Matrix = distLDAModel.topicsMatrix
+
+    //Topic distribution: for each document, return distribution (vector) over topics for that docs
+    val docTopicDist: RDD[(Long, Vector)] = distLDAModel.topicDistributions
+
+    //Create doc results from vector: convert docID back to string, convert vector of probabilities to array
+    val docToTopicMixDF =
+      formatSparkLDADocTopicOutput(docTopicDist, documentDictionary, sqlContext)
+
+    documentDictionary.unpersist()
+
+    //Create word results from matrix: convert matrix to sequence, wordIDs back to strings, sequence of probabilities to array
+    val revWordMap: Map[Int, String] = wordDictionary.map(_.swap)
+
+    val wordResults = formatSparkLDAWordOutput(wordTopicMat, revWordMap)
+
+    //Create output object
+    SpotLDAOutput(docToTopicMixDF, wordResults)
+  }
+
+  def formatSparkLDAInput(docWordCount: RDD[SpotLDAInput],
+                          documentDictionary: DataFrame,
+                          wordDictionary: Map[String, Int],
+                          sqlContext: SQLContext): RDD[(Long, Vector)] = {
+
+    import sqlContext.implicits._
+
+    val getWordId = {
+      udf((word: String) => (wordDictionary(word)))
+    }
+
+    val docWordCountDF = docWordCount
+      .map({ case SpotLDAInput(doc, word, count) => (doc, word, count) })
+      .toDF(DocumentName, WordName, WordNameWordCount)
+
+    //Convert SpotSparkLDAInput into desired format for Spark LDA: (doc, word, count) -> word count per doc, where RDD
+    //is indexed by DocID
+    val wordCountsPerDocDF = docWordCountDF
+      .join(documentDictionary, docWordCountDF(DocumentName) === documentDictionary(DocumentName))
+      .drop(documentDictionary(DocumentName))
+      .withColumn(WordNumber, getWordId(docWordCountDF(WordName)))
+      .drop(WordName)
+
+    val wordCountsPerDoc: RDD[(Long, Iterable[(Int, Double)])]
+    = wordCountsPerDocDF
+      .select(DocumentNumber, WordNumber, WordNameWordCount)
+      .rdd
+      .map({ case Row(documentId: Long, wordId: Int, wordCount: Int) => (documentId.toLong, (wordId, wordCount.toDouble)) })
+      .groupByKey
+
+    //Sum of distinct words in each doc (words will be repeated between different docs), used for sparse vec size
+    val numUniqueWords = wordDictionary.size
+    val ldaInput: RDD[(Long, Vector)] = wordCountsPerDoc
+      .mapValues({ case vs => Vectors.sparse(numUniqueWords, vs.toSeq) })
+
+    ldaInput
+  }
+
+  def formatSparkLDAWordOutput(wordTopMat: Matrix, wordMap: Map[Int, String]): scala.Predef.Map[String, Array[Double]] = {
+
+    // incoming word top matrix is in column-major order and the columns are unnormalized
+    val m = wordTopMat.numRows
+    val n = wordTopMat.numCols
+    val columnSums: Array[Double] = Range(0, n).map(j => (Range(0, m).map(i => wordTopMat(i, j)).sum)).toArray
+
+    val wordProbs: Seq[Array[Double]] = wordTopMat.transpose.toArray.grouped(n).toSeq
+      .map(unnormProbs => unnormProbs.zipWithIndex.map({ case (u, j) => u / columnSums(j) }))
+
+    wordProbs.zipWithIndex.map({ case (topicProbs, wordInd) => (wordMap(wordInd), topicProbs) }).toMap
+  }
+
+  def formatSparkLDADocTopicOutput(docTopDist: RDD[(Long, Vector)], documentDictionary: DataFrame, sqlContext: SQLContext):
+  DataFrame = {
+    import sqlContext.implicits._
+
+    val topicDistributionToArray = udf((topicDistribution: Vector) => topicDistribution.toArray)
+    val documentToTopicDistributionDF = docTopDist.toDF(DocumentNumber, TopicProbabilityMix)
+
+    documentToTopicDistributionDF
+      .join(documentDictionary, documentToTopicDistributionDF(DocumentNumber) === documentDictionary(DocumentNumber))
+      .drop(documentDictionary(DocumentNumber))
+      .drop(documentToTopicDistributionDF(DocumentNumber))
+      .select(DocumentName, TopicProbabilityMix)
+      .withColumn(TopicProbabilityMixArray, topicDistributionToArray(documentToTopicDistributionDF(TopicProbabilityMix)))
+      .selectExpr(s"$DocumentName  AS $DocumentName", s"$TopicProbabilityMixArray AS $TopicProbabilityMix")
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-ml/src/main/scala/org/apache/spot/lda/SpotLDAWrapperSchema.scala
----------------------------------------------------------------------
diff --git a/spot-ml/src/main/scala/org/apache/spot/lda/SpotLDAWrapperSchema.scala b/spot-ml/src/main/scala/org/apache/spot/lda/SpotLDAWrapperSchema.scala
new file mode 100644
index 0000000..d5412f2
--- /dev/null
+++ b/spot-ml/src/main/scala/org/apache/spot/lda/SpotLDAWrapperSchema.scala
@@ -0,0 +1,22 @@
+package org.apache.spot.lda
+
+object SpotLDAWrapperSchema {
+
+  // modelDF columns
+  val DocumentName = "document_name"
+  val DocumentNumber = "document_number"
+  val DocumentCount = "document_count"
+  val DocumentNameWordNameWordCount = "document_word_count"
+
+  val WordNameWordCount = "word_count"
+  val WordName = "word_name"
+  val WordNumber = "word_number"
+
+  // documentResults
+  val TopicProbabilityMix = "topic_prob_mix"
+  val TopicProbabilityMixArray = "topic_prob_mix_array"
+
+  // wordResults
+  val _0_0_0_0_0 = "0_0_0_0_0"
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-ml/src/main/scala/org/apache/spot/netflow/model/FlowSuspiciousConnectsModel.scala
----------------------------------------------------------------------
diff --git a/spot-ml/src/main/scala/org/apache/spot/netflow/model/FlowSuspiciousConnectsModel.scala b/spot-ml/src/main/scala/org/apache/spot/netflow/model/FlowSuspiciousConnectsModel.scala
index d6999bf..3590d9a 100644
--- a/spot-ml/src/main/scala/org/apache/spot/netflow/model/FlowSuspiciousConnectsModel.scala
+++ b/spot-ml/src/main/scala/org/apache/spot/netflow/model/FlowSuspiciousConnectsModel.scala
@@ -2,17 +2,17 @@ package org.apache.spot.netflow.model
 
 import org.apache.log4j.Logger
 import org.apache.spark.SparkContext
+import org.apache.spark.sql.WideUDFs.udf
 import org.apache.spark.sql.functions._
 import org.apache.spark.sql.types.StructType
-import org.apache.spark.sql.{DataFrame, Row, SQLContext, WideUDFs}
-import org.apache.spot.spotldacwrapper.{SpotLDACInput, SpotLDACOutput}
-import org.apache.spot.spotldacwrapper.SpotLDACSchema._
+import org.apache.spark.sql.{DataFrame, Row, SQLContext}
 import org.apache.spot.SuspiciousConnectsArgumentParser.SuspiciousConnectsConfig
+import org.apache.spot.lda.SpotLDAWrapper
+import org.apache.spot.lda.SpotLDAWrapper.{SpotLDAInput, SpotLDAOutput}
+import org.apache.spot.lda.SpotLDAWrapperSchema._
 import org.apache.spot.netflow.FlowSchema._
 import org.apache.spot.netflow.FlowWordCreator
 import org.apache.spot.utilities.Quantiles
-import WideUDFs.udf
-import org.apache.spot.spotldacwrapper.SpotLDACWrapper
 
 /**
   * A probabilistic model of the netflow traffic observed in a network.
@@ -139,7 +139,7 @@ object FlowSuspiciousConnectsModel {
 
     val totalDataDF = selectedDF.unionAll(FlowFeedback.loadFeedbackDF(sparkContext,
       sqlContext,
-      config.scoresFile,
+      config.feedbackFile,
       config.duplicationFactor))
 
 
@@ -194,29 +194,18 @@ object FlowSuspiciousConnectsModel {
     val ipWordCounts =
       sparkContext.union(srcWordCounts, dstWordCounts)
         .reduceByKey(_ + _)
-        .map({ case ((ip, word), count) => SpotLDACInput(ip, word, count) })
+        .map({ case ((ip, word), count) => SpotLDAInput(ip, word, count) })
 
 
-    val SpotLDACOutput(ipToTopicMixDF, wordToPerTopicProb) = SpotLDACWrapper.runLDA(ipWordCounts,
-      config.modelFile,
-      config.hdfsModelFile,
-      config.topicDocumentFile,
-      config.topicWordFile,
-      config.mpiPreparationCmd,
-      config.mpiCmd,
-      config.mpiProcessCount,
+    val SpotLDAOutput(ipToTopicMixDF, wordToPerTopicProb) = SpotLDAWrapper.runLDA(sparkContext,
+      sqlContext,
+      ipWordCounts,
       config.topicCount,
-      config.localPath,
-      config.ldaPath,
-      config.localUser,
-      config.analysis,
-      config.nodes,
+      logger,
       config.ldaPRGSeed,
-      sparkContext,
-      sqlContext,
-      logger
-    )
-
+      config.ldaAlpha,
+      config.ldaBeta,
+      config.ldaMaxiterations)
 
     new FlowSuspiciousConnectsModel(topicCount,
       ipToTopicMixDF,
@@ -224,6 +213,7 @@ object FlowSuspiciousConnectsModel {
       timeCuts,
       ibytCuts,
       ipktCuts)
+
   }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-ml/src/main/scala/org/apache/spot/proxy/ProxySuspiciousConnectsModel.scala
----------------------------------------------------------------------
diff --git a/spot-ml/src/main/scala/org/apache/spot/proxy/ProxySuspiciousConnectsModel.scala b/spot-ml/src/main/scala/org/apache/spot/proxy/ProxySuspiciousConnectsModel.scala
index 7e99b89..582821b 100644
--- a/spot-ml/src/main/scala/org/apache/spot/proxy/ProxySuspiciousConnectsModel.scala
+++ b/spot-ml/src/main/scala/org/apache/spot/proxy/ProxySuspiciousConnectsModel.scala
@@ -6,13 +6,12 @@ import org.apache.spark.broadcast.Broadcast
 import org.apache.spark.rdd.RDD
 import org.apache.spark.sql.functions._
 import org.apache.spark.sql.{DataFrame, Row, SQLContext}
-import org.apache.spot.spotldacwrapper.{SpotLDACInput, SpotLDACOutput}
 import org.apache.spot.SuspiciousConnectsArgumentParser.SuspiciousConnectsConfig
 import org.apache.spot.proxy.ProxySchema._
 import org.apache.spot.utilities._
 import org.apache.spot.SuspiciousConnectsScoreFunction
-import org.apache.spot.spotldacwrapper.SpotLDACWrapper
-
+import org.apache.spot.lda.SpotLDAWrapper
+import org.apache.spot.lda.SpotLDAWrapper.{SpotLDAInput, SpotLDAOutput}
 /**
   * Encapsulation of a proxy suspicious connections model.
   *
@@ -85,7 +84,7 @@ object ProxySuspiciousConnectsModel {
     * @param sqlContext   SQL context.
     * @param logger       Logge object.
     * @param config       SuspiciousConnetsArgumnetParser.Config object containg CLI arguments.
-    * @param inDF           Dataframe for training data, with columns Host, Time, ReqMethod, FullURI, ResponseContentType,
+    * @param inDF         Dataframe for training data, with columns Host, Time, ReqMethod, FullURI, ResponseContentType,
     *                     UserAgent, RespCode (as defined in ProxySchema object).
     * @return ProxySuspiciousConnectsModel
     */
@@ -97,9 +96,9 @@ object ProxySuspiciousConnectsModel {
 
     logger.info("training new proxy suspcious connects model")
 
-    
+
     val df = inDF.select(Date, Time, ClientIP, Host, ReqMethod, UserAgent, ResponseContentType, RespCode, FullURI)
-      .unionAll(ProxyFeedback.loadFeedbackDF(sparkContext, sqlContext, config.scoresFile, config.duplicationFactor))
+      .unionAll(ProxyFeedback.loadFeedbackDF(sparkContext, sqlContext, config.feedbackFile, config.duplicationFactor))
 
     val timeCuts =
       Quantiles.computeDeciles(df.select(Time).rdd.map({ case Row(t: String) => TimeUtilities.getTimeAsDouble(t) }))
@@ -115,33 +114,25 @@ object ProxySuspiciousConnectsModel {
     val agentCuts =
       Quantiles.computeQuintiles(df.select(UserAgent).rdd.map({ case Row(agent: String) => agentToCountBC.value(agent) }))
 
-    val docWordCount: RDD[SpotLDACInput] =
-      getIPWordCounts(sparkContext, sqlContext, logger, df, config.scoresFile, config.duplicationFactor, agentToCount, timeCuts, entropyCuts, agentCuts)
+    val docWordCount: RDD[SpotLDAInput] =
+      getIPWordCounts(sparkContext, sqlContext, logger, df, config.feedbackFile, config.duplicationFactor, agentToCount, timeCuts, entropyCuts, agentCuts)
 
 
-    val SpotLDACOutput(ipToTopicMixDF, wordToPerTopicProb) = SpotLDACWrapper.runLDA(docWordCount,
-      config.modelFile,
-      config.hdfsModelFile,
-      config.topicDocumentFile,
-      config.topicWordFile,
-      config.mpiPreparationCmd,
-      config.mpiCmd,
-      config.mpiProcessCount,
+    val SpotLDAOutput(ipToTopicMixDF, wordResults) = SpotLDAWrapper.runLDA(sparkContext,
+      sqlContext,
+      docWordCount,
       config.topicCount,
-      config.localPath,
-      config.ldaPath,
-      config.localUser,
-      config.analysis,
-      config.nodes,
+      logger,
       config.ldaPRGSeed,
-      sparkContext,
-      sqlContext,
-      logger)
+      config.ldaAlpha,
+      config.ldaBeta,
+      config.ldaMaxiterations)
+
 
     // Since Proxy is still broadcasting ip to topic mix, we need to convert data frame to Map[String, Array[Double]]
     val ipToTopicMix = ipToTopicMixDF
       .rdd
-      .map({ case (ipToTopicMixRow: Row) => (ipToTopicMixRow.toSeq.toArray) })
+      .map({ case (ipToTopicMixRow: Row) => ipToTopicMixRow.toSeq.toArray })
       .map({
         case (ipToTopicMixSeq) => (ipToTopicMixSeq(0).asInstanceOf[String], ipToTopicMixSeq(1).asInstanceOf[Seq[Double]]
           .toArray)
@@ -149,14 +140,16 @@ object ProxySuspiciousConnectsModel {
       .collectAsMap
       .toMap
 
-    new ProxySuspiciousConnectsModel(config.topicCount, ipToTopicMix, wordToPerTopicProb, timeCuts, entropyCuts, agentCuts)
+
+    new ProxySuspiciousConnectsModel(config.topicCount, ipToTopicMix, wordResults, timeCuts, entropyCuts, agentCuts)
+
   }
 
   /**
     * Transform proxy log events into summarized words and aggregate into IP-word counts.
-    * Returned as [[SpotLDACInput]] objects.
+    * Returned as [[SpotLDAInput]] objects.
     *
-    * @return RDD of [[SpotLDACInput]] objects containing the aggregated IP-word counts.
+    * @return RDD of [[SpotLDAInput]] objects containing the aggregated IP-word counts.
     */
   def getIPWordCounts(sc: SparkContext,
                       sqlContext: SQLContext,
@@ -167,7 +160,7 @@ object ProxySuspiciousConnectsModel {
                       agentToCount: Map[String, Long],
                       timeCuts: Array[Double],
                       entropyCuts: Array[Double],
-                      agentCuts: Array[Double]): RDD[SpotLDACInput] = {
+                      agentCuts: Array[Double]): RDD[SpotLDAInput] = {
 
 
     logger.info("Read source data")
@@ -184,7 +177,7 @@ object ProxySuspiciousConnectsModel {
                         agentToCount: Map[String, Long],
                         timeCuts: Array[Double],
                         entropyCuts: Array[Double],
-                        agentCuts: Array[Double]): RDD[SpotLDACInput] = {
+                        agentCuts: Array[Double]): RDD[SpotLDAInput] = {
 
     val topDomains: Broadcast[Set[String]] = sc.broadcast(TopDomains.TopDomains)
 
@@ -202,6 +195,6 @@ object ProxySuspiciousConnectsModel {
       select(ClientIP, Word)
 
     ipWordDF.rdd.map({ case Row(ip, word) => ((ip.asInstanceOf[String], word.asInstanceOf[String]), 1) })
-      .reduceByKey(_ + _).map({ case ((ip, word), count) => SpotLDACInput(ip, word, count) })
+      .reduceByKey(_ + _).map({ case ((ip, word), count) => SpotLDAInput(ip, word, count) })
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-ml/src/main/scala/org/apache/spot/spotldacwrapper/SpotLDACInput.scala
----------------------------------------------------------------------
diff --git a/spot-ml/src/main/scala/org/apache/spot/spotldacwrapper/SpotLDACInput.scala b/spot-ml/src/main/scala/org/apache/spot/spotldacwrapper/SpotLDACInput.scala
deleted file mode 100644
index e9763ef..0000000
--- a/spot-ml/src/main/scala/org/apache/spot/spotldacwrapper/SpotLDACInput.scala
+++ /dev/null
@@ -1,6 +0,0 @@
-package org.apache.spot.spotldacwrapper
-
-/**
-  * Created by rabarona on 11/14/16.
-  */
-case class SpotLDACInput (doc: String, word: String, count: Int) extends Serializable

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-ml/src/main/scala/org/apache/spot/spotldacwrapper/SpotLDACOutput.scala
----------------------------------------------------------------------
diff --git a/spot-ml/src/main/scala/org/apache/spot/spotldacwrapper/SpotLDACOutput.scala b/spot-ml/src/main/scala/org/apache/spot/spotldacwrapper/SpotLDACOutput.scala
deleted file mode 100644
index c3aa67e..0000000
--- a/spot-ml/src/main/scala/org/apache/spot/spotldacwrapper/SpotLDACOutput.scala
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.apache.spot.spotldacwrapper
-
-import org.apache.spark.sql.DataFrame
-/**
-  * Created by rabarona on 11/14/16.
-  */
-case class SpotLDACOutput (docToTopicMix: DataFrame, wordResults: Map[String, Array[Double]])

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-ml/src/main/scala/org/apache/spot/spotldacwrapper/SpotLDACSchema.scala
----------------------------------------------------------------------
diff --git a/spot-ml/src/main/scala/org/apache/spot/spotldacwrapper/SpotLDACSchema.scala b/spot-ml/src/main/scala/org/apache/spot/spotldacwrapper/SpotLDACSchema.scala
deleted file mode 100644
index 5c10459..0000000
--- a/spot-ml/src/main/scala/org/apache/spot/spotldacwrapper/SpotLDACSchema.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.apache.spot.spotldacwrapper
-
-/**
-  * Created by rabarona on 11/14/16.
-  */
-object SpotLDACSchema {
-
-  // modelDF columns
-  val DocumentName = "document_name"
-  val DocumentId = "document_id"
-  val WordNameWordCount = "word_count"
-  val DocumentCount = "document_count"
-  val DocumentNameWordNameWordCount = "document_word_count"
-
-  // documentResults
-  val TopicProbabilityMix = "topic_prob_mix"
-
-  // wordResults
-  val _0_0_0_0_0 = "0_0_0_0_0"
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-ml/src/main/scala/org/apache/spot/spotldacwrapper/SpotLDACWrapper.scala
----------------------------------------------------------------------
diff --git a/spot-ml/src/main/scala/org/apache/spot/spotldacwrapper/SpotLDACWrapper.scala b/spot-ml/src/main/scala/org/apache/spot/spotldacwrapper/SpotLDACWrapper.scala
deleted file mode 100644
index 395e2e4..0000000
--- a/spot-ml/src/main/scala/org/apache/spot/spotldacwrapper/SpotLDACWrapper.scala
+++ /dev/null
@@ -1,292 +0,0 @@
-package org.apache.spot.spotldacwrapper
-
-import java.io.File
-
-import org.apache.log4j.Logger
-import org.apache.spark.SparkContext
-import org.apache.spark.rdd.RDD
-import org.apache.spark.sql.functions._
-import org.apache.spark.sql.{DataFrame, SQLContext}
-
-import org.apache.spot.spotldacwrapper.SpotLDACSchema._
-
-import scala.collection.immutable.Map
-import scala.io.Source._
-import scala.sys.process._
-
-/**
-  * Contains routines for LDA including pre and post operations
-  * 1. Creates list of unique documents, words and model based on those two
-  * 2. Processes the model calling MPI
-  * 3. Reads MPI results: Topic distributions per document and words per topic
-  * 4. Calculates and returns probability of word given topic: p(w|z)
-  */
-
-object SpotLDACWrapper {
-
-  /**
-    * runLDA receives a RDD of SpotLDACInput and converts to Spot-LDA-C input model, then calls system process to run
-    * Spot-LDA-C. After that, reads local files final.gamma and final.beta to normalize ML results and
-    * return as SpotLDACOutput object.
-    *
-    * @param docWordCount RDD containing a list of documents or ips, each word they are related to and the count of
-    *                     each word.
-    * @param modelFile Final destination (local file system) for model so Spot-LDA-C can pick it up.
-    * @param hdfsModelFile HDFS temporary location for model.
-    * @param topicDocumentFile Location of Spot-LDA-C results file final.gamma (local file system).
-    * @param topicWordFile Location of Spot-LDA-C results file final.beta (local file system).
-    * @param mpiPreparationCmd MPI preparation command if required.
-    * @param mpiCmd MPI command.
-    * @param mpiProcessCount MPI process count.
-    * @param topicCount Number of topics for Spot-LDA-C
-    * @param localPath Local path where installation is located.
-    * @param ldaPath Spot-LDA-C local path.
-    * @param localUser Spot local path.
-    * @param dataSource Flow, DNS or Proxy.
-    * @param nodes  List of Nodes to distribute model.dat (LDA input).
-    * @param prgSeed Flag for LDA, seeded no seeded.
-    * @param sparkContext Application Spark Context.
-    * @param sqlContext Application SQL Context.
-    * @param logger Application Logger.
-    * @return
-    */
-  def runLDA(docWordCount: RDD[SpotLDACInput],
-             modelFile: String,
-             hdfsModelFile: String,
-             topicDocumentFile: String,
-             topicWordFile: String,
-             mpiPreparationCmd: String,
-             mpiCmd: String,
-             mpiProcessCount: String,
-             topicCount: Int,
-             localPath: String,
-             ldaPath: String,
-             localUser: String,
-             dataSource: String,
-             nodes: String,
-             prgSeed: Option[Long],
-             sparkContext: SparkContext,
-             sqlContext: SQLContext,
-             logger: Logger): SpotLDACOutput =  {
-
-    import sqlContext.implicits._
-    val docWordCountCache = docWordCount.cache()
-
-    // Create word Map Word,Index for further usage
-    val wordDictionary: Map[String, Int] = {
-      val words = docWordCountCache.map({case SpotLDACInput(doc, word, count) => word})
-        .distinct
-        .collect
-      words.zipWithIndex.toMap
-    }
-
-    // Create model for LDA
-    val modelDF = createModel(docWordCountCache, wordDictionary, sparkContext, sqlContext, logger)
-
-    docWordCountCache.unpersist()
-
-    val documentDictionary = modelDF.select(col(DocumentName))
-      .rdd
-      .map(
-        x=>  x.toString().replaceAll("\\[","").replaceAll("\\]","")
-      )
-      .zipWithIndex.toDF(DocumentName, DocumentId)
-
-    // Save model to HDFS and then getmerge to file system
-
-    modelDF.select(col(DocumentNameWordNameWordCount)).rdd.map(_.mkString).saveAsTextFile(hdfsModelFile)
-    sys.process.Process(Seq("hadoop", "fs", "-getmerge", hdfsModelFile + "/part-*", modelFile)).!
-    sys.process.Process(Seq("hadoop", "fs", "-rm", "-r", "-skipTrash", hdfsModelFile)).!
-
-    // Copy model.dat to each node in machinefile
-
-    val nodeList = nodes.replace("'","").split(",")
-    for (node <- nodeList){
-      sys.process.Process(Seq("ssh", node, "mkdir -p " + localUser + "/ml/" + dataSource)).!
-      sys.process.Process(Seq("scp", "-r", localPath, node + ":" + localUser + "/ml/" + dataSource )).!
-    }
-
-    // Execute Pre MPI command
-
-    if(mpiPreparationCmd != "" && mpiPreparationCmd != null)
-      stringToProcess(mpiPreparationCmd).!!
-
-    // Execute MPI-Spot-LDA-C
-
-    val prgSeedString = if (prgSeed.nonEmpty) prgSeed.get.toString() else ""
-
-    sys.process.Process(Seq(mpiCmd, "-n", mpiProcessCount, "-f", "machinefile", "./lda", "est", "2.5",
-      topicCount.toString(), "settings.txt",  modelFile, "random", localPath, prgSeedString),
-      new java.io.File(ldaPath)) #> (System.out) !!
-
-    // Read topic info per document
-
-    val topicDocumentFileExists = if (topicDocumentFile != "") new File(topicDocumentFile).exists else false
-    val topicWordFileExists = if (topicWordFile != "") new File(topicWordFile).exists() else false
-
-    val documentTopicMixRawLines = {
-      if (topicDocumentFileExists) {
-        fromFile(topicDocumentFile).getLines().toArray
-      }
-      else Array[String]()
-    }
-
-    // Create document results
-
-    val docToTopicMix = getDocumentResults(documentTopicMixRawLines, documentDictionary, topicCount, sparkContext, sqlContext)
-
-    // Read words per topic
-
-    val topicWordData = {
-      if (topicWordFileExists) {
-        fromFile(topicWordFile).getLines().toArray
-      }
-      else Array[String]()
-    }
-
-    // Create word results
-    val wordResults = getWordToProbPerTopicMap(topicWordData, wordDictionary)
-
-    SpotLDACOutput(docToTopicMix, wordResults)
-  }
-
-  /**
-    * getWordProbabilitiesFromTopicLine
-    *
-    * @param topicLine A line of text encoding the probabilities of the word given a topic.
-    * @return probability of each word conditioned on this topic
-    */
-  def getWordProbabilitesFromTopicLine(topicLine: String) : Array[Double] = {
-
-    val logWordProbs: Array[Double] = topicLine.trim().split(" ").map(_.toDouble)
-
-    val wordProbs: Array[Double] = logWordProbs.map(math.exp)
-
-    // Normalize to account for any weirdness from the log/exp transformations
-    val sumRawWord = wordProbs.sum
-    wordProbs.map(_ / sumRawWord)
-  }
-
-
-  /**
-    * getDocumentToTopicProbabilityArray returns an array with probability distribution given the number of topics
-    * @param documentTopicProbabilityMix a line with probability distribution. Its index matches a document in document
-    *                                    dictionary.
-    * @param topicCount number of topics.
-    * @return
-    */
-  def getDocumentToTopicProbabilityArray(documentTopicProbabilityMix: String, topicCount: Int) : Array[Double]  ={
-
-    val topics = documentTopicProbabilityMix.split(" ").map(_.toDouble)
-    val topicsSum = topics.sum
-
-    val topicsProb = {
-      if (topicsSum > 0) {
-        topics.map(_ / topicsSum)
-      }
-      else {
-        Array.fill(topicCount)(0d)
-      }
-    }
-    topicsProb
-  }
-
-  /**
-    * createModel creates a new data frame with document names and document-word-count for further use in Spot-LDA-C
-    * @param documentWordData RDD with document-word data and the count of each word.
-    * @param wordToIndex  word dictionary with numeric index
-    * @param sparkContext Application Spark Context
-    * @param sqlContext Application Sql Context
-    * @param logger Application Logger
-    * @return
-    */
-  def createModel(documentWordData: RDD[SpotLDACInput],
-                  wordToIndex: Map[String, Int],
-                  sparkContext: SparkContext,
-                  sqlContext: SQLContext,
-                  logger: Logger): DataFrame = {
-    import sqlContext.implicits._
-
-    val documentCount = documentWordData
-      .map({case SpotLDACInput(doc, word, count) => doc})
-      .map(document => (document, 1))
-      .reduceByKey(_ + _)
-
-    val wordIndexdocWordCount = documentWordData
-      .map({case SpotLDACInput(doc, word, count) => (doc, wordToIndex(word) + ":" + count)})
-      .groupByKey()
-      .map(x => (x._1, x._2.mkString(" ")))
-
-    val wordCountDF = wordIndexdocWordCount.toDF(DocumentName,WordNameWordCount)
-    val distinctDocDF = documentCount.toDF(DocumentName,DocumentCount)
-
-    val docWordCount = distinctDocDF.join(wordCountDF, wordCountDF(DocumentName).equalTo(distinctDocDF(DocumentName)))
-                              .drop(wordCountDF(DocumentName))
-
-    def concatDocWordCount = {udf( (a: String, b: String) => a.concat(" ").concat(b))}
-
-    val modelDF = docWordCount.withColumn(DocumentNameWordNameWordCount,
-              concatDocWordCount(
-                  docWordCount(DocumentCount),
-                  docWordCount(WordNameWordCount)))
-                  .drop(col(DocumentCount)).drop(col(WordNameWordCount))
-    modelDF
-  }
-
-  /**
-    * getDocumentResults normalizes Spot-LDA-C results for further steps.
-    * @param ldaResults Spot-LDA-C results.
-    * @param docIndexToDocument data frame with information about document and its index. The position of each line in
-    *                           ldaResults corresponds to the index of each element in docIndexToDocument.
-    * @param topicCount number of topics.
-    * @param sparkContext Application Spark Context.
-    * @param sqlContext Application Sql Context.
-    * @return
-    */
-  def getDocumentResults(ldaResults: Array[String],
-                         docIndexToDocument: DataFrame,
-                         topicCount: Int, sparkContext: SparkContext, sqlContext: SQLContext) : DataFrame = {
-
-      import sqlContext.implicits._
-
-      val topicDocumentData = sparkContext.parallelize(ldaResults.zipWithIndex)
-        .map(
-          {
-            case (documentTopicProbabilityMix, documentTopicProbabilityMixId) =>
-              (getDocumentToTopicProbabilityArray(documentTopicProbabilityMix, topicCount), documentTopicProbabilityMixId)
-          }
-        ).toDF(TopicProbabilityMix, DocumentId)
-
-      val ipToTopicMix = topicDocumentData.join(docIndexToDocument,
-        topicDocumentData(DocumentId).equalTo(docIndexToDocument(DocumentId)))
-        .drop(topicDocumentData(DocumentId))
-        .drop(docIndexToDocument(DocumentId)).select(col(DocumentName), col(TopicProbabilityMix))
-
-      ipToTopicMix
-    }
-
-  /**
-    * getWordToProbPerTopicMap normalizes Spot-LDA-C results for further steps.
-    * @param topicWordData
-    * @param wordToIndex
-    * @return
-    */
-  def getWordToProbPerTopicMap(topicWordData: Array[String],
-                               wordToIndex: Map[String, Int]): Map[String, Array[Double]] = {
-
-
-    val probabilityOfWordGivenTopic = topicWordData.map(getWordProbabilitesFromTopicLine).transpose
-
-    val indexToWord = {
-      val addedIndex = wordToIndex.size
-      val tempWordDictionary = wordToIndex + (_0_0_0_0_0 -> addedIndex)
-      tempWordDictionary.map({
-        case (k, v) => (v, k)
-      })
-    }
-
-    probabilityOfWordGivenTopic.zipWithIndex.map({ case (probOfWordGivenTopic, index) => indexToWord(index) ->
-      probOfWordGivenTopic}).toMap
-
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-ml/src/test/scala/org/apache/spot/SpotLDACWrapperTest.scala
----------------------------------------------------------------------
diff --git a/spot-ml/src/test/scala/org/apache/spot/SpotLDACWrapperTest.scala b/spot-ml/src/test/scala/org/apache/spot/SpotLDACWrapperTest.scala
deleted file mode 100644
index 528d9d9..0000000
--- a/spot-ml/src/test/scala/org/apache/spot/SpotLDACWrapperTest.scala
+++ /dev/null
@@ -1,189 +0,0 @@
-package org.apache.spot
-
-import org.apache.log4j.{Level, LogManager}
-import org.apache.spark.sql.{DataFrame, Row}
-import org.apache.spark.sql.functions._
-import org.apache.spot.spotldacwrapper.SpotLDACWrapper
-import org.apache.spot.spotldacwrapper.SpotLDACInput
-import org.apache.spot.spotldacwrapper.SpotLDACSchema._
-import org.apache.spot.testutils.TestingSparkContextFlatSpec
-import org.scalatest.Matchers
-
-
-class SpotLDACWrapperTest extends TestingSparkContextFlatSpec with Matchers{
-
-  val logger = LogManager.getLogger("SuspiciousConnectsAnalysis")
-  logger.setLevel(Level.INFO)
-
-
-  "normalizeWord" should "calculate exponential of each value in the input string, then sum up all the exponential and " +
-    "then divide  each exponential by the total sum" in {
-
-    val wordProbability = "1 2 3 4 5"
-    val result = SpotLDACWrapper.getWordProbabilitesFromTopicLine(wordProbability)
-
-    result.length shouldBe 5
-    result(0) shouldBe 0.011656230956039607
-    result(1) shouldBe 0.03168492079612427
-    result(2) shouldBe 0.0861285444362687
-    result(3) shouldBe 0.23412165725273662
-    result(4) shouldBe 0.6364086465588308
-  }
-
-  "getTopicDocument" should "return string of document and 20 values when the sum of each value in the line is bigger" +
-    "than 0. Each result value should be divided by the sum of all values" in {
-    val topicCount = 20
-    val document = "192.168.1.1"
-    val line = "0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 " +
-      "0.0124531442 0.0124531442 0.0124531442 23983.5532262138 0.0124531442 0.0124531442 0.0124531442 0.0124531442 " +
-      "0.0124531442 0.0124531442 22999.4716800747 0.0124531442"
-
-    var topicMixOUT = SpotLDACWrapper.getDocumentToTopicProbabilityArray(line, topicCount)
-
-    topicMixOUT shouldBe Array(2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7,
-      2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7,
-      2.6505498126219955E-7, 2.6505498126219955E-7, 0.5104702996191969, 2.6505498126219955E-7, 2.6505498126219955E-7,
-      2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 0.48952492939114034,
-      2.6505498126219955E-7)
-  }
-
-  it should "return string of document and 0.0 20 times when the sum of each value in the line is 0" in {
-    val document = "192.168.1.1"
-    val line = "0.0 0.0 1.0 -1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0"
-
-    val topicCount = 20
-    val topicMixOUT = SpotLDACWrapper.getDocumentToTopicProbabilityArray(line, topicCount)
-
-    topicMixOUT shouldBe Array(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
-  }
-
-  "createModel" should "return model in Array[String] format. Each string should contain the document count and the" +
-    "total count for each word" in {
-
-    val testSqlContext = new org.apache.spark.sql.SQLContext(sparkContext)
-    import testSqlContext.implicits._
-
-    val documentWordData = sparkContext.parallelize(Array(SpotLDACInput("192.168.1.1", "333333_7.0_0.0_1.0", 8),
-      SpotLDACInput("10.10.98.123", "1111111_6.0_3.0_5.0", 4),
-      SpotLDACInput("66.23.45.11", "-1_43_7.0_2.0_6.0", 2),
-      SpotLDACInput("192.168.1.1", "-1_80_6.0_1.0_1.0", 5)))
-
-    val wordDictionary = Map("333333_7.0_0.0_1.0" -> 0,
-      "1111111_6.0_3.0_5.0" -> 1,
-      "-1_43_7.0_2.0_6.0" -> 2,
-      "-1_80_6.0_1.0_1.0" -> 3)
-
-    val modelDF: DataFrame = SpotLDACWrapper.createModel(documentWordData, wordDictionary, sparkContext, sqlContext, logger)
-
-    val model = modelDF.select(col(DocumentNameWordNameWordCount)).rdd
-      .map(
-        x=> ( x.toString().replaceAll("\\[","").replaceAll("\\]","") )
-      ).collect
-
-    val documentDictionary = modelDF.select(col(DocumentName))
-      .rdd
-      .map(x=>x.toString.replaceAll("\\]","").replaceAll("\\[",""))
-      .zipWithIndex.toDF(DocumentName, DocumentId)
-
-    model should contain ("2 0:8 3:5")
-    model should contain ("1 1:4")
-    model should contain ("1 2:2")
-    model shouldBe Array("1 2:2", "1 1:4", "2 0:8 3:5")
-
-  }
-
-  "getDocumentResults" should "return DataFrame with two columns. One for document (document_name) and the other for the " +
-    "probabilities distribution (topic_prob_mix) when the sum of each value in the line is bigger" +
-    "than 0. Each result value should be divided by the sum of all values and the result array order should be the same" +
-    "as incoming data (topicDocument Data)" in {
-
-    val testSqlContext = new org.apache.spark.sql.SQLContext(sparkContext)
-    import testSqlContext.implicits._
-
-    val topicCount = 20
-    val documentDictionary = sparkContext.parallelize(Array
-    (("10.10.98.123"->3), ( "66.23.45.11"->0), ( "192.168.1.1"->1 ), ("133.546.43.22" -> 2))).toDF(DocumentName,DocumentId)
-
-    val topicDocumentData = Array("0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 " +
-      "0.0124531442 0.0124531442 0.0124531442 0.0124531442 23983.5532262138 0.0124531442 0.0124531442 0.0124531442 " +
-      "0.0124531442 0.0124531442 0.0124531442 22999.4716800747 0.0124531442",
-    "0.0124531442 0.0124531442 45583.9162803520 0.0124531442 24896.2502172987 0.0124531442 0.0124531442 0.0124531442 " +
-      "38659.6152616495 0.0124531442 0.0124531442 0.0124531442 0.0124531442 64804.4886288180 25162.0192468565 " +
-      "0.0124531442 0.0124531442 36361.7850838895 0.0124531442 0.0124531442",
-    "0.0124531442 0.0124531442 53816.0629371489 0.0124531442 24404.5440320289 0.0124531442 0.0124531442 0.0124531442 " +
-      "28303.9934577136 0.0124531442 0.0124531442 0.0124531442 0.0124531442 71151.8773513492 26093.1297387104 " +
-      "0.0124531442 0.0124531442 29142.4672019139 0.0124531442 0.0124531442",
-    "0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 " +
-      "0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 12.0124531442 " +
-      "0.0124531442 0.0124531442 0.0124531442 0.0124531442")
-
-    val resultsDF = SpotLDACWrapper.getDocumentResults(topicDocumentData, documentDictionary, topicCount, sparkContext, testSqlContext)
-
-    // Since DNS is still broadcasting ip to topic mix, we need to convert data frame to Map[String, Array[Double]]
-    val ipToTopicMix = resultsDF
-      .rdd
-      .map({ case (ipToTopicMixRow: Row) => (ipToTopicMixRow.toSeq.toArray) })
-      .map({
-        case (ipToTopicMixSeq) => (ipToTopicMixSeq(0).asInstanceOf[String], ipToTopicMixSeq(1).asInstanceOf[Seq[Double]]
-          .toArray)
-      })
-      .collectAsMap
-      .toMap
-
-    ipToTopicMix("66.23.45.11") shouldBe Array(2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7,
-      2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7,
-      2.6505498126219955E-7, 2.6505498126219955E-7, 0.5104702996191969, 2.6505498126219955E-7, 2.6505498126219955E-7,
-      2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 0.48952492939114034, 2.6505498126219955E-7)
-
-    ipToTopicMix("192.168.1.1") shouldBe Array(5.28867235797652E-8, 5.28867235797652E-8, 0.19358837746391266, 5.28867235797652E-8,
-      0.10573081643228267, 5.28867235797652E-8, 5.28867235797652E-8, 5.28867235797652E-8, 0.1641818606776375, 5.28867235797652E-8,
-      5.28867235797652E-8, 5.28867235797652E-8, 5.28867235797652E-8, 0.27521540117076093, 0.10685949951637365, 5.28867235797652E-8,
-      5.28867235797652E-8, 0.15442330432490242, 5.28867235797652E-8, 5.28867235797652E-8)
-
-    ipToTopicMix("133.546.43.22") shouldBe Array(5.346710724792232E-8, 5.346710724792232E-8, 0.2310572464680428, 5.346710724792232E-8,
-      0.1047799938827603, 5.346710724792232E-8, 5.346710724792232E-8, 5.346710724792232E-8, 0.12152213364300919, 5.346710724792232E-8,
-      5.346710724792232E-8, 5.346710724792232E-8, 5.346710724792232E-8, 0.30548791503077616, 0.11202987324065357, 5.346710724792232E-8,
-      5.346710724792232E-8, 0.12512208919525633, 5.346710724792232E-8, 5.346710724792232E-8)
-
-    ipToTopicMix("10.10.98.123") shouldBe Array(0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624,
-      0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624,
-      0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624,
-      0.0010166609738175624, 0.9806834414974662, 0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624)
-  }
-
-  "getWordResults" should "return Array[String] with 20 elements and N word probability. The result array should have the" +
-    "same order as the input data (topicWordData)" in {
-
-    val wordDictionary = Map("-1_23.0_7.0_7.0_4.0" -> 3, "23.0_7.0_7.0_4.0" -> 0, "333333.0_7.0_7.0_4.0" -> 2, "80.0_7.0_7.0_4.0" -> 1)
-    val topicWordData = Array("-15.3937807051 -536.5105632673 -532.4503365466 -10.8318318078",
-    "-532.7002781469 -447.4890465231 -525.1690620213 -13.9180467610",
-    "-19.5667065907 -5.4442353782 -8.0252973255 -12.4288410371",
-    "-537.3544437825 -15.4983056878 -22.4722439197 -14.7817718408",
-    "-13.3791705206 -5.3657121205 -9.6286562391 -10.8083455362",
-    "-539.4466499733 -535.9756606126 -122.4199569787 -535.7615756409",
-    "-14.9824699328 -532.0369117371 -527.9766850251 -11.1874512926",
-    "-15.1889345209 -534.5750685563 -530.5148418392 -13.5374760178",
-    "-20.4194054373 -5.3920297886 -9.0613037095 -11.5228207125",
-    "-16.7232163605 -533.1029777067 -529.0427509894 -11.7742458954",
-    "-15.4319201624 -533.2550983208 -529.1948716024 -10.7487557143",
-    "-536.2164790868 -532.7454897639 -528.6852629847 -532.5314047894",
-    "-14.9148351018 -535.3169147724 -531.2566880561 -10.9572759378",
-    "-19.2062800183 -5.8636196300 -8.3638265558 -10.6807087581",
-    "-20.4589237180 -5.2246884025 -8.1727002832 -10.7430483178",
-    "-341.6123784319 -339.5204175204 -337.1106321483 -339.3909978330",
-    "-534.8483200081 -531.3773307914 -527.3171040363 -17.0420121428",
-    "-19.9682608636 -5.4274731739 -8.0755820355 -12.0653946611",
-    "-535.7333037656 -532.2623144682 -528.2020876890 -532.0482294927",
-    "-18.4350359818 -534.4612736041 -530.4010468817 -11.0784977885")
-
-    val results = SpotLDACWrapper.getWordToProbPerTopicMap(topicWordData, wordDictionary)
-
-    results.keySet.size shouldBe 4
-    results("23.0_7.0_7.0_4.0").length shouldBe 20
-    results("23.0_7.0_7.0_4.0")(0) shouldBe 0.010333787125924218
-    results("23.0_7.0_7.0_4.0")(19) shouldBe 6.379973716629045E-4
-    results("-1_23.0_7.0_7.0_4.0")(0) shouldBe 0.9896662128740757
-    results("-1_23.0_7.0_7.0_4.0")(19) shouldBe 0.9993620026283371
-  }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-ml/src/test/scala/org/apache/spot/SpotLDACWrapperTest.scala.tmp
----------------------------------------------------------------------
diff --git a/spot-ml/src/test/scala/org/apache/spot/SpotLDACWrapperTest.scala.tmp b/spot-ml/src/test/scala/org/apache/spot/SpotLDACWrapperTest.scala.tmp
deleted file mode 100644
index f96f186..0000000
--- a/spot-ml/src/test/scala/org/apache/spot/SpotLDACWrapperTest.scala.tmp
+++ /dev/null
@@ -1,166 +0,0 @@
-package org.apache.spot
-
-import org.apache.spot.SpotLDACWrapper.SpotLDACInput
-import org.apache.spot.testutils.TestingSparkContextFlatSpec
-import org.scalatest.Matchers
-
-
-class SpotLDACWrapperTest extends TestingSparkContextFlatSpec with Matchers{
-
-
-  "normalizeWord" should "calculate exponential of each value in the input string, then sum up all the exponential and " +
-    "then divide  each exponential by the total sum" in {
-
-    val wordProbability = "1 2 3 4 5"
-    val result = SpotLDACWrapper.getWordProbabilitesFromTopicLine(wordProbability)
-
-    result.length shouldBe 5
-    result(0) shouldBe 0.011656230956039607
-    result(1) shouldBe 0.03168492079612427
-    result(2) shouldBe 0.0861285444362687
-    result(3) shouldBe 0.23412165725273662
-    result(4) shouldBe 0.6364086465588308
-  }
-
-  "getTopicDocument" should "return string of document and 20 values when the sum of each value in the line is bigger" +
-    "than 0. Each result value should be divided by the sum of all values" in {
-    val topicCount = 20
-    val document = "192.168.1.1"
-    val line = "0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 " +
-      "0.0124531442 0.0124531442 0.0124531442 23983.5532262138 0.0124531442 0.0124531442 0.0124531442 0.0124531442 " +
-      "0.0124531442 0.0124531442 22999.4716800747 0.0124531442"
-
-<<<<<<< HEAD:src/test/scala/org/opennetworkinsight/OniLDACWrapperTest.scala
-    var (docOUT, topicMixOUT) = OniLDACWrapper.getTopicDocument(document, line, topicCount)
-=======
-    var (docOUT, topicMixOUT) = SpotLDACWrapper.getTopicDocument(document, line)
->>>>>>> 1692d2101cb1fbb424e34ae0e8cd395a1de0d502:src/test/scala/org/apache/spot/SpotLDACWrapperTest.scala
-
-    docOUT shouldBe document
-    topicMixOUT shouldBe Array(2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7,
-      2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7,
-      2.6505498126219955E-7, 2.6505498126219955E-7, 0.5104702996191969, 2.6505498126219955E-7, 2.6505498126219955E-7,
-      2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 0.48952492939114034,
-      2.6505498126219955E-7)
-  }
-
-  it should "return string of document and 0.0 20 times when the sum of each value in the line is 0" in {
-    val document = "192.168.1.1"
-    val line = "0.0 0.0 1.0 -1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0"
-<<<<<<< HEAD:src/test/scala/org/opennetworkinsight/OniLDACWrapperTest.scala
-    val topicCount = 20
-    val (docOUT, topicMixOUT) = OniLDACWrapper.getTopicDocument(document, line, topicCount)
-=======
-
-    val (docOUT, topicMixOUT) = SpotLDACWrapper.getTopicDocument(document, line)
->>>>>>> 1692d2101cb1fbb424e34ae0e8cd395a1de0d502:src/test/scala/org/apache/spot/SpotLDACWrapperTest.scala
-
-    docOUT shouldBe document
-    topicMixOUT shouldBe Array(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
-  }
-
-  "createModel" should "return model in Array[String] format. Each string should contain the document count and the" +
-    "total count for each word" in {
-
-    val documentWordData = sparkContext.parallelize(Array(SpotLDACInput("192.168.1.1", "333333_7.0_0.0_1.0", 8),
-      SpotLDACInput("10.10.98.123", "1111111_6.0_3.0_5.0", 4),
-      SpotLDACInput("66.23.45.11", "-1_43_7.0_2.0_6.0", 2),
-      SpotLDACInput("192.168.1.1", "-1_80_6.0_1.0_1.0", 5)))
-
-    val wordDictionary = Map("333333_7.0_0.0_1.0" -> 0,
-      "1111111_6.0_3.0_5.0" -> 1,
-      "-1_43_7.0_2.0_6.0" -> 2,
-      "-1_80_6.0_1.0_1.0" -> 3)
-
-    val distinctDocument = documentWordData.map({case SpotLDACInput(doc, word, count) => doc}).distinct.collect()
-
-    val model = SpotLDACWrapper.createModel(documentWordData, wordDictionary, distinctDocument)
-
-    model should contain ("2 0:8 3:5")
-    model should contain ("1 1:4")
-    model should contain ("1 2:2")
-    model shouldBe Array("2 0:8 3:5", "1 1:4", "1 2:2")
-
-  }
-
-  "getDocumentResults" should "return Array[String] of documents and its 20 values when the sum of each value in the line is bigger" +
-    "than 0. Each result value should be divided by the sum of all values and the result array order should be the same" +
-    "as incomming data (topicDocument Data)" in {
-    val topicCount = 20
-    val documentDictionary = Map(3 -> "10.10.98.123", 0 -> "66.23.45.11", 1 -> "192.168.1.1", 2 -> "133.546.43.22")
-    val topicDocumentData = Array("0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 " +
-      "0.0124531442 0.0124531442 0.0124531442 0.0124531442 23983.5532262138 0.0124531442 0.0124531442 0.0124531442 " +
-      "0.0124531442 0.0124531442 0.0124531442 22999.4716800747 0.0124531442",
-    "0.0124531442 0.0124531442 45583.9162803520 0.0124531442 24896.2502172987 0.0124531442 0.0124531442 0.0124531442 " +
-      "38659.6152616495 0.0124531442 0.0124531442 0.0124531442 0.0124531442 64804.4886288180 25162.0192468565 " +
-      "0.0124531442 0.0124531442 36361.7850838895 0.0124531442 0.0124531442",
-    "0.0124531442 0.0124531442 53816.0629371489 0.0124531442 24404.5440320289 0.0124531442 0.0124531442 0.0124531442 " +
-      "28303.9934577136 0.0124531442 0.0124531442 0.0124531442 0.0124531442 71151.8773513492 26093.1297387104 " +
-      "0.0124531442 0.0124531442 29142.4672019139 0.0124531442 0.0124531442",
-    "0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 " +
-      "0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 0.0124531442 12.0124531442 " +
-      "0.0124531442 0.0124531442 0.0124531442 0.0124531442")
-
-<<<<<<< HEAD:src/test/scala/org/opennetworkinsight/OniLDACWrapperTest.scala
-    val results = OniLDACWrapper.getDocumentResults(topicDocumentData, documentDictionary, topicCount)
-=======
-    val results = SpotLDACWrapper.getDocumentResults(topicDocumentData, documentDictionary)
->>>>>>> 1692d2101cb1fbb424e34ae0e8cd395a1de0d502:src/test/scala/org/apache/spot/SpotLDACWrapperTest.scala
-
-    results("66.23.45.11") shouldBe Array(2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7,
-      2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7,
-      2.6505498126219955E-7, 2.6505498126219955E-7, 0.5104702996191969, 2.6505498126219955E-7, 2.6505498126219955E-7,
-      2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 2.6505498126219955E-7, 0.48952492939114034, 2.6505498126219955E-7)
-
-    results("192.168.1.1") shouldBe Array(5.28867235797652E-8, 5.28867235797652E-8, 0.19358837746391266, 5.28867235797652E-8,
-      0.10573081643228267, 5.28867235797652E-8, 5.28867235797652E-8, 5.28867235797652E-8, 0.1641818606776375, 5.28867235797652E-8,
-      5.28867235797652E-8, 5.28867235797652E-8, 5.28867235797652E-8, 0.27521540117076093, 0.10685949951637365, 5.28867235797652E-8,
-      5.28867235797652E-8, 0.15442330432490242, 5.28867235797652E-8, 5.28867235797652E-8)
-
-    results("133.546.43.22") shouldBe Array(5.346710724792232E-8, 5.346710724792232E-8, 0.2310572464680428, 5.346710724792232E-8,
-      0.1047799938827603, 5.346710724792232E-8, 5.346710724792232E-8, 5.346710724792232E-8, 0.12152213364300919, 5.346710724792232E-8,
-      5.346710724792232E-8, 5.346710724792232E-8, 5.346710724792232E-8, 0.30548791503077616, 0.11202987324065357, 5.346710724792232E-8,
-      5.346710724792232E-8, 0.12512208919525633, 5.346710724792232E-8, 5.346710724792232E-8)
-
-    results("10.10.98.123") shouldBe Array(0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624,
-      0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624,
-      0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624,
-      0.0010166609738175624, 0.9806834414974662, 0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624, 0.0010166609738175624)
-  }
-
-  "getWordResults" should "return Array[String] with 20 elements and N word probability. The result array should have the" +
-    "same order as the input data (topicWordData)" in {
-
-    val wordDictionary = Map("-1_23.0_7.0_7.0_4.0" -> 3, "23.0_7.0_7.0_4.0" -> 0, "333333.0_7.0_7.0_4.0" -> 2, "80.0_7.0_7.0_4.0" -> 1)
-    val topicWordData = Array("-15.3937807051 -536.5105632673 -532.4503365466 -10.8318318078",
-    "-532.7002781469 -447.4890465231 -525.1690620213 -13.9180467610",
-    "-19.5667065907 -5.4442353782 -8.0252973255 -12.4288410371",
-    "-537.3544437825 -15.4983056878 -22.4722439197 -14.7817718408",
-    "-13.3791705206 -5.3657121205 -9.6286562391 -10.8083455362",
-    "-539.4466499733 -535.9756606126 -122.4199569787 -535.7615756409",
-    "-14.9824699328 -532.0369117371 -527.9766850251 -11.1874512926",
-    "-15.1889345209 -534.5750685563 -530.5148418392 -13.5374760178",
-    "-20.4194054373 -5.3920297886 -9.0613037095 -11.5228207125",
-    "-16.7232163605 -533.1029777067 -529.0427509894 -11.7742458954",
-    "-15.4319201624 -533.2550983208 -529.1948716024 -10.7487557143",
-    "-536.2164790868 -532.7454897639 -528.6852629847 -532.5314047894",
-    "-14.9148351018 -535.3169147724 -531.2566880561 -10.9572759378",
-    "-19.2062800183 -5.8636196300 -8.3638265558 -10.6807087581",
-    "-20.4589237180 -5.2246884025 -8.1727002832 -10.7430483178",
-    "-341.6123784319 -339.5204175204 -337.1106321483 -339.3909978330",
-    "-534.8483200081 -531.3773307914 -527.3171040363 -17.0420121428",
-    "-19.9682608636 -5.4274731739 -8.0755820355 -12.0653946611",
-    "-535.7333037656 -532.2623144682 -528.2020876890 -532.0482294927",
-    "-18.4350359818 -534.4612736041 -530.4010468817 -11.0784977885")
-
-    val results = SpotLDACWrapper.getWordToProbPerTopicMap(topicWordData, wordDictionary)
-
-    results.keySet.size shouldBe 4
-    results("23.0_7.0_7.0_4.0").length shouldBe 20
-    results("23.0_7.0_7.0_4.0")(0) shouldBe 0.010333787125924218
-    results("23.0_7.0_7.0_4.0")(19) shouldBe 6.379973716629045E-4
-    results("-1_23.0_7.0_7.0_4.0")(0) shouldBe 0.9896662128740757
-    results("-1_23.0_7.0_7.0_4.0")(19) shouldBe 0.9993620026283371
-  }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-ml/src/test/scala/org/apache/spot/SpotLDAWrapperTest.scala
----------------------------------------------------------------------
diff --git a/spot-ml/src/test/scala/org/apache/spot/SpotLDAWrapperTest.scala b/spot-ml/src/test/scala/org/apache/spot/SpotLDAWrapperTest.scala
new file mode 100644
index 0000000..70fb89c
--- /dev/null
+++ b/spot-ml/src/test/scala/org/apache/spot/SpotLDAWrapperTest.scala
@@ -0,0 +1,140 @@
+package org.apache.spot
+
+import org.apache.log4j.{Level, LogManager}
+import org.apache.spark.mllib.linalg.{Matrices, Vector, Vectors}
+import org.apache.spark.rdd.RDD
+import org.apache.spark.sql.{DataFrame, SQLContext}
+import org.apache.spot.lda.SpotLDAWrapperSchema._
+import org.apache.spot.lda.SpotLDAWrapper
+import org.apache.spot.lda.SpotLDAWrapper._
+import org.apache.spot.testutils.TestingSparkContextFlatSpec
+import org.scalatest.Matchers
+
+import scala.collection.immutable.Map
+
+class SpotLDAWrapperTest extends TestingSparkContextFlatSpec with Matchers {
+
+  val ldaAlpha = 1.02
+  val ldaBeta = 1.001
+  val ldaMaxiterations = 20
+
+  "SparkLDA" should "handle an extremely unbalanced two word doc" in {
+    val logger = LogManager.getLogger("SuspiciousConnectsAnalysis")
+    logger.setLevel(Level.INFO)
+    val testSqlContext = new org.apache.spark.sql.SQLContext(sparkContext)
+
+    val catFancy = SpotLDAInput("pets", "cat", 1)
+    val dogWorld = SpotLDAInput("pets", "dog", 999)
+
+    val data = sparkContext.parallelize(Seq(catFancy, dogWorld))
+    val out = SpotLDAWrapper.runLDA(sparkContext, testSqlContext, data, 2, logger, Some(0xdeadbeef), ldaAlpha, ldaBeta, ldaMaxiterations)
+
+    val topicMixDF = out.docToTopicMix
+
+    var topicMix =
+      topicMixDF.filter(topicMixDF(DocumentName) === "pets").select(TopicProbabilityMix).first().toSeq(0).asInstanceOf[Seq[Double]].toArray
+    val catTopics = out.wordResults("cat")
+    val dogTopics = out.wordResults("dog")
+
+    Math.abs(topicMix(0) * catTopics(0) + topicMix(1) * catTopics(1)) should be < 0.01
+    Math.abs(0.999 - (topicMix(0) * dogTopics(0) + topicMix(1) * dogTopics(1))) should be < 0.01
+  }
+
+  "SparkLDA" should "handle distinct docs on distinct words" in {
+    val logger = LogManager.getLogger("SuspiciousConnectsAnalysis")
+    logger.setLevel(Level.INFO)
+    val testSqlContext = new org.apache.spark.sql.SQLContext(sparkContext)
+
+    val catFancy = SpotLDAInput("cat fancy", "cat", 1)
+    val dogWorld = SpotLDAInput("dog world", "dog", 1)
+
+    val data = sparkContext.parallelize(Seq(catFancy, dogWorld))
+    val out = SpotLDAWrapper.runLDA(sparkContext, testSqlContext, data, 2, logger, Some(0xdeadbeef), ldaAlpha, ldaBeta, ldaMaxiterations)
+
+    val topicMixDF = out.docToTopicMix
+    var dogTopicMix: Array[Double] =
+      topicMixDF.filter(topicMixDF(DocumentName) === "dog world").select(TopicProbabilityMix).first().toSeq(0).asInstanceOf[Seq[Double]].toArray
+
+    val catTopicMix: Array[Double] =
+      topicMixDF.filter(topicMixDF(DocumentName) === "cat fancy").select(TopicProbabilityMix).first().toSeq(0).asInstanceOf[Seq[Double]].toArray
+
+    val catTopics = out.wordResults("cat")
+    val dogTopics = out.wordResults("dog")
+
+    Math.abs(1 - (catTopicMix(0) * catTopics(0) + catTopicMix(1) * catTopics(1))) should be < 0.01
+    Math.abs(1 - (dogTopicMix(0) * dogTopics(0) + dogTopicMix(1) * dogTopics(1))) should be < 0.01
+  }
+
+  "formatSparkLDAInput" should "return input in RDD[(Long, Vector)] (collected as Array for testing) format. The index " +
+    "is the docID, values are the vectors of word occurrences in that doc" in {
+
+    val sqlContext = new SQLContext(sparkContext)
+    import sqlContext.implicits._
+
+    val documentWordData = sparkContext.parallelize(Array(SpotLDAInput("192.168.1.1", "333333_7.0_0.0_1.0", 8),
+      SpotLDAInput("10.10.98.123", "1111111_6.0_3.0_5.0", 4),
+      SpotLDAInput("66.23.45.11", "-1_43_7.0_2.0_6.0", 2),
+      SpotLDAInput("192.168.1.1", "-1_80_6.0_1.0_1.0", 5)))
+
+    val wordDictionary = Map("333333_7.0_0.0_1.0" -> 0, "1111111_6.0_3.0_5.0" -> 1, "-1_43_7.0_2.0_6.0" -> 2, "-1_80_6.0_1.0_1.0" -> 3)
+
+    val documentDictionary: DataFrame = {
+      documentWordData
+        .map({ case SpotLDAInput(doc, word, count) => doc })
+        .distinct
+        .zipWithIndex
+        .toDF(DocumentName, DocumentNumber)
+    }
+
+    val sparkLDAInput: RDD[(Long, Vector)] = SpotLDAWrapper.formatSparkLDAInput(documentWordData, documentDictionary, wordDictionary, sqlContext)
+    val sparkLDAInArr: Array[(Long, Vector)] = sparkLDAInput.collect()
+
+    sparkLDAInArr shouldBe Array((0, Vectors.sparse(4, Array(0, 3), Array(8.0, 5.0))), (2, Vectors.sparse(4, Array(2), Array(2.0))), (1, Vectors.sparse(4, Array(1), Array(4.0))))
+  }
+
+  "formatSparkLDADocTopicOuptut" should "return RDD[(String,Array(Double))] after converting doc results from vector: " +
+    "convert docID back to string, convert vector of probabilities to array" in {
+
+    val sqlContext = new SQLContext(sparkContext)
+    import sqlContext.implicits._
+
+    val documentWordData = sparkContext.parallelize(Array(SpotLDAInput("192.168.1.1", "333333_7.0_0.0_1.0", 8),
+      SpotLDAInput("10.10.98.123", "1111111_6.0_3.0_5.0", 4),
+      SpotLDAInput("66.23.45.11", "-1_43_7.0_2.0_6.0", 2),
+      SpotLDAInput("192.168.1.1", "-1_80_6.0_1.0_1.0", 5)))
+
+    val documentDictionary: DataFrame = {
+      documentWordData
+        .map({ case SpotLDAInput(doc, word, count) => doc })
+        .distinct
+        .zipWithIndex
+        .toDF(DocumentName, DocumentNumber)
+    }
+
+    val docTopicDist: RDD[(Long, Vector)] = sparkContext.parallelize(Array((0.toLong, Vectors.dense(0.15, 0.3, 0.5, 0.05)), (1.toLong,
+      Vectors.dense(0.25, 0.15, 0.4, 0.2)), (2.toLong, Vectors.dense(0.4, 0.1, 0.3, 0.2))))
+
+    val sparkDocRes: DataFrame = formatSparkLDADocTopicOutput(docTopicDist, documentDictionary, sqlContext)
+
+    val documents = sparkDocRes.select(DocumentName).map(documentName => documentName.toString.replaceAll("\\[", "").replaceAll("\\]", "")).collect()
+
+    documents(0) should be("10.10.98.123")
+    documents(1) should be("192.168.1.1")
+    documents(2) should be("66.23.45.11")
+  }
+
+  "formatSparkLDAWordOutput" should "return Map[Int,String] after converting word matrix to sequence, wordIDs back to strings, and sequence of probabilities to array" in {
+    val testMat = Matrices.dense(4, 4, Array(0.5, 0.2, 0.05, 0.25, 0.25, 0.1, 0.15, 0.5, 0.1, 0.4, 0.25, 0.25, 0.7, 0.2, 0.02, 0.08))
+
+    val wordDictionary = Map("-1_23.0_7.0_7.0_4.0" -> 3, "23.0_7.0_7.0_4.0" -> 0, "333333.0_7.0_7.0_4.0" -> 2, "80.0_7.0_7.0_4.0" -> 1)
+    val revWordMap: Map[Int, String] = wordDictionary.map(_.swap)
+
+    val sparkWordRes = formatSparkLDAWordOutput(testMat, revWordMap)
+
+    sparkWordRes should contain key ("23.0_7.0_7.0_4.0")
+    sparkWordRes should contain key ("80.0_7.0_7.0_4.0")
+    sparkWordRes should contain key ("333333.0_7.0_7.0_4.0")
+    sparkWordRes should contain key ("-1_23.0_7.0_7.0_4.0")
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/39a376c8/spot-setup/spot.conf
----------------------------------------------------------------------
diff --git a/spot-setup/spot.conf b/spot-setup/spot.conf
index f393689..8f60eb1 100755
--- a/spot-setup/spot.conf
+++ b/spot-setup/spot.conf
@@ -40,14 +40,3 @@ SPAK_EXEC_MEM_OVERHEAD=''
 TOL='1e-6'
 
 
-# MPI configuration
-
-# command to run MPI
-MPI_CMD='mpiexec'
-
-# command to prepare system for MPI, eg. load environment variables
-MPI_PREP_CMD=''
-
-# number of processes to run in MPI
-PROCESS_COUNT=20
-


[17/50] [abbrv] incubator-spot git commit: Cleaned up the code removing an unused function

Posted by ev...@apache.org.
Cleaned up the code removing an unused function


Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/9597dd1a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/9597dd1a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/9597dd1a

Branch: refs/heads/master
Commit: 9597dd1ac936e803931576436c89da758068790d
Parents: 8f9f05a
Author: LedaLima <ll...@llimagar-mac01.local>
Authored: Mon Nov 28 11:17:14 2016 -0600
Committer: LedaLima <ll...@llimagar-mac01.local>
Committed: Mon Nov 28 11:17:14 2016 -0600

----------------------------------------------------------------------
 spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb | 3 ---
 1 file changed, 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/9597dd1a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
index 3fd5d65..acab173 100644
--- a/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
+++ b/spot-oa/oa/flow/ipynb_templates/Threat_Investigation_master.ipynb
@@ -540,9 +540,6 @@
     "        top_twoway_b.update(top_twoway_conns) # merge the two dictionaries\n",
     "\n",
     "def display_results(cols, dataframe, top):    \n",
-    "    return display_as_html_table(cols, dataframe, top) \n",
-    "\n",
-    "def display_as_html_table(cols, dataframe, top):\n",
     "    table = dataframe[:top].to_html(classes='table table-striped table-bordered table-hover', columns=cols, index=False)\n",
     "    return widgets.HTML(value=table, width='100%')\n",
     "            \n",


[34/50] [abbrv] incubator-spot git commit: Merge pull request #151 from Open-Network-Insight/spot_flow_TI_search_bugfix

Posted by ev...@apache.org.
Merge pull request #151 from Open-Network-Insight/spot_flow_TI_search_bugfix

Removed saved connection from list after clicking 'save' button

Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/88a2ddaa
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/88a2ddaa
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/88a2ddaa

Branch: refs/heads/master
Commit: 88a2ddaa5bb6303d8c6757cd3ecefc897509d84c
Parents: 6bcf408 ad8839f
Author: LedaLima <ga...@intel.com>
Authored: Thu Dec 1 09:34:41 2016 -0800
Committer: GitHub <no...@github.com>
Committed: Thu Dec 1 09:34:41 2016 -0800

----------------------------------------------------------------------
 .../Threat_Investigation_master.ipynb           | 31 ++++++++------------
 1 file changed, 12 insertions(+), 19 deletions(-)
----------------------------------------------------------------------



[12/50] [abbrv] incubator-spot git commit: Fix pipeline typo

Posted by ev...@apache.org.
Fix pipeline typo

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

Branch: refs/heads/master
Commit: ea52d1280bb437e2c6206b790783e5db331f7a8a
Parents: f3b7da5
Author: Everardo Lopez Sandoval <ev...@intel.com>
Authored: Wed Nov 23 16:54:15 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Wed Nov 23 16:54:15 2016 -0600

----------------------------------------------------------------------
 spot-ingest/pipelines/dns/collector.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/ea52d128/spot-ingest/pipelines/dns/collector.py
----------------------------------------------------------------------
diff --git a/spot-ingest/pipelines/dns/collector.py b/spot-ingest/pipelines/dns/collector.py
index 1eae7d2..496011c 100755
--- a/spot-ingest/pipelines/dns/collector.py
+++ b/spot-ingest/pipelines/dns/collector.py
@@ -83,7 +83,7 @@ class Collector(object):
 
 def ingest_file(file,pkt_num,pcap_split_staging, partition,hdfs_root_path,topic,kafka_servers):
 
-    logger = logging.getLogger('SPOT.INGEST.FLOW.{0}'.format(os.getpid()))
+    logger = logging.getLogger('SPOT.INGEST.DNS.{0}'.format(os.getpid()))
     
     try:
         # get file name and date.


[14/50] [abbrv] incubator-spot git commit: Netflow Storyboard: Clear frames after user moves to a different date (#144)

Posted by ev...@apache.org.
Netflow Storyboard: Clear frames after user moves to a different date (#144)

* Netflow Storyboard: Clear frames after user moves to a different date

* Netflow Storyboard: Fixed charts not updating after resize events


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

Branch: refs/heads/master
Commit: dcdf0caef010b9d9b2911393e00562dd3378dc90
Parents: ea52d12
Author: daortizh <di...@intel.com>
Authored: Fri Nov 25 16:07:32 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Fri Nov 25 16:07:32 2016 -0600

----------------------------------------------------------------------
 .../flow/js/components/GlobeViewPanel.react.js  | 42 ++++++++------
 .../js/components/ImpactAnalysisPanel.react.js  | 59 +++++++++++---------
 .../IncidentProgressionPanel.react.js           | 31 +++++-----
 .../flow/js/components/TimelinePanel.react.js   | 15 ++---
 .../ui/flow/js/constants/NetflowConstants.js    |  6 +-
 spot-oa/ui/flow/js/stores/GlobeViewStore.js     | 45 +++------------
 .../ui/flow/js/stores/ImpactAnalysisStore.js    | 57 +++++--------------
 .../flow/js/stores/IncidentProgressionStore.js  | 57 +++++--------------
 spot-oa/ui/flow/js/stores/TimelineStore.js      | 19 +++----
 spot-oa/ui/js/components/ChartMixin.react.js    |  7 ++-
 .../ui/js/components/DendrogramMixin.react.js   | 12 ++--
 spot-oa/ui/js/stores/JsonStore.js               |  2 +-
 12 files changed, 145 insertions(+), 207 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/dcdf0cae/spot-oa/ui/flow/js/components/GlobeViewPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/components/GlobeViewPanel.react.js b/spot-oa/ui/flow/js/components/GlobeViewPanel.react.js
index 0f3db43..d96bdd7 100755
--- a/spot-oa/ui/flow/js/components/GlobeViewPanel.react.js
+++ b/spot-oa/ui/flow/js/components/GlobeViewPanel.react.js
@@ -53,7 +53,13 @@ function buildGraph(root, ipsrc) {
         .attr("height", height)
         .on("mousedown", mousedown);
 
-    $('svg', ReactDOM.findDOMNode(this)).off('parentUpdate').on('parentUpdate', () => buildGraph.call(this, root, ipsrc));
+    function resizeHandler() {
+        buildGraph.call(this, root, ipsrc);
+    }
+
+    window.removeEventListener('resize', resizeHandler.bind(this));
+    window.addEventListener('resize', resizeHandler.bind(this));
+    $('svg', ReactDOM.findDOMNode(this)).off('parentUpdate').on('parentUpdate', resizeHandler.bind(this));
 
     queue()
         .defer(d3.json, "../flow/world-110m.json")
@@ -286,25 +292,23 @@ var GlobeViewPanel = React.createClass({
     },
     _onChange: function ()
     {
-        var state, filterName, root;
-
-        state = GlobeViewStore.getData();
+        const storeData = GlobeViewStore.getData();
 
-        root = {
-            name: GlobeViewStore.getFilterValue(),
-            children: []
+        const state ={
+            loading: storeData.loading
         };
 
-        if (!state.loading)
-        {
-            filterName = GlobeViewStore.getFilterName();
-            root.children = state.data;
+        if (storeData.error) {
+            state.error = storeData.error;
+        }
+        else if(!storeData.loading && storeData.data) {
+            state.root = {
+                name: GlobeViewStore.getIp(),
+                children: storeData.data
+            };
         }
 
-        state.root = root;
-        delete state.data;
-
-        this.setState(state);
+        this.replaceState(state);
     },
     getInitialState: function ()
     {
@@ -342,8 +346,12 @@ var GlobeViewPanel = React.createClass({
     {
         if (!this.state.loading && !this.state.error)
         {
-
-          buildGraph.call(this, this.state.root);
+            if (this.state.root) {
+                buildGraph.call(this, this.state.root);
+            }
+            else {
+                d3.select(ReactDOM.findDOMNode(this)).selectAll('*').remove();
+            }
         }
     }
 });

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/dcdf0cae/spot-oa/ui/flow/js/components/ImpactAnalysisPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/components/ImpactAnalysisPanel.react.js b/spot-oa/ui/flow/js/components/ImpactAnalysisPanel.react.js
index be8c84e..e490c5d 100755
--- a/spot-oa/ui/flow/js/components/ImpactAnalysisPanel.react.js
+++ b/spot-oa/ui/flow/js/components/ImpactAnalysisPanel.react.js
@@ -29,7 +29,14 @@ function buildGraph(root, ipsrc)
         .append("svg:g")
         .attr("transform", "translate(" + m[3] + "," + m[0] + ")");
 
-    $('svg', ReactDOM.findDOMNode(this)).off('parentUpdate').on('parentUpdate', () => buildGraph.call(this, root, ipsrc));
+    function resizeHandler() {
+        buildGraph.call(this, root, ipsrc);
+    }
+
+    window.removeEventListener('resize', resizeHandler.bind(this));
+    window.addEventListener('resize', resizeHandler.bind(this));
+
+    $('svg', ReactDOM.findDOMNode(this)).off('parentUpdate').on('parentUpdate', resizeHandler.bind(this));
 
     svg.append("svg:rect")
         .attr("class", "background")
@@ -217,34 +224,29 @@ var ImpactAnalysisPanel = React.createClass({
     },
     _onChange: function ()
     {
-        var state, filterName, root;
-
-        state = ImpactAnalysisStore.getData();
+        const storeData = ImpactAnalysisStore.getData();
 
-        root = {
-            name: ImpactAnalysisStore.getFilterValue(),
-            size: 0,
-            children: []
-        };
+        const state = {loading: storeData.loading};
 
-        if (!state.loading)
-        {
-            filterName = ImpactAnalysisStore.getFilterName();
-
-            state.data.children.forEach(function (item)
-            {
-                root.children.push({
-                    name: item['name'],
-                    size: item['size'],
-                    children: item['children']
-                });
-            }.bind(this));
+        if (storeData.error) {
+            state.error = storeData.error;
+        }
+        else if(!storeData.loading && storeData.data) {
+            state.root = {
+                name: ImpactAnalysisStore.getIp(),
+                size: 0
+            };
+
+            state.root.children = storeData.data.children.map((item) => {
+                return {
+                    name: item.name,
+                    size: item.size,
+                    children: item.children
+                };
+            });
         }
 
-        state.root = root;
-        delete state.data;
-
-        this.setState(state);
+        this.replaceState(state);
     },
     getInitialState: function ()
     {
@@ -282,7 +284,12 @@ var ImpactAnalysisPanel = React.createClass({
     {
         if (!this.state.loading && !this.state.error)
         {
-          buildGraph.call(this, this.state.root);
+          if (this.state.root) {
+              buildGraph.call(this, this.state.root);
+          }
+          else {
+              d3.select(ReactDOM.findDOMNode(this)).selectAll('*').remove();
+          }
         }
     }
 });

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/dcdf0cae/spot-oa/ui/flow/js/components/IncidentProgressionPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/components/IncidentProgressionPanel.react.js b/spot-oa/ui/flow/js/components/IncidentProgressionPanel.react.js
index 310ca63..2eb8469 100755
--- a/spot-oa/ui/flow/js/components/IncidentProgressionPanel.react.js
+++ b/spot-oa/ui/flow/js/components/IncidentProgressionPanel.react.js
@@ -18,29 +18,30 @@ const IncidentProgressionPanel = React.createClass({
     _onChange: function ()
     {
         const storeData = IncidentProgressionStore.getData();
-        const state = {loading: storeData.loading};
-
-        state.data = {
-            id: 'root',
-            name: IncidentProgressionStore.getFilterValue(),
-            children: []
+        const state = {
+            loading: storeData.loading
         };
 
-        if (!state.loading)
-        {
-            let filterName = IncidentProgressionStore.getFilterName();
+        if (storeData.error) {
+            state.error = storeData.error;
+        }
+        else if(!storeData.loading && storeData.data) {
+            state.data = {
+                id: 'root',
+                name: IncidentProgressionStore.getIp()
+            };
 
-            state.leafNodes = 0;
-            storeData.data.children.forEach((item) => {
-                state.data.children.push({
-                    id: `node${++state.leafNodes}`,
+            state.leafNodes = storeData.data.children.length;
+            state.data.children = storeData.data.children.map((item, idx) => {
+                return {
+                    id: `node${idx}`,
                     name: item['name'],
                     children: item['children']
-                });
+                };
             });
         }
 
-        this.setState(state);
+        this.replaceState(state);
     }
 });
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/dcdf0cae/spot-oa/ui/flow/js/components/TimelinePanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/components/TimelinePanel.react.js b/spot-oa/ui/flow/js/components/TimelinePanel.react.js
index 8bc931a..6762b78 100755
--- a/spot-oa/ui/flow/js/components/TimelinePanel.react.js
+++ b/spot-oa/ui/flow/js/components/TimelinePanel.react.js
@@ -18,14 +18,15 @@ const TimelineChart = React.createClass({
     _onChange() {
         const storeData = TimelineStore.getData();
 
-        if (storeData.loading || storeData.error) {
-            this.setState(storeData);
+        let state = {loading: storeData.loading};
+        if (storeData.error) {
+            state.error = storeData.error;
         }
-        else {
-            const state = this._getStateFromStoreData(storeData.data);
-
-            this.setState(state);
+        else if (!storeData.loading && storeData.data.length) {
+            state = this._getStateFromStoreData(storeData.data);
         }
+
+        this.replaceState(state);
     },
     _getStateFromStoreData(data)
     {
@@ -63,7 +64,7 @@ const TimelineChart = React.createClass({
             array of object values. Turn objects into arrays
         */
 
-        const skipedIp = TimelineStore.getFilter();
+        const skipedIp = TimelineStore.getIp();
         data.forEach(item => {
             [
                 {ipField:'srcip', portField:'sport'},

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/dcdf0cae/spot-oa/ui/flow/js/constants/NetflowConstants.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/constants/NetflowConstants.js b/spot-oa/ui/flow/js/constants/NetflowConstants.js
index bf1e5f9..cb7ffb2 100755
--- a/spot-oa/ui/flow/js/constants/NetflowConstants.js
+++ b/spot-oa/ui/flow/js/constants/NetflowConstants.js
@@ -9,10 +9,10 @@ var NetflowConstants = {
   API_DETAILS: '../../data/flow/${date}/edge-${src_ip}-${dst_ip}-${time}.tsv',
   API_VISUAL_DETAILS: '../../data/flow/${date}/chord-${ip}.tsv',
   API_COMMENTS: '../../data/flow/${date}/threats.csv',
-  API_INCIDENT_PROGRESSION: '../../data/flow/${date}/threat-dendro-${id}.json',
+  API_INCIDENT_PROGRESSION: '../../data/flow/${date}/threat-dendro-${ip}.json',
   API_INGEST_SUMMARY: '../../data/flow/ingest_summary/is_${year}${month}.csv',
-  API_IMPACT_ANALYSIS: '../../data/flow/${date}/stats-${id}.json',
-  API_GLOBE_VIEW: '../../data/flow/${date}/globe-${id}.json',
+  API_IMPACT_ANALYSIS: '../../data/flow/${date}/stats-${ip}.json',
+  API_GLOBE_VIEW: '../../data/flow/${date}/globe-${ip}.json',
   API_TIMELINE: '../../data/flow/${date}/sbdet-${ip}.tsv',
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/dcdf0cae/spot-oa/ui/flow/js/stores/GlobeViewStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/stores/GlobeViewStore.js b/spot-oa/ui/flow/js/stores/GlobeViewStore.js
index 7e60c59..7a5d4e7 100755
--- a/spot-oa/ui/flow/js/stores/GlobeViewStore.js
+++ b/spot-oa/ui/flow/js/stores/GlobeViewStore.js
@@ -5,8 +5,7 @@ var FlowConstants = require('../constants/NetflowConstants');
 var SpotConstants = require('../../../js/constants/SpotConstants');
 var JsonStore = require('../../../js/stores/JsonStore');
 
-var fields = ['title', 'summary'];
-var filterName;
+const IP_FILTER_NAME = 'ip';
 
 var GlobeViewStore = assign(new JsonStore(FlowConstants.API_GLOBE_VIEW), {
     errorMessages: {
@@ -16,28 +15,19 @@ var GlobeViewStore = assign(new JsonStore(FlowConstants.API_GLOBE_VIEW), {
     {
         this.setEndpoint(FlowConstants.API_GLOBE_VIEW.replace('${date}', date.replace(/-/g, '')));
     },
-    setFilter: function (name, value)
+    setIp: function (value)
     {
-        filterName = name;
-        this.setRestFilter('id', value);
+        this.setRestFilter(IP_FILTER_NAME, value);
     },
-    getFilterName: function ()
+    getIp: function ()
     {
-        return filterName;
-    },
-    getFilterValue: function ()
-    {
-        return this.getRestFilter('id');
+        return this.getRestFilter(IP_FILTER_NAME);
     },
     setData: function (data)
     {
         this._data = data;
 
         this.emitChangeData();
-    },
-    clearFilter: function ()
-    {
-       this.removeRestFilter('id');
     }
 });
 
@@ -47,28 +37,11 @@ SpotDispatcher.register(function (action) {
             GlobeViewStore.setDate(action.date);
 
             break;
+        case SpotConstants.RELOAD_COMMENTS:
+            GlobeViewStore.resetData();
+            break;
         case SpotConstants.SELECT_COMMENT:
-            var comment, filterParts, key;
-
-            GlobeViewStore.clearFilter();
-
-            comment = action.comment;
-
-            filterParts = [];
-
-            for (key in comment)
-            {
-                // Skip comment fields
-                if (fields.indexOf(key)>=0) continue;
-
-                if (comment[key])
-                {
-                    GlobeViewStore.setFilter(key, comment[key]);
-
-                    break;
-                }
-            }
-
+            GlobeViewStore.setIp(action.comment.ip);
             GlobeViewStore.reload();
 
             break;

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/dcdf0cae/spot-oa/ui/flow/js/stores/ImpactAnalysisStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/stores/ImpactAnalysisStore.js b/spot-oa/ui/flow/js/stores/ImpactAnalysisStore.js
index e2cc1e9..b07e483 100755
--- a/spot-oa/ui/flow/js/stores/ImpactAnalysisStore.js
+++ b/spot-oa/ui/flow/js/stores/ImpactAnalysisStore.js
@@ -1,14 +1,13 @@
-var assign = require('object-assign');
+const assign = require('object-assign');
 
-var SpotDispatcher = require('../../../js/dispatchers/SpotDispatcher');
-var FlowConstants = require('../constants/NetflowConstants');
-var SpotConstants = require('../../../js/constants/SpotConstants');
-var RestStore = require('../../../js/stores/JsonStore');
+const SpotDispatcher = require('../../../js/dispatchers/SpotDispatcher');
+const FlowConstants = require('../constants/NetflowConstants');
+const SpotConstants = require('../../../js/constants/SpotConstants');
+const JsonStore = require('../../../js/stores/JsonStore');
 
-var fields = ['title', 'summary'];
-var filterName;
+const IP_FILTER_NAME = 'ip';
 
-var ImpactAnalysisStore = assign(new RestStore(FlowConstants.API_IMPACT_ANALYSIS), {
+const ImpactAnalysisStore = assign(new JsonStore(FlowConstants.API_IMPACT_ANALYSIS), {
     errorMessages: {
         404: 'Please choose a different date, no data has been found'
     },
@@ -16,22 +15,13 @@ var ImpactAnalysisStore = assign(new RestStore(FlowConstants.API_IMPACT_ANALYSIS
     {
         this.setEndpoint(FlowConstants.API_IMPACT_ANALYSIS.replace('${date}', date.replace(/-/g, '')));
     },
-    setFilter: function (name, value)
+    setIp(value)
     {
-        filterName = name;
-        this.setRestFilter('id', value);
+        this.setRestFilter(IP_FILTER_NAME, value);
     },
-    getFilterName: function ()
+    getIp()
     {
-        return filterName;
-    },
-    getFilterValue: function ()
-    {
-        return this.getRestFilter('id');
-    },
-    clearFilter: function ()
-    {
-       this.removeRestFilter('id');
+        this.getRestFilter(IP_FILTER_NAME);
     }
 });
 
@@ -41,28 +31,11 @@ SpotDispatcher.register(function (action) {
             ImpactAnalysisStore.setDate(action.date);
 
             break;
+        case SpotConstants.RELOAD_COMMENTS:
+            ImpactAnalysisStore.resetData();
+            break;
         case SpotConstants.SELECT_COMMENT:
-            var comment, filterParts, key;
-
-            ImpactAnalysisStore.clearFilter();
-
-            comment = action.comment;
-
-            filterParts = [];
-
-            for (key in comment)
-            {
-                // Skip comment fields
-                if (fields.indexOf(key)>=0) continue;
-
-                if (comment[key])
-                {
-                    ImpactAnalysisStore.setFilter(key, comment[key]);
-
-                    break;
-                }
-            }
-
+            ImpactAnalysisStore.setIp(action.comment.ip);
             ImpactAnalysisStore.reload();
 
             break;

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/dcdf0cae/spot-oa/ui/flow/js/stores/IncidentProgressionStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/stores/IncidentProgressionStore.js b/spot-oa/ui/flow/js/stores/IncidentProgressionStore.js
index 433305f..36410f4 100755
--- a/spot-oa/ui/flow/js/stores/IncidentProgressionStore.js
+++ b/spot-oa/ui/flow/js/stores/IncidentProgressionStore.js
@@ -1,14 +1,13 @@
-var assign = require('object-assign');
+const assign = require('object-assign');
 
-var SpotDispatcher = require('../../../js/dispatchers/SpotDispatcher');
-var SpotConstants = require('../../../js/constants/SpotConstants');
-var FlowConstants = require('../constants/NetflowConstants');
-var RestStore = require('../../../js/stores/JsonStore');
+const SpotDispatcher = require('../../../js/dispatchers/SpotDispatcher');
+const SpotConstants = require('../../../js/constants/SpotConstants');
+const FlowConstants = require('../constants/NetflowConstants');
+const JsonStore = require('../../../js/stores/JsonStore');
 
-var fields = ['title', 'summary'];
-var filterName;
+const IP_FILTER_NAME = 'ip';
 
-var IncidentProgressionStore = assign(new RestStore(FlowConstants.API_INCIDENT_PROGRESSION), {
+const IncidentProgressionStore = assign(new JsonStore(FlowConstants.API_INCIDENT_PROGRESSION), {
     errorMessages: {
         404: 'Please choose a different date, no data has been found'
     },
@@ -16,22 +15,13 @@ var IncidentProgressionStore = assign(new RestStore(FlowConstants.API_INCIDENT_P
     {
         this.setEndpoint(FlowConstants.API_INCIDENT_PROGRESSION.replace('${date}', date.replace(/-/g, '')));
     },
-    setFilter: function (name, value)
+    setIp: function (value)
     {
-        filterName = name;
-        this.setRestFilter('id', value);
+        this.setRestFilter(IP_FILTER_NAME, value);
     },
-    getFilterName: function ()
+    getIp: function ()
     {
-        return filterName;
-    },
-    getFilterValue: function ()
-    {
-        return this.getRestFilter('id');
-    },
-    clearFilter: function ()
-    {
-       this.removeRestFilter('id');
+        return this.getRestFilter(IP_FILTER_NAME);
     }
 });
 
@@ -40,28 +30,11 @@ SpotDispatcher.register(function (action) {
         case SpotConstants.UPDATE_DATE:
             IncidentProgressionStore.setDate(action.date);
             break;
+        case SpotConstants.RELOAD_COMMENTS:
+            IncidentProgressionStore.resetData();
+            break;
         case SpotConstants.SELECT_COMMENT:
-            var comment, filterParts, key;
-
-            IncidentProgressionStore.clearFilter();
-
-            comment = action.comment;
-
-            filterParts = [];
-
-            for (key in comment)
-            {
-                // Skip comment fields
-                if (fields.indexOf(key)>=0) continue;
-
-                if (comment[key])
-                {
-                    IncidentProgressionStore.setFilter(key, comment[key]);
-
-                    break;
-                }
-            }
-
+            IncidentProgressionStore.setIp(action.comment.ip);
             IncidentProgressionStore.reload();
 
             break;

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/dcdf0cae/spot-oa/ui/flow/js/stores/TimelineStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/flow/js/stores/TimelineStore.js b/spot-oa/ui/flow/js/stores/TimelineStore.js
index 0309d14..4ea9d3d 100755
--- a/spot-oa/ui/flow/js/stores/TimelineStore.js
+++ b/spot-oa/ui/flow/js/stores/TimelineStore.js
@@ -6,7 +6,7 @@ const FlowConstants = require('../constants/NetflowConstants');
 const SpotConstants = require('../../../js/constants/SpotConstants');
 const RestStore = require('../../../js/stores/RestStore');
 
-const FILTER_NAME = 'ip';
+const IP_FILTER_NAME = 'ip';
 
 const TimelineStore = assign(new RestStore(FlowConstants.API_TIMELINE), {
     _parser: d3.tsv,
@@ -21,17 +21,13 @@ const TimelineStore = assign(new RestStore(FlowConstants.API_TIMELINE), {
     getDate() {
         return this._date;
     },
-    setFilter: function (value)
+    setIp: function (value)
     {
-        this.setRestFilter(FILTER_NAME, value);
+        this.setRestFilter(IP_FILTER_NAME, value);
     },
-    getFilter: function ()
+    getIp: function ()
     {
-        return this.getRestFilter(FILTER_NAME);
-    },
-    clearFilter: function ()
-    {
-       this.removeRestFilter(FILTER_NAME);
+        return this.getRestFilter(IP_FILTER_NAME);
     }
 });
 
@@ -42,8 +38,11 @@ SpotDispatcher.register(function (action) {
             TimelineStore.setDate(action.date);
 
             break;
+        case SpotConstants.RELOAD_COMMENTS:
+            TimelineStore.resetData();
+            break;
         case SpotConstants.SELECT_COMMENT:
-            TimelineStore.setFilter(action.comment.ip);
+            TimelineStore.setIp(action.comment.ip);
 
             TimelineStore.reload();
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/dcdf0cae/spot-oa/ui/js/components/ChartMixin.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/components/ChartMixin.react.js b/spot-oa/ui/js/components/ChartMixin.react.js
index dc623e8..af3e537 100755
--- a/spot-oa/ui/js/components/ChartMixin.react.js
+++ b/spot-oa/ui/js/components/ChartMixin.react.js
@@ -1,6 +1,7 @@
-var React = require('react');
+const React = require('react');
+const $ = require('jquery');
 
-var ChartMixin = {
+const ChartMixin = {
     propTypes: {
         className: React.PropTypes.string
     },
@@ -10,7 +11,7 @@ var ChartMixin = {
         };
     },
     componentWillUpdate() {
-        window.removeEventListener('resize', this._onViewportResize);
+        window.removeEventListener('resize', this.draw);
         if (this.svg) {
             $(this.svg).off('parentUpdate');
         }

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/dcdf0cae/spot-oa/ui/js/components/DendrogramMixin.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/components/DendrogramMixin.react.js b/spot-oa/ui/js/components/DendrogramMixin.react.js
index 7630a81..37fa323 100755
--- a/spot-oa/ui/js/components/DendrogramMixin.react.js
+++ b/spot-oa/ui/js/components/DendrogramMixin.react.js
@@ -45,8 +45,7 @@ var DendrogramMixin = {
       nodeSel.exit = nodeSel.update.exit();
 
       const nodeEl = nodeSel.enter.append('g')
-                                .attr('class', n => `node depth_${n.depth}`)
-                                .attr('transform', n => `translate(${n.y},${n.x})`);
+                                .attr('class', n => `node depth_${n.depth}`);
 
       nodeEl.append('circle')
                         .attr('r', 4.5)
@@ -70,6 +69,8 @@ var DendrogramMixin = {
                       .attr('fill', 'black')
                       .text(n => n.name);
 
+    nodeSel.update.attr('transform', n => `translate(${n.y},${n.x})`);
+
     nodeSel.exit.remove();
   },
   drawLinks(links) {
@@ -82,7 +83,6 @@ var DendrogramMixin = {
 
       linkSel.enter.append('path', '.node')
         .attr('class', 'link')
-        .attr('d', this.diagonal)
         .on('mouseover', function (l)
         {
             d3.select(this)
@@ -104,8 +104,10 @@ var DendrogramMixin = {
                         .style('fill', null);
       });
 
-    // Remove old nodes
-    linkSel.exit.remove();
+      linkSel.update.attr('d', this.diagonal);
+
+      // Remove old nodes
+      linkSel.exit.remove();
   }
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/dcdf0cae/spot-oa/ui/js/stores/JsonStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/JsonStore.js b/spot-oa/ui/js/stores/JsonStore.js
index 60b2a08..7c79e4d 100755
--- a/spot-oa/ui/js/stores/JsonStore.js
+++ b/spot-oa/ui/js/stores/JsonStore.js
@@ -79,7 +79,7 @@ assign(JsonStore.prototype, EventEmitter.prototype, {
             error: function (response)
             {
                 this.setData({error: this.errorMessages[response.status] || this.defaultErrorMessage});
-            }          
+            }
         });
     }
 });


[02/50] [abbrv] incubator-spot git commit: Spot ui colors (#138)

Posted by ev...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/css/bootstrap-spot.min.css
----------------------------------------------------------------------
diff --git a/spot-oa/ui/css/bootstrap-spot.min.css b/spot-oa/ui/css/bootstrap-spot.min.css
new file mode 100644
index 0000000..02e78bf
--- /dev/null
+++ b/spot-oa/ui/css/bootstrap-spot.min.css
@@ -0,0 +1,1484 @@
+/*! Generated by Live LESS Theme Customizer */
+.label,sub,sup{vertical-align:baseline}
+body,figure{margin:0}
+.d3-tip:after,.form-control-feedback,a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}
+.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.pre-scrollable{max-height:340px}
+html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;font-size:10px;-webkit-tap-highlight-color:transparent}
+article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}
+audio,canvas,progress,video{display:inline-block;vertical-align:baseline}
+audio:not([controls]){display:none;height:0}
+[hidden],template{display:none}
+a{background-color:transparent}
+a:active,a:hover{outline:0}
+b,optgroup,strong{font-weight:700}
+dfn{font-style:italic}
+h1{margin:.67em 0}
+mark{background:#ff0;color:#000}
+sub,sup{font-size:75%;line-height:0;position:relative}
+sup{top:-.5em}
+sub{bottom:-.25em}
+img{border:0;vertical-align:middle}
+svg:not(:root){overflow:hidden}
+hr{box-sizing:content-box;height:0}
+pre,textarea{overflow:auto}
+code,kbd,pre,samp{font-size:1em}
+button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}
+button{overflow:visible}
+button,select{text-transform:none}
+button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}
+button[disabled],html input[disabled]{cursor:default}
+button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
+input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}
+input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}
+input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}
+table{border-collapse:collapse;border-spacing:0}
+td,th{padding:0}
+@media print{blockquote,img,pre,tr{page-break-inside:avoid}
+*,:after,:before{background:0 0!important;color:#000!important;box-shadow:none!important;text-shadow:none!important}
+a,a:visited{text-decoration:underline}
+a[href]:after{content:" (" attr(href) ")"}
+abbr[title]:after{content:" (" attr(title) ")"}
+a[href^="javascript:"]:after,a[href^="#"]:after{content:""}
+blockquote,pre{border:1px solid #999}
+thead{display:table-header-group}
+img{max-width:100%!important}
+h2,h3,p{orphans:3;widows:3}
+h2,h3{page-break-after:avoid}
+.navbar{display:none}
+.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}
+.label{border:1px solid #000}
+.table{border-collapse:collapse!important}
+.table td,.table th{background-color:#fff!important}
+.table-bordered td,.table-bordered th{border:1px solid #ddd!important}
+}
+.img-thumbnail,body{background-color:#fff}
+.btn,.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-warning.active,.btn-warning:active,.btn.active,.btn:active,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover,.form-control,.navbar-toggle,.open>.dropdown-toggle.btn-danger,.open>.dropdown-toggle.btn-default,.open>.dropdown-toggle.btn-info,.open>.dropdown-toggle.btn-primary,.open>.dropdown-toggle.btn-warning{background-image:none}
+@font-face{font-family:'Glyphicons Halflings';src:url(../node_modules/bootstrap/fonts/glyphicons-halflings-regular.eot);src:url(../node_modules/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../node_modules/bootstrap/fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../node_modules/bootstrap/fonts/glyphicons-halflings-regular.woff) format('woff'),url(../node_modules/bootstrap/fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../node_modules/bootstrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}
+.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
+.glyphicon-asterisk:before{content:"\2a"}
+.glyphicon-plus:before{content:"\2b"}
+.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}
+.glyphicon-minus:before{content:"\2212"}
+.glyphicon-cloud:before{content:"\2601"}
+.glyphicon-envelope:before{content:"\2709"}
+.glyphicon-pencil:before{content:"\270f"}
+.glyphicon-glass:before{content:"\e001"}
+.glyphicon-music:before{content:"\e002"}
+.glyphicon-search:before{content:"\e003"}
+.glyphicon-heart:before{content:"\e005"}
+.glyphicon-star:before{content:"\e006"}
+.glyphicon-star-empty:before{content:"\e007"}
+.glyphicon-user:before{content:"\e008"}
+.glyphicon-film:before{content:"\e009"}
+.glyphicon-th-large:before{content:"\e010"}
+.glyphicon-th:before{content:"\e011"}
+.glyphicon-th-list:before{content:"\e012"}
+.glyphicon-ok:before{content:"\e013"}
+.glyphicon-remove:before{content:"\e014"}
+.glyphicon-zoom-in:before{content:"\e015"}
+.glyphicon-zoom-out:before{content:"\e016"}
+.glyphicon-off:before{content:"\e017"}
+.glyphicon-signal:before{content:"\e018"}
+.glyphicon-cog:before{content:"\e019"}
+.glyphicon-trash:before{content:"\e020"}
+.glyphicon-home:before{content:"\e021"}
+.glyphicon-file:before{content:"\e022"}
+.glyphicon-time:before{content:"\e023"}
+.glyphicon-road:before{content:"\e024"}
+.glyphicon-download-alt:before{content:"\e025"}
+.glyphicon-download:before{content:"\e026"}
+.glyphicon-upload:before{content:"\e027"}
+.glyphicon-inbox:before{content:"\e028"}
+.glyphicon-play-circle:before{content:"\e029"}
+.glyphicon-repeat:before{content:"\e030"}
+.glyphicon-refresh:before{content:"\e031"}
+.glyphicon-list-alt:before{content:"\e032"}
+.glyphicon-lock:before{content:"\e033"}
+.glyphicon-flag:before{content:"\e034"}
+.glyphicon-headphones:before{content:"\e035"}
+.glyphicon-volume-off:before{content:"\e036"}
+.glyphicon-volume-down:before{content:"\e037"}
+.glyphicon-volume-up:before{content:"\e038"}
+.glyphicon-qrcode:before{content:"\e039"}
+.glyphicon-barcode:before{content:"\e040"}
+.glyphicon-tag:before{content:"\e041"}
+.glyphicon-tags:before{content:"\e042"}
+.glyphicon-book:before{content:"\e043"}
+.glyphicon-bookmark:before{content:"\e044"}
+.glyphicon-print:before{content:"\e045"}
+.glyphicon-camera:before{content:"\e046"}
+.glyphicon-font:before{content:"\e047"}
+.glyphicon-bold:before{content:"\e048"}
+.glyphicon-italic:before{content:"\e049"}
+.glyphicon-text-height:before{content:"\e050"}
+.glyphicon-text-width:before{content:"\e051"}
+.glyphicon-align-left:before{content:"\e052"}
+.glyphicon-align-center:before{content:"\e053"}
+.glyphicon-align-right:before{content:"\e054"}
+.glyphicon-align-justify:before{content:"\e055"}
+.glyphicon-list:before{content:"\e056"}
+.glyphicon-indent-left:before{content:"\e057"}
+.glyphicon-indent-right:before{content:"\e058"}
+.glyphicon-facetime-video:before{content:"\e059"}
+.glyphicon-picture:before{content:"\e060"}
+.glyphicon-map-marker:before{content:"\e062"}
+.glyphicon-adjust:before{content:"\e063"}
+.glyphicon-tint:before{content:"\e064"}
+.glyphicon-edit:before{content:"\e065"}
+.glyphicon-share:before{content:"\e066"}
+.glyphicon-check:before{content:"\e067"}
+.glyphicon-move:before{content:"\e068"}
+.glyphicon-step-backward:before{content:"\e069"}
+.glyphicon-fast-backward:before{content:"\e070"}
+.glyphicon-backward:before{content:"\e071"}
+.glyphicon-play:before{content:"\e072"}
+.glyphicon-pause:before{content:"\e073"}
+.glyphicon-stop:before{content:"\e074"}
+.glyphicon-forward:before{content:"\e075"}
+.glyphicon-fast-forward:before{content:"\e076"}
+.glyphicon-step-forward:before{content:"\e077"}
+.glyphicon-eject:before{content:"\e078"}
+.glyphicon-chevron-left:before{content:"\e079"}
+.glyphicon-chevron-right:before{content:"\e080"}
+.glyphicon-plus-sign:before{content:"\e081"}
+.glyphicon-minus-sign:before{content:"\e082"}
+.glyphicon-remove-sign:before{content:"\e083"}
+.glyphicon-ok-sign:before{content:"\e084"}
+.glyphicon-question-sign:before{content:"\e085"}
+.glyphicon-info-sign:before{content:"\e086"}
+.glyphicon-screenshot:before{content:"\e087"}
+.glyphicon-remove-circle:before{content:"\e088"}
+.glyphicon-ok-circle:before{content:"\e089"}
+.glyphicon-ban-circle:before{content:"\e090"}
+.glyphicon-arrow-left:before{content:"\e091"}
+.glyphicon-arrow-right:before{content:"\e092"}
+.glyphicon-arrow-up:before{content:"\e093"}
+.glyphicon-arrow-down:before{content:"\e094"}
+.glyphicon-share-alt:before{content:"\e095"}
+.glyphicon-resize-full:before{content:"\e096"}
+.glyphicon-resize-small:before{content:"\e097"}
+.glyphicon-exclamation-sign:before{content:"\e101"}
+.glyphicon-gift:before{content:"\e102"}
+.glyphicon-leaf:before{content:"\e103"}
+.glyphicon-fire:before{content:"\e104"}
+.glyphicon-eye-open:before{content:"\e105"}
+.glyphicon-eye-close:before{content:"\e106"}
+.glyphicon-warning-sign:before{content:"\e107"}
+.glyphicon-plane:before{content:"\e108"}
+.glyphicon-calendar:before{content:"\e109"}
+.glyphicon-random:before{content:"\e110"}
+.glyphicon-comment:before{content:"\e111"}
+.glyphicon-magnet:before{content:"\e112"}
+.glyphicon-chevron-up:before{content:"\e113"}
+.glyphicon-chevron-down:before{content:"\e114"}
+.glyphicon-retweet:before{content:"\e115"}
+.glyphicon-shopping-cart:before{content:"\e116"}
+.glyphicon-folder-close:before{content:"\e117"}
+.glyphicon-folder-open:before{content:"\e118"}
+.glyphicon-resize-vertical:before{content:"\e119"}
+.glyphicon-resize-horizontal:before{content:"\e120"}
+.glyphicon-hdd:before{content:"\e121"}
+.glyphicon-bullhorn:before{content:"\e122"}
+.glyphicon-bell:before{content:"\e123"}
+.glyphicon-certificate:before{content:"\e124"}
+.glyphicon-thumbs-up:before{content:"\e125"}
+.glyphicon-thumbs-down:before{content:"\e126"}
+.glyphicon-hand-right:before{content:"\e127"}
+.glyphicon-hand-left:before{content:"\e128"}
+.glyphicon-hand-up:before{content:"\e129"}
+.glyphicon-hand-down:before{content:"\e130"}
+.glyphicon-circle-arrow-right:before{content:"\e131"}
+.glyphicon-circle-arrow-left:before{content:"\e132"}
+.glyphicon-circle-arrow-up:before{content:"\e133"}
+.glyphicon-circle-arrow-down:before{content:"\e134"}
+.glyphicon-globe:before{content:"\e135"}
+.glyphicon-wrench:before{content:"\e136"}
+.glyphicon-tasks:before{content:"\e137"}
+.glyphicon-filter:before{content:"\e138"}
+.glyphicon-briefcase:before{content:"\e139"}
+.glyphicon-fullscreen:before{content:"\e140"}
+.glyphicon-dashboard:before{content:"\e141"}
+.glyphicon-paperclip:before{content:"\e142"}
+.glyphicon-heart-empty:before{content:"\e143"}
+.glyphicon-link:before{content:"\e144"}
+.glyphicon-phone:before{content:"\e145"}
+.glyphicon-pushpin:before{content:"\e146"}
+.glyphicon-usd:before{content:"\e148"}
+.glyphicon-gbp:before{content:"\e149"}
+.glyphicon-sort:before{content:"\e150"}
+.glyphicon-sort-by-alphabet:before{content:"\e151"}
+.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}
+.glyphicon-sort-by-order:before{content:"\e153"}
+.glyphicon-sort-by-order-alt:before{content:"\e154"}
+.glyphicon-sort-by-attributes:before{content:"\e155"}
+.glyphicon-sort-by-attributes-alt:before{content:"\e156"}
+.glyphicon-unchecked:before{content:"\e157"}
+.glyphicon-expand:before{content:"\e158"}
+.glyphicon-collapse-down:before{content:"\e159"}
+.glyphicon-collapse-up:before{content:"\e160"}
+.glyphicon-log-in:before{content:"\e161"}
+.glyphicon-flash:before{content:"\e162"}
+.glyphicon-log-out:before{content:"\e163"}
+.glyphicon-new-window:before{content:"\e164"}
+.glyphicon-record:before{content:"\e165"}
+.glyphicon-save:before{content:"\e166"}
+.glyphicon-open:before{content:"\e167"}
+.glyphicon-saved:before{content:"\e168"}
+.glyphicon-import:before{content:"\e169"}
+.glyphicon-export:before{content:"\e170"}
+.glyphicon-send:before{content:"\e171"}
+.glyphicon-floppy-disk:before{content:"\e172"}
+.glyphicon-floppy-saved:before{content:"\e173"}
+.glyphicon-floppy-remove:before{content:"\e174"}
+.glyphicon-floppy-save:before{content:"\e175"}
+.glyphicon-floppy-open:before{content:"\e176"}
+.glyphicon-credit-card:before{content:"\e177"}
+.glyphicon-transfer:before{content:"\e178"}
+.glyphicon-cutlery:before{content:"\e179"}
+.glyphicon-header:before{content:"\e180"}
+.glyphicon-compressed:before{content:"\e181"}
+.glyphicon-earphone:before{content:"\e182"}
+.glyphicon-phone-alt:before{content:"\e183"}
+.glyphicon-tower:before{content:"\e184"}
+.glyphicon-stats:before{content:"\e185"}
+.glyphicon-sd-video:before{content:"\e186"}
+.glyphicon-hd-video:before{content:"\e187"}
+.glyphicon-subtitles:before{content:"\e188"}
+.glyphicon-sound-stereo:before{content:"\e189"}
+.glyphicon-sound-dolby:before{content:"\e190"}
+.glyphicon-sound-5-1:before{content:"\e191"}
+.glyphicon-sound-6-1:before{content:"\e192"}
+.glyphicon-sound-7-1:before{content:"\e193"}
+.glyphicon-copyright-mark:before{content:"\e194"}
+.glyphicon-registration-mark:before{content:"\e195"}
+.glyphicon-cloud-download:before{content:"\e197"}
+.glyphicon-cloud-upload:before{content:"\e198"}
+.glyphicon-tree-conifer:before{content:"\e199"}
+.glyphicon-tree-deciduous:before{content:"\e200"}
+.glyphicon-cd:before{content:"\e201"}
+.glyphicon-save-file:before{content:"\e202"}
+.glyphicon-open-file:before{content:"\e203"}
+.glyphicon-level-up:before{content:"\e204"}
+.glyphicon-copy:before{content:"\e205"}
+.glyphicon-paste:before{content:"\e206"}
+.glyphicon-alert:before{content:"\e209"}
+.glyphicon-equalizer:before{content:"\e210"}
+.glyphicon-king:before{content:"\e211"}
+.glyphicon-queen:before{content:"\e212"}
+.glyphicon-pawn:before{content:"\e213"}
+.glyphicon-bishop:before{content:"\e214"}
+.glyphicon-knight:before{content:"\e215"}
+.glyphicon-baby-formula:before{content:"\e216"}
+.glyphicon-tent:before{content:"\26fa"}
+.glyphicon-blackboard:before{content:"\e218"}
+.glyphicon-bed:before{content:"\e219"}
+.glyphicon-apple:before{content:"\f8ff"}
+.glyphicon-erase:before{content:"\e221"}
+.glyphicon-hourglass:before{content:"\231b"}
+.glyphicon-lamp:before{content:"\e223"}
+.glyphicon-duplicate:before{content:"\e224"}
+.glyphicon-piggy-bank:before{content:"\e225"}
+.glyphicon-scissors:before{content:"\e226"}
+.glyphicon-bitcoin:before,.glyphicon-btc:before,.glyphicon-xbt:before{content:"\e227"}
+.glyphicon-jpy:before,.glyphicon-yen:before{content:"\00a5"}
+.glyphicon-rub:before,.glyphicon-ruble:before{content:"\20bd"}
+.glyphicon-scale:before{content:"\e230"}
+.glyphicon-ice-lolly:before{content:"\e231"}
+.glyphicon-ice-lolly-tasted:before{content:"\e232"}
+.glyphicon-education:before{content:"\e233"}
+.glyphicon-option-horizontal:before{content:"\e234"}
+.glyphicon-option-vertical:before{content:"\e235"}
+.glyphicon-menu-hamburger:before{content:"\e236"}
+.glyphicon-modal-window:before{content:"\e237"}
+.glyphicon-oil:before{content:"\e238"}
+.glyphicon-grain:before{content:"\e239"}
+.glyphicon-sunglasses:before{content:"\e240"}
+.glyphicon-text-size:before{content:"\e241"}
+.glyphicon-text-color:before{content:"\e242"}
+.glyphicon-text-background:before{content:"\e243"}
+.glyphicon-object-align-top:before{content:"\e244"}
+.glyphicon-object-align-bottom:before{content:"\e245"}
+.glyphicon-object-align-horizontal:before{content:"\e246"}
+.glyphicon-object-align-left:before{content:"\e247"}
+.glyphicon-object-align-vertical:before{content:"\e248"}
+.glyphicon-object-align-right:before{content:"\e249"}
+.glyphicon-triangle-right:before{content:"\e250"}
+.glyphicon-triangle-left:before{content:"\e251"}
+.glyphicon-triangle-bottom:before{content:"\e252"}
+.glyphicon-triangle-top:before{content:"\e253"}
+.glyphicon-console:before{content:"\e254"}
+.glyphicon-superscript:before{content:"\e255"}
+.glyphicon-subscript:before{content:"\e256"}
+.glyphicon-menu-left:before{content:"\e257"}
+.glyphicon-menu-right:before{content:"\e258"}
+.glyphicon-menu-down:before{content:"\e259"}
+.glyphicon-menu-up:before{content:"\e260"}
+*,:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}
+body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#82837e}
+button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}
+a{color:#174d72;text-decoration:none}
+a:focus,a:hover{color:#f7a706;text-decoration:underline}
+a:focus{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}
+.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}
+.img-rounded{border-radius:6px}
+.img-thumbnail{padding:4px;line-height:1.42857143;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}
+.img-circle{border-radius:50%}
+hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #d6d4d0}
+.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}
+.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}
+[role=button]{cursor:pointer}
+.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}
+.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#c6c2be}
+.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}
+.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}
+.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}
+.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}
+.h1,h1{font-size:36px}
+.h2,h2{font-size:30px}
+.h3,h3{font-size:24px}
+.h4,h4{font-size:18px}
+.h5,h5{font-size:14px}
+.h6,h6{font-size:12px}
+p{margin:0 0 10px}
+.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}
+address,blockquote .small,blockquote footer,blockquote small,dd,dt,pre{line-height:1.42857143}
+dt,kbd kbd,label{font-weight:700}
+@media (min-width:768px){.lead{font-size:21px}
+}
+.small,small{font-size:85%}
+.mark,mark{background-color:#fcf8e3;padding:.2em}
+.list-inline,.list-unstyled{list-style:none;padding-left:0}
+.text-left{text-align:left}
+.text-right{text-align:right}
+.btn,.text-center{text-align:center}
+.text-justify{text-align:justify}
+.text-nowrap{white-space:nowrap}
+.text-lowercase{text-transform:lowercase}
+.text-uppercase{text-transform:uppercase}
+.text-capitalize{text-transform:capitalize}
+.text-muted{color:#c6c2be}
+.text-primary{color:#174d72}
+a.text-primary:focus,a.text-primary:hover{color:#0e3048}
+.text-success{color:#3c763d}
+a.text-success:focus,a.text-success:hover{color:#2b542c}
+.text-info{color:#31708f}
+a.text-info:focus,a.text-info:hover{color:#245269}
+.text-warning{color:#8a6d3b}
+a.text-warning:focus,a.text-warning:hover{color:#66512c}
+.text-danger{color:#a94442}
+a.text-danger:focus,a.text-danger:hover{color:#843534}
+.bg-primary{color:#fff;background-color:#174d72}
+a.bg-primary:focus,a.bg-primary:hover{background-color:#0e3048}
+.bg-success{background-color:#dff0d8}
+a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}
+.bg-info{background-color:#d9edf7}
+a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}
+.bg-warning{background-color:#fcf8e3}
+a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}
+.bg-danger{background-color:#f2dede}
+a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}
+pre code,table{background-color:transparent}
+.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #d6d4d0}
+dl,ol,ul{margin-top:0}
+ol,ul{margin-bottom:10px}
+ol ol,ol ul,ul ol,ul ul{margin-bottom:0}
+.list-inline{margin-left:-5px}
+.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}
+dl{margin-bottom:20px}
+dd{margin-left:0}
+@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
+.dl-horizontal dd{margin-left:180px}
+}
+abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #c6c2be}
+.initialism{font-size:90%;text-transform:uppercase}
+blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #d6d4d0}
+blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}
+blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;color:#c6c2be}
+blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}
+.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #d6d4d0;border-left:0;text-align:right}
+caption,th{text-align:left}
+code,kbd{padding:2px 4px;font-size:90%}
+.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}
+.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}
+address{margin-bottom:20px;font-style:normal}
+code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}
+code{color:#c7254e;background-color:#f9f2f4;border-radius:4px}
+kbd{color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}
+kbd kbd{padding:0;font-size:100%;box-shadow:none}
+pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;word-break:break-all;word-wrap:break-word;color:#82837e;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}
+.container,.container-fluid{margin-right:auto;margin-left:auto}
+pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;border-radius:0}
+.container,.container-fluid{padding-left:15px;padding-right:15px}
+.pre-scrollable{overflow-y:scroll}
+@media (min-width:768px){.container{width:750px}
+}
+@media (min-width:992px){.container{width:970px}
+}
+@media (min-width:1200px){.container{width:1170px}
+}
+.row{margin-left:-15px;margin-right:-15px}
+.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-left:15px;padding-right:15px}
+.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}
+.col-xs-12{width:100%}
+.col-xs-11{width:91.66666667%}
+.col-xs-10{width:83.33333333%}
+.col-xs-9{width:75%}
+.col-xs-8{width:66.66666667%}
+.col-xs-7{width:58.33333333%}
+.col-xs-6{width:50%}
+.col-xs-5{width:41.66666667%}
+.col-xs-4{width:33.33333333%}
+.col-xs-3{width:25%}
+.col-xs-2{width:16.66666667%}
+.col-xs-1{width:8.33333333%}
+.col-xs-pull-12{right:100%}
+.col-xs-pull-11{right:91.66666667%}
+.col-xs-pull-10{right:83.33333333%}
+.col-xs-pull-9{right:75%}
+.col-xs-pull-8{right:66.66666667%}
+.col-xs-pull-7{right:58.33333333%}
+.col-xs-pull-6{right:50%}
+.col-xs-pull-5{right:41.66666667%}
+.col-xs-pull-4{right:33.33333333%}
+.col-xs-pull-3{right:25%}
+.col-xs-pull-2{right:16.66666667%}
+.col-xs-pull-1{right:8.33333333%}
+.col-xs-pull-0{right:auto}
+.col-xs-push-12{left:100%}
+.col-xs-push-11{left:91.66666667%}
+.col-xs-push-10{left:83.33333333%}
+.col-xs-push-9{left:75%}
+.col-xs-push-8{left:66.66666667%}
+.col-xs-push-7{left:58.33333333%}
+.col-xs-push-6{left:50%}
+.col-xs-push-5{left:41.66666667%}
+.col-xs-push-4{left:33.33333333%}
+.col-xs-push-3{left:25%}
+.col-xs-push-2{left:16.66666667%}
+.col-xs-push-1{left:8.33333333%}
+.col-xs-push-0{left:auto}
+.col-xs-offset-12{margin-left:100%}
+.col-xs-offset-11{margin-left:91.66666667%}
+.col-xs-offset-10{margin-left:83.33333333%}
+.col-xs-offset-9{margin-left:75%}
+.col-xs-offset-8{margin-left:66.66666667%}
+.col-xs-offset-7{margin-left:58.33333333%}
+.col-xs-offset-6{margin-left:50%}
+.col-xs-offset-5{margin-left:41.66666667%}
+.col-xs-offset-4{margin-left:33.33333333%}
+.col-xs-offset-3{margin-left:25%}
+.col-xs-offset-2{margin-left:16.66666667%}
+.col-xs-offset-1{margin-left:8.33333333%}
+.col-xs-offset-0{margin-left:0}
+@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}
+.col-sm-12{width:100%}
+.col-sm-11{width:91.66666667%}
+.col-sm-10{width:83.33333333%}
+.col-sm-9{width:75%}
+.col-sm-8{width:66.66666667%}
+.col-sm-7{width:58.33333333%}
+.col-sm-6{width:50%}
+.col-sm-5{width:41.66666667%}
+.col-sm-4{width:33.33333333%}
+.col-sm-3{width:25%}
+.col-sm-2{width:16.66666667%}
+.col-sm-1{width:8.33333333%}
+.col-sm-pull-12{right:100%}
+.col-sm-pull-11{right:91.66666667%}
+.col-sm-pull-10{right:83.33333333%}
+.col-sm-pull-9{right:75%}
+.col-sm-pull-8{right:66.66666667%}
+.col-sm-pull-7{right:58.33333333%}
+.col-sm-pull-6{right:50%}
+.col-sm-pull-5{right:41.66666667%}
+.col-sm-pull-4{right:33.33333333%}
+.col-sm-pull-3{right:25%}
+.col-sm-pull-2{right:16.66666667%}
+.col-sm-pull-1{right:8.33333333%}
+.col-sm-pull-0{right:auto}
+.col-sm-push-12{left:100%}
+.col-sm-push-11{left:91.66666667%}
+.col-sm-push-10{left:83.33333333%}
+.col-sm-push-9{left:75%}
+.col-sm-push-8{left:66.66666667%}
+.col-sm-push-7{left:58.33333333%}
+.col-sm-push-6{left:50%}
+.col-sm-push-5{left:41.66666667%}
+.col-sm-push-4{left:33.33333333%}
+.col-sm-push-3{left:25%}
+.col-sm-push-2{left:16.66666667%}
+.col-sm-push-1{left:8.33333333%}
+.col-sm-push-0{left:auto}
+.col-sm-offset-12{margin-left:100%}
+.col-sm-offset-11{margin-left:91.66666667%}
+.col-sm-offset-10{margin-left:83.33333333%}
+.col-sm-offset-9{margin-left:75%}
+.col-sm-offset-8{margin-left:66.66666667%}
+.col-sm-offset-7{margin-left:58.33333333%}
+.col-sm-offset-6{margin-left:50%}
+.col-sm-offset-5{margin-left:41.66666667%}
+.col-sm-offset-4{margin-left:33.33333333%}
+.col-sm-offset-3{margin-left:25%}
+.col-sm-offset-2{margin-left:16.66666667%}
+.col-sm-offset-1{margin-left:8.33333333%}
+.col-sm-offset-0{margin-left:0}
+}
+@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}
+.col-md-12{width:100%}
+.col-md-11{width:91.66666667%}
+.col-md-10{width:83.33333333%}
+.col-md-9{width:75%}
+.col-md-8{width:66.66666667%}
+.col-md-7{width:58.33333333%}
+.col-md-6{width:50%}
+.col-md-5{width:41.66666667%}
+.col-md-4{width:33.33333333%}
+.col-md-3{width:25%}
+.col-md-2{width:16.66666667%}
+.col-md-1{width:8.33333333%}
+.col-md-pull-12{right:100%}
+.col-md-pull-11{right:91.66666667%}
+.col-md-pull-10{right:83.33333333%}
+.col-md-pull-9{right:75%}
+.col-md-pull-8{right:66.66666667%}
+.col-md-pull-7{right:58.33333333%}
+.col-md-pull-6{right:50%}
+.col-md-pull-5{right:41.66666667%}
+.col-md-pull-4{right:33.33333333%}
+.col-md-pull-3{right:25%}
+.col-md-pull-2{right:16.66666667%}
+.col-md-pull-1{right:8.33333333%}
+.col-md-pull-0{right:auto}
+.col-md-push-12{left:100%}
+.col-md-push-11{left:91.66666667%}
+.col-md-push-10{left:83.33333333%}
+.col-md-push-9{left:75%}
+.col-md-push-8{left:66.66666667%}
+.col-md-push-7{left:58.33333333%}
+.col-md-push-6{left:50%}
+.col-md-push-5{left:41.66666667%}
+.col-md-push-4{left:33.33333333%}
+.col-md-push-3{left:25%}
+.col-md-push-2{left:16.66666667%}
+.col-md-push-1{left:8.33333333%}
+.col-md-push-0{left:auto}
+.col-md-offset-12{margin-left:100%}
+.col-md-offset-11{margin-left:91.66666667%}
+.col-md-offset-10{margin-left:83.33333333%}
+.col-md-offset-9{margin-left:75%}
+.col-md-offset-8{margin-left:66.66666667%}
+.col-md-offset-7{margin-left:58.33333333%}
+.col-md-offset-6{margin-left:50%}
+.col-md-offset-5{margin-left:41.66666667%}
+.col-md-offset-4{margin-left:33.33333333%}
+.col-md-offset-3{margin-left:25%}
+.col-md-offset-2{margin-left:16.66666667%}
+.col-md-offset-1{margin-left:8.33333333%}
+.col-md-offset-0{margin-left:0}
+}
+@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}
+.col-lg-12{width:100%}
+.col-lg-11{width:91.66666667%}
+.col-lg-10{width:83.33333333%}
+.col-lg-9{width:75%}
+.col-lg-8{width:66.66666667%}
+.col-lg-7{width:58.33333333%}
+.col-lg-6{width:50%}
+.col-lg-5{width:41.66666667%}
+.col-lg-4{width:33.33333333%}
+.col-lg-3{width:25%}
+.col-lg-2{width:16.66666667%}
+.col-lg-1{width:8.33333333%}
+.col-lg-pull-12{right:100%}
+.col-lg-pull-11{right:91.66666667%}
+.col-lg-pull-10{right:83.33333333%}
+.col-lg-pull-9{right:75%}
+.col-lg-pull-8{right:66.66666667%}
+.col-lg-pull-7{right:58.33333333%}
+.col-lg-pull-6{right:50%}
+.col-lg-pull-5{right:41.66666667%}
+.col-lg-pull-4{right:33.33333333%}
+.col-lg-pull-3{right:25%}
+.col-lg-pull-2{right:16.66666667%}
+.col-lg-pull-1{right:8.33333333%}
+.col-lg-pull-0{right:auto}
+.col-lg-push-12{left:100%}
+.col-lg-push-11{left:91.66666667%}
+.col-lg-push-10{left:83.33333333%}
+.col-lg-push-9{left:75%}
+.col-lg-push-8{left:66.66666667%}
+.col-lg-push-7{left:58.33333333%}
+.col-lg-push-6{left:50%}
+.col-lg-push-5{left:41.66666667%}
+.col-lg-push-4{left:33.33333333%}
+.col-lg-push-3{left:25%}
+.col-lg-push-2{left:16.66666667%}
+.col-lg-push-1{left:8.33333333%}
+.col-lg-push-0{left:auto}
+.col-lg-offset-12{margin-left:100%}
+.col-lg-offset-11{margin-left:91.66666667%}
+.col-lg-offset-10{margin-left:83.33333333%}
+.col-lg-offset-9{margin-left:75%}
+.col-lg-offset-8{margin-left:66.66666667%}
+.col-lg-offset-7{margin-left:58.33333333%}
+.col-lg-offset-6{margin-left:50%}
+.col-lg-offset-5{margin-left:41.66666667%}
+.col-lg-offset-4{margin-left:33.33333333%}
+.col-lg-offset-3{margin-left:25%}
+.col-lg-offset-2{margin-left:16.66666667%}
+.col-lg-offset-1{margin-left:8.33333333%}
+.col-lg-offset-0{margin-left:0}
+}
+caption{padding-top:8px;padding-bottom:8px;color:#c6c2be}
+.table{width:100%;max-width:100%;margin-bottom:20px}
+.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}
+.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}
+.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}
+.table>tbody+tbody{border-top:2px solid #ddd}
+.table .table{background-color:#fff}
+.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}
+.table-bordered,.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}
+.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}
+.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}
+.table-hover>tbody>tr:hover,.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}
+table col[class*=col-]{position:static;float:none;display:table-column}
+table td[class*=col-],table th[class*=col-]{position:static;float:none;display:table-cell}
+.btn-group>.btn-group,.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group,.dropdown-menu{float:left}
+.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}
+.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}
+.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}
+.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}
+.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}
+.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}
+.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}
+.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}
+.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}
+.table-responsive{overflow-x:auto;min-height:.01%}
+@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}
+.table-responsive>.table{margin-bottom:0}
+.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}
+.table-responsive>.table-bordered{border:0}
+.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}
+.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}
+.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}
+}
+fieldset,legend{padding:0;border:0}
+fieldset{margin:0;min-width:0}
+legend{display:block;width:100%;margin-bottom:20px;font-size:21px;line-height:inherit;color:#82837e;border-bottom:1px solid #e5e5e5}
+label{display:inline-block;max-width:100%;margin-bottom:5px}
+input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none}
+input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}
+.form-control,output{display:block;font-size:14px;line-height:1.42857143;color:#a3a3a0}
+input[type=file]{display:block}
+input[type=range]{display:block;width:100%}
+select[multiple],select[size]{height:auto}
+input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}
+output{padding-top:7px}
+.form-control{width:100%;height:34px;padding:6px 12px;background-color:#fff;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}
+.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}
+.form-control::-moz-placeholder{color:#999;opacity:1}
+.form-control:-ms-input-placeholder{color:#999}
+.form-control::-webkit-input-placeholder{color:#999}
+.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .form-control-feedback,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}
+.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#d6d4d0;opacity:1}
+.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}
+textarea.form-control{height:auto}
+@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}
+.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}
+.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}
+}
+.form-group{margin-bottom:15px}
+.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}
+.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}
+.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-left:-20px;margin-top:4px\9}
+.checkbox+.checkbox,.radio+.radio{margin-top:-5px}
+.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:400;cursor:pointer}
+.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}
+.checkbox-inline.disabled,.checkbox.disabled label,.radio-inline.disabled,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio label,fieldset[disabled] .radio-inline,fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}
+.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0;min-height:34px}
+.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}
+.form-group-sm .form-control,.input-sm{font-size:12px;padding:5px 10px;border-radius:3px}
+.input-sm{height:30px;line-height:1.5}
+select.input-sm{height:30px;line-height:30px}
+select[multiple].input-sm,textarea.input-sm{height:auto}
+.form-group-sm .form-control{height:30px;line-height:1.5}
+.form-group-sm select.form-control{height:30px;line-height:30px}
+.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}
+.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}
+.form-group-lg .form-control,.input-lg{font-size:18px;padding:10px 16px;border-radius:6px}
+.input-lg{height:46px;line-height:1.3333333}
+select.input-lg{height:46px;line-height:46px}
+select[multiple].input-lg,textarea.input-lg{height:auto}
+.form-group-lg .form-control{height:46px;line-height:1.3333333}
+.form-group-lg select.form-control{height:46px;line-height:46px}
+.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}
+.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}
+.has-feedback{position:relative}
+.has-feedback .form-control{padding-right:42.5px}
+.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center}
+.collapsing,.dropdown,.dropup{position:relative}
+.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}
+.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}
+.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}
+.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}
+.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}
+.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .form-control-feedback,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}
+.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}
+.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}
+.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}
+.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .form-control-feedback,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}
+.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}
+.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}
+.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}
+.has-feedback label~.form-control-feedback{top:25px}
+.has-feedback label.sr-only~.form-control-feedback{top:0}
+.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#c1c1bf}
+@media (min-width:768px){.form-inline .form-control-static,.form-inline .form-group{display:inline-block}
+.form-inline .control-label,.form-inline .form-group{margin-bottom:0;vertical-align:middle}
+.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}
+.form-inline .input-group{display:inline-table;vertical-align:middle}
+.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}
+.form-inline .input-group>.form-control{width:100%}
+.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}
+.form-inline .checkbox label,.form-inline .radio label{padding-left:0}
+.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}
+.form-inline .has-feedback .form-control-feedback{top:0}
+}
+.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{margin-top:0;margin-bottom:0;padding-top:7px}
+.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}
+.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}
+.form-horizontal .has-feedback .form-control-feedback{right:15px}
+@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:7px}
+.form-horizontal .form-group-lg .control-label{padding-top:14.33px;font-size:18px}
+.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}
+}
+.btn{display:inline-block;margin-bottom:0;font-weight:400;vertical-align:middle;touch-action:manipulation;cursor:pointer;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
+.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}
+.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}
+.btn.active,.btn:active{outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}
+.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}
+.btn-default{color:#333;background-color:#fff;border-color:#ccc}
+.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}
+.btn-default.active,.btn-default:active,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}
+.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}
+.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}
+.btn-default .badge{color:#fff;background-color:#333}
+.btn-primary{color:#fff;background-color:#174d72;border-color:#133f5d}
+.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0e3048;border-color:#000}
+.btn-primary.active,.btn-primary:active,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#0e3048;border-color:#081c2a}
+.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#081c2a;border-color:#000}
+.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#174d72;border-color:#133f5d}
+.btn-primary .badge{color:#174d72;background-color:#fff}
+.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}
+.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}
+.btn-success.active,.btn-success:active,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}
+.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}
+.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}
+.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}
+.btn-success .badge{color:#5cb85c;background-color:#fff}
+.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}
+.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}
+.btn-info.active,.btn-info:active,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}
+.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}
+.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}
+.btn-info .badge{color:#5bc0de;background-color:#fff}
+.btn-warning{color:#fff;background-color:#f7a706;border-color:#de9605}
+.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#c58505;border-color:#624202}
+.btn-warning.active,.btn-warning:active,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#c58505;border-color:#a26e04}
+.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#a26e04;border-color:#624202}
+.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f7a706;border-color:#de9605}
+.btn-warning .badge{color:#f7a706;background-color:#fff}
+.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}
+.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}
+.btn-danger.active,.btn-danger:active,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}
+.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}
+.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}
+.btn-danger .badge{color:#d9534f;background-color:#fff}
+.btn-link{color:#174d72;font-weight:400;border-radius:0}
+.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}
+.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}
+.btn-link:focus,.btn-link:hover{color:#f7a706;text-decoration:underline;background-color:transparent}
+.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#c6c2be;text-decoration:none}
+.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}
+.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}
+.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}
+.btn-block{display:block;width:100%}
+.btn-block+.btn-block{margin-top:5px}
+input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}
+.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}
+.fade.in{opacity:1}
+.collapse{display:none}
+.collapse.in{display:block}
+tr.collapse.in{display:table-row}
+tbody.collapse.in{display:table-row-group}
+.collapsing{height:0;overflow:hidden;-webkit-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;transition-timing-function:ease}
+.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}
+.dropdown-toggle:focus{outline:0}
+.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;text-align:left;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}
+.btn-group-vertical>.btn:not(:first-child):not(:last-child),.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn,.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}
+.dropdown-header,.dropdown-menu>li>a{white-space:nowrap;padding:3px 20px;line-height:1.42857143}
+.dropdown-menu-right,.dropdown-menu.pull-right{left:auto;right:0}
+.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}
+.dropdown-menu>li>a{display:block;clear:both;font-weight:400;color:#82837e}
+.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{text-decoration:none;color:#757671;background-color:#f5f5f5}
+.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;outline:0;background-color:#174d72}
+.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#c6c2be}
+.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;background-color:transparent;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}
+.open>.dropdown-menu{display:block}
+.open>a{outline:0}
+.dropdown-menu-left{left:0;right:auto}
+.dropdown-header{display:block;font-size:12px;color:#c6c2be}
+.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}
+.nav-justified>.dropdown .dropdown-menu,.nav-tabs.nav-justified>.dropdown .dropdown-menu{left:auto;top:auto}
+.pull-right>.dropdown-menu{right:0;left:auto}
+.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9;content:""}
+.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}
+@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}
+.navbar-right .dropdown-menu-left{left:0;right:auto}
+}
+.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}
+.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}
+.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}
+.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}
+.btn-toolbar{margin-left:-5px}
+.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}
+.btn .caret,.btn-group>.btn:first-child{margin-left:0}
+.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}
+.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}
+.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}
+.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}
+.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}
+.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}
+.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}
+.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}
+.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}
+.btn-lg .caret{border-width:5px 5px 0}
+.dropup .btn-lg .caret{border-width:0 5px 5px}
+.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}
+.btn-group-vertical>.btn-group>.btn{float:none}
+.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}
+.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}
+.btn-group-vertical>.btn:last-child:not(:first-child){border-bottom-left-radius:4px;border-top-right-radius:0;border-top-left-radius:0}
+.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}
+.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}
+.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}
+.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}
+.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}
+.btn-group-justified>.btn-group .btn{width:100%}
+.btn-group-justified>.btn-group .dropdown-menu{left:auto}
+[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}
+.input-group{position:relative;display:table;border-collapse:separate}
+.input-group[class*=col-]{float:none;padding-left:0;padding-right:0}
+.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}
+.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}
+select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}
+select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}
+.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}
+select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}
+select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}
+.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}
+.nav>li,.nav>li>a{position:relative;display:block}
+.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}
+.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}
+.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#a3a3a0;text-align:center;background-color:#d6d4d0;border:1px solid #ccc;border-radius:4px}
+.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}
+.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}
+.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}
+.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}
+.input-group-addon:first-child{border-right:0}
+.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-bottom-left-radius:0;border-top-left-radius:0}
+.input-group-addon:last-child{border-left:0}
+.input-group-btn{position:relative;font-size:0;white-space:nowrap}
+.input-group-btn>.btn{position:relative}
+.input-group-btn>.btn+.btn{margin-left:-1px}
+.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}
+.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}
+.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}
+.nav{margin-bottom:0;padding-left:0;list-style:none}
+.nav>li>a{padding:10px 15px}
+.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#d6d4d0}
+.nav>li.disabled>a{color:#c6c2be}
+.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#c6c2be;text-decoration:none;background-color:transparent;cursor:not-allowed}
+.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#d6d4d0;border-color:#174d72}
+.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}
+.nav>li>a>img{max-width:none}
+.nav-tabs{border-bottom:1px solid #ddd}
+.nav-tabs>li{float:left;margin-bottom:-1px}
+.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}
+.nav-tabs>li>a:hover{border-color:#d6d4d0 #d6d4d0 #ddd}
+.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#a3a3a0;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}
+.nav-tabs.nav-justified{width:100%;border-bottom:0}
+.nav-tabs.nav-justified>li{float:none}
+.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px;margin-right:0;border-radius:4px}
+.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}
+@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}
+.nav-tabs.nav-justified>li>a{margin-bottom:0;border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}
+.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}
+}
+.nav-pills>li{float:left}
+.nav-justified>li,.nav-stacked>li{float:none}
+.nav-pills>li>a{border-radius:4px}
+.nav-pills>li+li{margin-left:2px}
+.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#174d72}
+.nav-stacked>li+li{margin-top:2px;margin-left:0}
+.nav-justified{width:100%}
+.nav-justified>li>a{text-align:center;margin-bottom:5px}
+.nav-tabs-justified{border-bottom:0}
+.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}
+.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}
+@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}
+.nav-justified>li>a{margin-bottom:0}
+.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}
+.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}
+}
+.tab-content>.tab-pane{display:none}
+.tab-content>.active{display:block}
+.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}
+.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}
+.navbar-collapse{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}
+.navbar-collapse.in{overflow-y:auto}
+@media (min-width:768px){.navbar{border-radius:4px}
+.navbar-header{float:left}
+.navbar-collapse{width:auto;border-top:0;box-shadow:none}
+.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}
+.navbar-collapse.in{overflow-y:visible}
+.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-left:0;padding-right:0}
+}
+.embed-responsive,.modal,.modal-open,.progress{overflow:hidden}
+@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}
+}
+.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}
+.navbar-static-top{z-index:1000;border-width:0 0 1px}
+.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}
+.navbar-fixed-top{top:0;border-width:0 0 1px}
+.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}
+.navbar-brand{float:left;padding:15px;font-size:18px;line-height:20px;height:50px}
+.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}
+.navbar-brand>img{display:block}
+@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}
+.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}
+.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}
+}
+.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;border:1px solid transparent;border-radius:4px}
+.navbar-toggle:focus{outline:0}
+.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}
+.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}
+.navbar-nav{margin:7.5px -15px}
+.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}
+@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}
+.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}
+.navbar-nav .open .dropdown-menu>li>a{line-height:20px}
+.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}
+}
+.progress-bar-striped,.progress-striped .progress-bar,.progress-striped .progress-bar-danger,.progress-striped .progress-bar-info,.progress-striped .progress-bar-success,.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}
+@media (min-width:768px){.navbar-toggle{display:none}
+.navbar-nav{float:left;margin:0}
+.navbar-nav>li{float:left}
+.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}
+}
+.navbar-form{padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);margin:8px -15px}
+@media (min-width:768px){.navbar-form .form-control-static,.navbar-form .form-group{display:inline-block}
+.navbar-form .control-label,.navbar-form .form-group{margin-bottom:0;vertical-align:middle}
+.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}
+.navbar-form .input-group{display:inline-table;vertical-align:middle}
+.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}
+.navbar-form .input-group>.form-control{width:100%}
+.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}
+.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}
+.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}
+.navbar-form .has-feedback .form-control-feedback{top:0}
+}
+.btn .badge,.btn .label{position:relative;top:-1px}
+.breadcrumb>li,.pagination{display:inline-block}
+@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}
+.navbar-form .form-group:last-child{margin-bottom:0}
+}
+@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}
+}
+.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}
+.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-radius:4px 4px 0 0}
+.navbar-btn{margin-top:8px;margin-bottom:8px}
+.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}
+.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}
+.navbar-text{margin-top:15px;margin-bottom:15px}
+@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}
+.navbar-left{float:left!important}
+.navbar-right{float:right!important;margin-right:-15px}
+.navbar-right~.navbar-right{margin-right:0}
+}
+.navbar-default{background-color:#174d72;border-color:#113a56}
+.navbar-default .navbar-brand{color:#e8e5e0}
+.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#e8e5e0;background-color:transparent}
+.navbar-default .navbar-text{color:#e0e0e0}
+.navbar-default .navbar-nav>li>a{color:#c6c2be}
+.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#f7a706;background-color:transparent}
+.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#f7a706;background-color:#113a56}
+.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#82837e;background-color:transparent}
+.navbar-default .navbar-toggle{border-color:#ddd}
+.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}
+.navbar-default .navbar-toggle .icon-bar{background-color:#888}
+.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#113a56}
+.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{background-color:#113a56;color:#f7a706}
+@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#c6c2be}
+.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#f7a706;background-color:transparent}
+.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#f7a706;background-color:#113a56}
+.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#82837e;background-color:transparent}
+}
+.navbar-default .navbar-link{color:#c6c2be}
+.navbar-default .navbar-link:hover{color:#f7a706}
+.navbar-default .btn-link{color:#c6c2be}
+.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#f7a706}
+.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#82837e}
+.navbar-inverse{background-color:#222;border-color:#080808}
+.navbar-inverse .navbar-brand{color:#eae8e7}
+.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}
+.navbar-inverse .navbar-nav>li>a,.navbar-inverse .navbar-text{color:#eae8e7}
+.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#f7a706;background-color:transparent}
+.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#f7a706;background-color:#080808}
+.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}
+.navbar-inverse .navbar-toggle{border-color:#333}
+.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}
+.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}
+.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}
+.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{background-color:#080808;color:#f7a706}
+@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}
+.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}
+.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#eae8e7}
+.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#f7a706;background-color:transparent}
+.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#f7a706;background-color:#080808}
+.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}
+}
+.navbar-inverse .navbar-link{color:#eae8e7}
+.navbar-inverse .navbar-link:hover{color:#f7a706}
+.navbar-inverse .btn-link{color:#eae8e7}
+.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#f7a706}
+.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}
+.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}
+.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#ccc}
+.breadcrumb>.active{color:#c6c2be}
+.pagination{padding-left:0;margin:20px 0;border-radius:4px}
+.pager li,.pagination>li{display:inline}
+.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857143;text-decoration:none;color:#174d72;background-color:#fff;border:1px solid #ddd;margin-left:-1px}
+.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}
+.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}
+.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:3;color:#f7a706;background-color:#d6d4d0;border-color:#ddd}
+.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;background-color:#174d72;border-color:#174d72;cursor:default}
+.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#c6c2be;background-color:#fff;border-color:#ddd;cursor:not-allowed}
+.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}
+.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}
+.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}
+.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}
+.badge,.label{text-align:center;font-weight:700;line-height:1;white-space:nowrap}
+.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}
+.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}
+.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}
+.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}
+.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#d6d4d0}
+.pager .next>a,.pager .next>span{float:right}
+.pager .previous>a,.pager .previous>span{float:left}
+.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#c6c2be;background-color:#fff;cursor:not-allowed}
+.label{display:inline;padding:.2em .6em .3em;font-size:75%;color:#fff;border-radius:.25em}
+a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}
+.label:empty{display:none}
+.label-default{background-color:#c6c2be}
+.label-default[href]:focus,.label-default[href]:hover{background-color:#aea8a3}
+.label-primary{background-color:#174d72}
+.label-primary[href]:focus,.label-primary[href]:hover{background-color:#0e3048}
+.label-success{background-color:#5cb85c}
+.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}
+.label-info{background-color:#5bc0de}
+.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}
+.label-warning{background-color:#f7a706}
+.label-warning[href]:focus,.label-warning[href]:hover{background-color:#c58505}
+.label-danger{background-color:#d9534f}
+.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}
+.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;color:#fff;vertical-align:middle;background-color:#c6c2be;border-radius:10px}
+.badge:empty{display:none}
+.media-object,.thumbnail{display:block}
+.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}
+a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}
+.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#174d72;background-color:#fff}
+.jumbotron,.jumbotron .h1,.jumbotron h1{color:inherit}
+.list-group-item>.badge{float:right}
+.list-group-item>.badge+.badge{margin-right:5px}
+.nav-pills>li>a>.badge{margin-left:3px}
+.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;background-color:#d6d4d0}
+.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}
+.alert .alert-link,.close{font-weight:700}
+.alert,.thumbnail{margin-bottom:20px}
+.jumbotron>hr{border-top-color:#bebbb5}
+.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}
+.jumbotron .container{max-width:100%}
+@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}
+.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}
+.jumbotron .h1,.jumbotron h1{font-size:63px}
+}
+.thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}
+.thumbnail a>img,.thumbnail>img{margin-left:auto;margin-right:auto}
+a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#174d72}
+.thumbnail .caption{padding:9px;color:#82837e}
+.alert{padding:15px;border:1px solid transparent;border-radius:4px}
+.alert h4{margin-top:0;color:inherit}
+.alert>p,.alert>ul{margin-bottom:0}
+.alert>p+p{margin-top:5px}
+.alert-dismissable,.alert-dismissible{padding-right:35px}
+.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}
+.modal,.modal-backdrop{right:0;bottom:0;left:0}
+.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}
+.alert-success hr{border-top-color:#c9e2b3}
+.alert-success .alert-link{color:#2b542c}
+.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}
+.alert-info hr{border-top-color:#a6e1ec}
+.alert-info .alert-link{color:#245269}
+.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}
+.alert-warning hr{border-top-color:#f7e1b5}
+.alert-warning .alert-link{color:#66512c}
+.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}
+.alert-danger hr{border-top-color:#e4b9c0}
+.alert-danger .alert-link{color:#843534}
+@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}
+to{background-position:0 0}
+}
+@keyframes progress-bar-stripes{from{background-position:40px 0}
+to{background-position:0 0}
+}
+.progress{height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}
+.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#174d72;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}
+.progress-bar-striped,.progress-striped .progress-bar{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:40px 40px}
+.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}
+.progress-bar-success{background-color:#5cb85c}
+.progress-striped .progress-bar-success{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}
+.progress-bar-info{background-color:#5bc0de}
+.progress-striped .progress-bar-info{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}
+.progress-bar-warning{background-color:#f7a706}
+.progress-striped .progress-bar-warning{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}
+.progress-bar-danger{background-color:#d9534f}
+.progress-striped .progress-bar-danger{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}
+.media{margin-top:15px}
+.media:first-child{margin-top:0}
+.media,.media-body{zoom:1;overflow:hidden}
+.media-body{width:10000px}
+.media-object.img-thumbnail{max-width:none}
+.media-right,.media>.pull-right{padding-left:10px}
+.media-left,.media>.pull-left{padding-right:10px}
+.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}
+.media-middle{vertical-align:middle}
+.media-bottom{vertical-align:bottom}
+.media-heading{margin-top:0;margin-bottom:5px}
+.media-list{padding-left:0;list-style:none}
+.list-group{margin-bottom:20px;padding-left:0}
+.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}
+.list-group-item:first-child{border-top-right-radius:4px;border-top-left

<TRUNCATED>
http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/717982f4/spot-oa/ui/css/main.css
----------------------------------------------------------------------
diff --git a/spot-oa/ui/css/main.css b/spot-oa/ui/css/main.css
index ccb0107..c79df60 100755
--- a/spot-oa/ui/css/main.css
+++ b/spot-oa/ui/css/main.css
@@ -86,7 +86,6 @@
         position: fixed;
         z-index: 3;
         width: 100%;
-        height: 94px;
     }
 
     #spot-content, #spot-content-wrapper {



[36/50] [abbrv] incubator-spot git commit: Updated reference to duxbury.conf with spot.conf (#157)

Posted by ev...@apache.org.
Updated reference to duxbury.conf with spot.conf (#157)



Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/584f7399
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/584f7399
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/584f7399

Branch: refs/heads/master
Commit: 584f73991de305bf492632140beea551e7537fe7
Parents: 1f8e46e
Author: Ricardo Barona <ri...@intel.com>
Authored: Thu Dec 1 15:26:56 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Thu Dec 1 15:26:56 2016 -0600

----------------------------------------------------------------------
 spot-ml/SPARKCONF.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/584f7399/spot-ml/SPARKCONF.md
----------------------------------------------------------------------
diff --git a/spot-ml/SPARKCONF.md b/spot-ml/SPARKCONF.md
index f7c9b6f..3f57ce3 100644
--- a/spot-ml/SPARKCONF.md
+++ b/spot-ml/SPARKCONF.md
@@ -29,7 +29,7 @@ When running _Spark_ on _Yarn_ users can set up a set of properties in order to
 effective way. Since not all clusters are the same and not all users are planning to have the same capacity of computation, we have created
 variables that users need to configure before running oni-ml.
 
-After installing oni-setup users will find the [duxbay.conf](https://github.com/Open-Network-Insight/oni-setup/blob/master/duxbay.conf) 
+After installing oni-setup users will find the [spot.conf](https://github.com/Open-Network-Insight/open-network-insight/blob/spot/spot-setup/spot.conf) 
 file under /etc folder. This file contains all the required configuration to run oni-ml, as explained in [INSTALL.md](https://github.com/Open-Network-Insight/oni-ml/blob/master/INSTALL.md). In this
 file exist a section for _Spark_ properties, below is the explanation for each of those variables:
 


[04/50] [abbrv] incubator-spot git commit: Merge pull request #139 from rabarona/1.1-spot-ml_performance_improvements

Posted by ev...@apache.org.
Merge pull request #139 from rabarona/1.1-spot-ml_performance_improvements

1.1 spot ml performance improvements

Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/1d3a34ac
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/1d3a34ac
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/1d3a34ac

Branch: refs/heads/master
Commit: 1d3a34ac0ddc0050c9d0bdcc3a91ee0eb43d3235
Parents: 717982f 4bd5da4
Author: NathanSegerlind <na...@intel.com>
Authored: Fri Nov 18 11:31:46 2016 -0800
Committer: GitHub <no...@github.com>
Committed: Fri Nov 18 11:31:46 2016 -0800

----------------------------------------------------------------------
 spot-ml/ml_ops.sh                               |  12 +-
 .../scala/org/apache/spot/SpotLDACWrapper.scala | 205 -------------
 .../org/apache/spot/SuspiciousConnects.scala    |   2 +-
 .../spot/SuspiciousConnectsArgumentParser.scala |   5 +
 .../dns/model/DNSSuspiciousConnectsModel.scala  |  24 +-
 .../FlowSuspiciousConnectsAnalysis.scala        |   6 +-
 .../model/FlowSuspiciousConnectsModel.scala     |  52 ++--
 .../proxy/ProxySuspiciousConnectsModel.scala    |  28 +-
 .../spot/spotldacwrapper/SpotLDACInput.scala    |   6 +
 .../spot/spotldacwrapper/SpotLDACOutput.scala   |   7 +
 .../spot/spotldacwrapper/SpotLDACSchema.scala   |  21 ++
 .../spot/spotldacwrapper/SpotLDACWrapper.scala  | 292 +++++++++++++++++++
 .../org/apache/spot/utilities/Quantiles.scala   |   4 +-
 .../org/apache/spot/SpotLDACWrapperTest.scala   |  67 ++++-
 14 files changed, 454 insertions(+), 277 deletions(-)
----------------------------------------------------------------------



[33/50] [abbrv] incubator-spot git commit: Fix date format for ingest summary

Posted by ev...@apache.org.
Fix date format for ingest summary


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

Branch: refs/heads/master
Commit: 3e128136cf392dd42304e1c2023178ee9312ce7f
Parents: 3fe41bb
Author: elopezsa <ev...@intel.com>
Authored: Thu Dec 1 10:17:40 2016 -0600
Committer: elopezsa <ev...@intel.com>
Committed: Thu Dec 1 10:17:40 2016 -0600

----------------------------------------------------------------------
 spot-oa/oa/flow/flow_oa.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/3e128136/spot-oa/oa/flow/flow_oa.py
----------------------------------------------------------------------
diff --git a/spot-oa/oa/flow/flow_oa.py b/spot-oa/oa/flow/flow_oa.py
index cace445..0b8a820 100644
--- a/spot-oa/oa/flow/flow_oa.py
+++ b/spot-oa/oa/flow/flow_oa.py
@@ -417,8 +417,8 @@ class OA(object):
         next(result_rows)
 
         ingest_summary_results = [ ["date","flows"] ]
-        ingest_summary_results.extend([ ["{0}/{1}/{2} {3}:{4}".format(mn,dy,yr,row[3].zfill(2) ,row[4].zfill(2)), row[5]] for row in result_rows ])
-        ingest_summay_file = "{0}/is_{1}.csv".format(self._ingest_summary_path,self._date)
+        ingest_summary_results.extend([ ["{0}-{1}-{2} {3}:{4}".format(yr, mn, dy, row[3].zfill(2) ,row[4].zfill(2)), row[5]] for row in result_rows ])
+        ingest_summay_file = "{0}/is_{1}{2}.csv".format(self._ingest_summary_path,yr,mn)
 
 
         write_format =  'a' if os.path.isfile(ingest_summay_file) else 'w+'


[06/50] [abbrv] incubator-spot git commit: Merge pull request #134 from Open-Network-Insight/spark_conf

Posted by ev...@apache.org.
Merge pull request #134 from Open-Network-Insight/spark_conf

Spark conf

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

Branch: refs/heads/master
Commit: f3b7da50a5d7aaa41589d94774fcd84242019bed
Parents: 1d3a34a 28b1af4
Author: Everardo Lopez Sandoval <ev...@intel.com>
Authored: Tue Nov 22 08:07:48 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Tue Nov 22 08:07:48 2016 -0600

----------------------------------------------------------------------
 spot-ingest/ingest_conf.json              |  13 ++-
 spot-ingest/pipelines/proxy/bluecoat.py   | 131 +++++++++++++++++++++++++
 spot-ingest/pipelines/proxy/bro_parser.py | 130 ------------------------
 spot-ingest/pipelines/proxy/worker.py     |  34 ++++---
 4 files changed, 162 insertions(+), 146 deletions(-)
----------------------------------------------------------------------



[48/50] [abbrv] incubator-spot git commit: remove git clone instruction

Posted by ev...@apache.org.
remove git clone instruction


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

Branch: refs/heads/master
Commit: d8f2543d65b065825b13e2b97cf2c1e580326fda
Parents: 300d313
Author: elopezsa <ev...@intel.com>
Authored: Thu Dec 8 10:15:27 2016 -0600
Committer: elopezsa <ev...@intel.com>
Committed: Thu Dec 8 10:15:27 2016 -0600

----------------------------------------------------------------------
 spot-ingest/README.md | 4 ----
 1 file changed, 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/d8f2543d/spot-ingest/README.md
----------------------------------------------------------------------
diff --git a/spot-ingest/README.md b/spot-ingest/README.md
index 6239844..bef9279 100644
--- a/spot-ingest/README.md
+++ b/spot-ingest/README.md
@@ -38,10 +38,6 @@ The following roles are required in all the nodes where the Ingest Framework wil
 * [HDFS gateway (i.e. Edge Server)](https://hadoop.apache.org/docs/r2.4.1/hadoop-project-dist/hadoop-hdfs/HdfsNfsGateway.html)
 * Kafka Broker
 
-**Get the code:**
-
-     git clone https://github.com/Open-Network-Insight/spot-ingest.git
-
 **Ingest Configuration:**
 
 The file **ingest_conf.json** contains all the required configuration to start the ingest module


[27/50] [abbrv] incubator-spot git commit: Restore blue diamonds on Network view diagrams (#154)

Posted by ev...@apache.org.
Restore blue diamonds on Network view diagrams (#154)



Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/056abbc7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/056abbc7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/056abbc7

Branch: refs/heads/master
Commit: 056abbc7980e3df4b04a269af956768d88dc9b0d
Parents: a4bff60
Author: daortizh <di...@intel.com>
Authored: Wed Nov 30 11:11:47 2016 -0600
Committer: GitHub <no...@github.com>
Committed: Wed Nov 30 11:11:47 2016 -0600

----------------------------------------------------------------------
 spot-oa/ui/css/bootstrap-spot-theme.less                | 6 ++++++
 spot-oa/ui/css/bootstrap-spot.min.css                   | 1 +
 spot-oa/ui/js/components/PolloNetworkViewMixin.react.js | 3 +--
 3 files changed, 8 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/056abbc7/spot-oa/ui/css/bootstrap-spot-theme.less
----------------------------------------------------------------------
diff --git a/spot-oa/ui/css/bootstrap-spot-theme.less b/spot-oa/ui/css/bootstrap-spot-theme.less
index 3de44a1..b6c325d 100644
--- a/spot-oa/ui/css/bootstrap-spot-theme.less
+++ b/spot-oa/ui/css/bootstrap-spot-theme.less
@@ -174,6 +174,12 @@
     fill: @brand-warning;
 }
 
+.node.internal {
+    stroke: hsl(0,60%,100%);
+    stroke-width: 2.5px;
+    fill: @brand-info;
+}
+
 /*-------------------------- Flashing/ blinker Animation----------------------*/
 .blink_me {
     -webkit-animation-name: blinker;

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/056abbc7/spot-oa/ui/css/bootstrap-spot.min.css
----------------------------------------------------------------------
diff --git a/spot-oa/ui/css/bootstrap-spot.min.css b/spot-oa/ui/css/bootstrap-spot.min.css
index 02e78bf..4e5b8f8 100644
--- a/spot-oa/ui/css/bootstrap-spot.min.css
+++ b/spot-oa/ui/css/bootstrap-spot.min.css
@@ -1468,6 +1468,7 @@ td.visible-print,th.visible-print{display:table-cell!important}
 .edge-faded,.faded,.node-faded{stroke-opacity:.2!important}
 .faded,.node-faded{fill-opacity:.2!important}
 .node{stroke:#fff;stroke-width:2.5px;fill:#f7a706}
+.node.internal{stroke:#fff;stroke-width:2.5px;fill:#5bc0de}
 .blink_me{-webkit-animation-name:blinker;-webkit-animation-duration:1.5s;-webkit-animation-timing-function:linear;-webkit-animation-iteration-count:infinite;-moz-animation-name:blinker;-moz-animation-duration:1.5s;-moz-animation-timing-function:linear;-moz-animation-iteration-count:infinite;animation-name:blinker;animation-duration:1.5s;animation-timing-function:linear;animation-iteration-count:infinite}
 .proxy-force .edge.blink_me{stroke:#f7a706}
 @-moz-keyframes blinker{0%,100%{stroke-opacity:1;fill-opacity:1}

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/056abbc7/spot-oa/ui/js/components/PolloNetworkViewMixin.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/components/PolloNetworkViewMixin.react.js b/spot-oa/ui/js/components/PolloNetworkViewMixin.react.js
index 79a996f..f1dcab3 100755
--- a/spot-oa/ui/js/components/PolloNetworkViewMixin.react.js
+++ b/spot-oa/ui/js/components/PolloNetworkViewMixin.react.js
@@ -21,7 +21,6 @@ const PolloNetworkViewMixin = {
         this.nodeSizeScale = d3.scale.linear().domain(hitsDomain);
         this.chargeScale = d3.scale.linear().domain(hitsDomain);
         this.typeScale = d3.scale.ordinal().domain(ipDomain).range(["circle", "diamond"]);
-        this.colorScale = d3.scale.ordinal().domain(ipDomain).range(["#fdb813", "#0071C5"]);
 
         // Link related scales
         this.opacityScale = d3.scale.threshold().domain([13]).range([0.1, 1]);
@@ -108,12 +107,12 @@ const PolloNetworkViewMixin = {
         this.nodesSel.enter
             .append('path', '.edge')
             .classed('node', true)
+            .classed('internal', n => n.internalIp=='1')
             .attr("id", n => SpotUtils.encodeId(n.id))
             .attr("d", d3.svg.symbol()
                .size(n => this.nodeSizeScale(n.hits))
                .type(n => this.typeScale(n.internalIp))
             )
-            .attr('fill', n => this.colorScale(n.internalIp))
             .call(this.force.drag)
             .on('mouseover', (n) => {
                 var direction = '';


[44/50] [abbrv] incubator-spot git commit: Merge pull request #163 from NathanSegerlind/sparklda_install

Posted by ev...@apache.org.
Merge pull request #163 from NathanSegerlind/sparklda_install

sparklda_install

Project: http://git-wip-us.apache.org/repos/asf/incubator-spot/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-spot/commit/83d157a3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-spot/tree/83d157a3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-spot/diff/83d157a3

Branch: refs/heads/master
Commit: 83d157a3e38e99e7bf72d2f9e5661f0e4ba2105b
Parents: 831ff7c be742b1
Author: NathanSegerlind <na...@intel.com>
Authored: Mon Dec 5 16:23:59 2016 -0800
Committer: GitHub <no...@github.com>
Committed: Mon Dec 5 16:23:59 2016 -0800

----------------------------------------------------------------------
 spot-ml/INSTALL.md    | 5 -----
 spot-ml/install_ml.sh | 2 +-
 2 files changed, 1 insertion(+), 6 deletions(-)
----------------------------------------------------------------------