azkaban-uncached

Ui additions for executing flows

3/7/2013 1:41:55 AM

Details

diff --git a/src/java/azkaban/execapp/FlowRunnerManager.java b/src/java/azkaban/execapp/FlowRunnerManager.java
index 26bddd0..11c6bc1 100644
--- a/src/java/azkaban/execapp/FlowRunnerManager.java
+++ b/src/java/azkaban/execapp/FlowRunnerManager.java
@@ -81,7 +81,7 @@ public class FlowRunnerManager implements EventListener {
 	
 	private long lastSubmitterThreadCheckTime = -1;
 	private long lastCleanerThreadCheckTime = -1;
-	private long executionDirRetention = 7*24*60*60*1000;
+	private long executionDirRetention = 1*24*60*60*1000;
 	
 	private Object executionDirDeletionSync = new Object();
 	
diff --git a/src/java/azkaban/executor/ExecutorManager.java b/src/java/azkaban/executor/ExecutorManager.java
index 975a58e..f83b49c 100644
--- a/src/java/azkaban/executor/ExecutorManager.java
+++ b/src/java/azkaban/executor/ExecutorManager.java
@@ -396,6 +396,10 @@ public class ExecutorManager {
 		return jsonResponse;
 	}
 	
+	public void shutdown() {
+		executingManager.shutdown();
+	}
+	
 	private class ExecutingManagerUpdaterThread extends Thread {
 		private boolean shutdown = false;
 
@@ -412,6 +416,10 @@ public class ExecutorManager {
 		private int numErrors = 6;
 		private long errorThreshold = 10000;
 		
+		private void shutdown() {
+			shutdown = true;
+		}
+		
 		@SuppressWarnings("unchecked")
 		public void run() {
 			while(!shutdown) {
diff --git a/src/java/azkaban/sla/SLAManager.java b/src/java/azkaban/sla/SLAManager.java
index 1adffc6..124e8f4 100644
--- a/src/java/azkaban/sla/SLAManager.java
+++ b/src/java/azkaban/sla/SLAManager.java
@@ -153,6 +153,7 @@ public class SLAManager {
 		private static final int TIMEOUT_MS = 60000;
 
 		public SLARunner() {
+			this.setName("SLAManagerThread");
 			SLAs = new PriorityBlockingQueue<SLA>(1,new SLAComparator());
 		}
 
diff --git a/src/java/azkaban/webapp/AzkabanWebServer.java b/src/java/azkaban/webapp/AzkabanWebServer.java
index 97c7414..3e4a654 100644
--- a/src/java/azkaban/webapp/AzkabanWebServer.java
+++ b/src/java/azkaban/webapp/AzkabanWebServer.java
@@ -456,7 +456,6 @@ public class AzkabanWebServer implements AzkabanServer {
 			public void run() {
 				logger.info("Shutting down http server...");
 				try {
-					app.getScheduleManager().shutdown();
 					app.close();
 					server.stop();
 					server.destroy();
@@ -465,7 +464,6 @@ public class AzkabanWebServer implements AzkabanServer {
 					logger.error("Error while shutting down http server.", e);
 				}
 				logger.info("kk thx bye.");
-				System.exit(0);
 			}
 		});
 		logger.info("Server running on port " + sslPortNumber + ".");
@@ -703,6 +701,9 @@ public class AzkabanWebServer implements AzkabanServer {
 		} catch (Exception e) {
 			logger.error("Failed to cleanup MBeanServer", e);
 		}
+		scheduleManager.shutdown();
+		slaManager.shutdown();
+		executorManager.shutdown();
 	}
 	
 	private void registerMbean(String name, Object mbean) {
diff --git a/src/java/azkaban/webapp/servlet/ExecutorServlet.java b/src/java/azkaban/webapp/servlet/ExecutorServlet.java
index b3eaba0..9c68784 100644
--- a/src/java/azkaban/webapp/servlet/ExecutorServlet.java
+++ b/src/java/azkaban/webapp/servlet/ExecutorServlet.java
@@ -54,7 +54,7 @@ public class ExecutorServlet extends LoginAbstractAzkabanServlet {
 	private ProjectManager projectManager;
 	private ExecutorManager executorManager;
 	private ScheduleManager scheduleManager;
-	private ExecutorVMHelper vmHelper;
+	private ExecutorVelocityHelper velocityHelper;
 
 	@Override
 	public void init(ServletConfig config) throws ServletException {
@@ -63,7 +63,7 @@ public class ExecutorServlet extends LoginAbstractAzkabanServlet {
 		projectManager = server.getProjectManager();
 		executorManager = server.getExecutorManager();
 		scheduleManager = server.getScheduleManager();
-		vmHelper = new ExecutorVMHelper();
+		velocityHelper = new ExecutorVelocityHelper();
 	}
 
 	@Override
@@ -127,7 +127,7 @@ public class ExecutorServlet extends LoginAbstractAzkabanServlet {
 		
 		List<ExecutableFlow> finishedFlows = executorManager.getRecentlyFinishedFlows();
 		page.add("recentlyFinished", finishedFlows.isEmpty() ? null : finishedFlows);
-		page.add("vmutils", vmHelper);
+		page.add("vmutils", velocityHelper);
 		page.render();
 	}
 	
@@ -764,7 +764,7 @@ public class ExecutorServlet extends LoginAbstractAzkabanServlet {
 		}
 	}
 	
-	public class ExecutorVMHelper {
+	public class ExecutorVelocityHelper {
 		public String getProjectName(int id) {
 			Project project = projectManager.getProject(id);
 			if (project == null) {
diff --git a/src/java/azkaban/webapp/servlet/velocity/executionoptionspanel.vm b/src/java/azkaban/webapp/servlet/velocity/executionoptionspanel.vm
index a16ddd7..d882d33 100644
--- a/src/java/azkaban/webapp/servlet/velocity/executionoptionspanel.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/executionoptionspanel.vm
@@ -1,82 +1,82 @@
 	<div id="modalBackground" class="modalBackground2">
-	<div id="executing-options" class="modal modalContainer2">
-		<a href='#' title='Close' class='modal-close'>x</a>
-			<h3>Executing Flow Options</h3>
-			<div>
-				<ul class="optionsPicker">
-					<li id="generalOptions">General Options</li>
-					<li id="flowOptions">Flow Options</li>
-				</ul>
-			</div>
-			<div class="optionsPane">
-				<div id="generalPanel" class="generalPanel panel">
-					<div id="completeActions">
-						<h4>Completion Actions</h4>
-						<dl>
-							<dt>Failure Action</dt>
-							<dd>
-								<select id="failureAction" name="failureAction">
-									<option value="finishCurrent">Finish Current Running</option>
-									<option value="cancelImmediately">Cancel All</option>
-									<option value="finishPossible">Finish All Possible</option>
-								</select>
-											</dd>
-							<dt>Failure Email</dt>
-							<dd>
-								<textarea id="failureEmails"></textarea>
-							</dd>
-							<dt>Notify on Failure</dt>
-							<dd>
-								<input id="notifyFailureFirst" class="checkbox" type="checkbox" name="notify" value="first" checked >First Failure</input>
-								<input id="notifyFailureLast" class="checkbox" type="checkbox" name="notify" value="last">Flow Stop</input>
-							</dd>
-							<dt>Success Email</dt>
-							<dd>
-								<textarea id="successEmails"></textarea>
-							</dd>
-							<dt>Concurrent Execution</dt>
-							<dd id="executingJob" class="disabled">
-								<input id="ignore" class="radio" type="radio" name="concurrent" value="ignore" checked /><label class="radioLabel" for="ignore">Run Concurrently</label>
-								<input id="pipeline" class="radio" type="radio" name="concurrent" value="pipeline" /><label class="radioLabel" for="pipeline">Pipeline</label>
-								<input id="queue" class="radio" type="radio" name="concurrent" value="queue" /><label class="radioLabel" for="queue">Queue Job</label>
-							</dd>
-						</dl>
-					</div>
-					<div id="flowPropertyOverride">
-						<h4>Flow Property Override</h4>
-						<div class="tableDiv">
-							<table>
-								<thead>
-									<tr>
-										<th>Name</th>
-										<th>Value</th>
-									</tr>
-								</thead>
-								<tbody>
-									<tr id="addRow"><td id="addRow-col" colspan="2"><span class="addIcon"></span><a href="#">Add Row</a></td></tr>
-								</tbody>
-							</table>
+		<div id="executing-options" class="modal modalContainer2">
+			<a href='#' title='Close' class='modal-close'>x</a>
+				<h3>Executing Flow Options</h3>
+				<div>
+					<ul class="optionsPicker">
+						<li id="generalOptions">General Options</li>
+						<li id="flowOptions">Flow Options</li>
+					</ul>
+				</div>
+				<div class="optionsPane">
+					<div id="generalPanel" class="generalPanel panel">
+						<div id="completeActions">
+							<h4>Completion Actions</h4>
+							<dl>
+								<dt>Failure Action</dt>
+								<dd>
+									<select id="failureAction" name="failureAction">
+										<option value="finishCurrent">Finish Current Running</option>
+										<option value="cancelImmediately">Cancel All</option>
+										<option value="finishPossible">Finish All Possible</option>
+									</select>
+												</dd>
+								<dt>Failure Email</dt>
+								<dd>
+									<textarea id="failureEmails"></textarea>
+								</dd>
+								<dt>Notify on Failure</dt>
+								<dd>
+									<input id="notifyFailureFirst" class="checkbox" type="checkbox" name="notify" value="first" checked >First Failure</input>
+									<input id="notifyFailureLast" class="checkbox" type="checkbox" name="notify" value="last">Flow Stop</input>
+								</dd>
+								<dt>Success Email</dt>
+								<dd>
+									<textarea id="successEmails"></textarea>
+								</dd>
+								<dt>Concurrent Execution</dt>
+								<dd id="executingJob" class="disabled">
+									<input id="ignore" class="radio" type="radio" name="concurrent" value="ignore" checked /><label class="radioLabel" for="ignore">Run Concurrently</label>
+									<input id="pipeline" class="radio" type="radio" name="concurrent" value="pipeline" /><label class="radioLabel" for="pipeline">Pipeline</label>
+									<input id="queue" class="radio" type="radio" name="concurrent" value="queue" /><label class="radioLabel" for="queue">Queue Job</label>
+								</dd>
+							</dl>
+						</div>
+						<div id="flowPropertyOverride">
+							<h4>Flow Property Override</h4>
+							<div class="tableDiv">
+								<table>
+									<thead>
+										<tr>
+											<th>Name</th>
+											<th>Value</th>
+										</tr>
+									</thead>
+									<tbody>
+										<tr id="addRow"><td id="addRow-col" colspan="2"><span class="addIcon"></span><a href="#">Add Row</a></td></tr>
+									</tbody>
+								</table>
+							</div>
 						</div>
 					</div>
-				</div>
-								<div id="graphPanel" class="graphPanel panel">
-									<div id="jobListCustom" class="jobList">
-										<div class="filterList">
-											<input class="filter" placeholder="  Job Filter" />
+									<div id="graphPanel" class="graphPanel panel">
+										<div id="jobListCustom" class="jobList">
+											<div class="filterList">
+												<input class="filter" placeholder="  Job Filter" />
+											</div>
+											<div class="list">
+											</div>
+											<div class="btn5 resetPanZoomBtn" >Reset Pan Zoom</div>
 										</div>
-										<div class="list">
+									<div id="svgDivCustom" class="svgDiv" >
+										<svg class="svgGraph" xmlns="http://www.w3.org/2000/svg" version="1.1" shape-rendering="optimize-speed" text-rendering="optimize-speed" >
+											</svg>
 										</div>
-										<div class="btn5 resetPanZoomBtn" >Reset Pan Zoom</div>
-									</div>
-								<div id="svgDivCustom" class="svgDiv" >
-									<svg class="svgGraph" xmlns="http://www.w3.org/2000/svg" version="1.1" shape-rendering="optimize-speed" text-rendering="optimize-speed" >
-										</svg>
-									</div>
+			</div>
+		</div>
+			<div class="actions">
+		<a class="yes btn1" id="execute-btn" href="#">Execute Now</a>
+		<a class="no simplemodal-close btn3" id="cancel-btn" href="#">Cancel</a>
 		</div>
-	</div>
-		<div class="actions">
-	<a class="yes btn1" id="execute-btn" href="#">Execute Now</a>
-	<a class="no simplemodal-close btn3" id="cancel-btn" href="#">Cancel</a>
-	</div>
 	</div>
 </div>
\ No newline at end of file
diff --git a/src/java/azkaban/webapp/servlet/velocity/flowexecutionpanel.vm b/src/java/azkaban/webapp/servlet/velocity/flowexecutionpanel.vm
new file mode 100644
index 0000000..9319c46
--- /dev/null
+++ b/src/java/azkaban/webapp/servlet/velocity/flowexecutionpanel.vm
@@ -0,0 +1,53 @@
+<script type="text/javascript" src="${context}/js/azkaban.layout.js"></script>
+<script type="text/javascript" src="${context}/js/svgNavigate.js"></script>
+<script type="text/javascript" src="${context}/js/azkaban.svg.graph.view.js"></script>
+<script type="text/javascript" src="${context}/js/azkaban.flow.execute.view.js"></script>
+
+<div id="modalBackground" class="modalBackground2">
+<div id="execute-flow-panel" class="modal modalContainer2">
+	<h3 id="execute-flow-panel-title"></h3>
+	<a title="Close" class="modal-close">x</a>
+	<div id="execute-message" class="message">
+	</div>
+	
+	<div class="panel">
+		<div id="executionGraphOptions">
+			<div id="graphOptions" class="sideMenu">
+				<h3>Jobs</h3>
+				<div>
+					<p>Jobs Panel</p>
+				</div>
+				<h3>Notification</h3>
+				<div>
+					<p>Jobs Panel</p>
+				</div>
+				<h3>Concurrent Runs</h3>
+				<div>
+					<p>Jobs Panel</p>
+				</div>
+				<h3>SLA</h3>
+				<div>
+					<p>Jobs Panel</p>
+				</div>
+				<h3>Flow Parameters</h3>
+				<div>
+					<p>Jobs Panel</p>
+				</div>
+			</div>
+		</div>
+		<div id="svgDivCustom" class="svgDiv" >
+			<svg class="svgGraph" xmlns="http://www.w3.org/2000/svg" version="1.1" shape-rendering="optimize-speed" text-rendering="optimize-speed" >
+			</svg>
+		</div>
+	</div>
+	
+	<div class="actions">
+		<a class="btn2" id="advanced-btn">Advanced Settings</a>
+		<a class="yes btn1" id="execute-btn">Execute</a>
+		<a class="no simplemodal-close btn3">Cancel</a>
+	</div>
+</div>
+</div>
+<div id="contextMenu">
+	
+</div>
diff --git a/src/java/azkaban/webapp/servlet/velocity/projectpage.vm b/src/java/azkaban/webapp/servlet/velocity/projectpage.vm
index f592314..34e5954 100644
--- a/src/java/azkaban/webapp/servlet/velocity/projectpage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/projectpage.vm
@@ -19,7 +19,7 @@
 	<head>
 #parse( "azkaban/webapp/servlet/velocity/style.vm" )
 		<script type="text/javascript" src="${context}/js/jquery/jquery.js"></script>    
-		<script type="text/javascript" src="${context}/js/jqueryui/jquery-ui.custom.min.js"></script>   
+		<script type="text/javascript" src="${context}/js/jqueryui/jquery-ui.custom.min.js"></script>
 		<script type="text/javascript" src="${context}/js/namespace.js"></script>
 		<script type="text/javascript" src="${context}/js/underscore-1.2.1-min.js"></script>
 		<script type="text/javascript" src="${context}/js/backbone-0.5.3-min.js"></script>
@@ -27,6 +27,8 @@
 		<script type="text/javascript" src="${context}/js/azkaban.ajax.utils.js"></script>
 		<script type="text/javascript" src="${context}/js/azkaban.nav.js"></script>
 		<script type="text/javascript" src="${context}/js/azkaban.project.view.js"></script>
+		
+		<link rel="stylesheet" type="text/css" href="${context}/css/jquery-ui-1.9.2.custom.css" /> 
 		<script type="text/javascript">
 			var contextURL = "${context}";
 			var currentTime = ${currentTime};
@@ -167,16 +169,9 @@
 				<a class="yes btn6" id="delete-btn" href="#">Yes</a>
 			</div>
 		</div>
-		<div id="flow-execute" class="modal">
-			<h3>Execute Flow</h3>
-			<div id="executeErrorMsg" class="box-error-message"></div>
-			<div id="execute-message" class="message">
-			</div>
-			<div class="actions">
-				<a class="yes btn1" id="execute-btn">Execute</a>
-				<a class="no simplemodal-close btn3">Cancel</a>
-			</div>
-		</div>
+		
+		#parse( "azkaban/webapp/servlet/velocity/flowexecutionpanel.vm" )
 	</body>
+	
 </html>
 
diff --git a/src/java/azkaban/webapp/session/SessionCache.java b/src/java/azkaban/webapp/session/SessionCache.java
index 8788226..e110be2 100644
--- a/src/java/azkaban/webapp/session/SessionCache.java
+++ b/src/java/azkaban/webapp/session/SessionCache.java
@@ -28,12 +28,12 @@ import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
  * 
  * The following global azkaban properties can be used: max.num.sessions - used
  * to determine the number of live sessions that azkaban will handle. Default is
- * 10000 session.time.to.live -Number of seconds before sessione expires.
- * Default set to 3 days.
+ * 10000 session.time.to.live -Number of seconds before session expires.
+ * Default set to 1 days.
  */
 public class SessionCache {
 	private static final int MAX_NUM_SESSIONS = 10000;
-	private static final int SESSION_TIME_TO_LIVE = 86400 * 3;
+	private static final int SESSION_TIME_TO_LIVE = 86400;
 	private CacheManager manager = CacheManager.create();
 	private Cache cache;
 
diff --git a/src/web/css/azkaban.css b/src/web/css/azkaban.css
index 9f38ce3..845017d 100644
--- a/src/web/css/azkaban.css
+++ b/src/web/css/azkaban.css
@@ -691,6 +691,7 @@ tr:hover td {
   color: #666;
   font-weight: bold;
   text-decoration: none;
+  cursor: pointer;
   position: absolute;
   top: 10px;
   right: 17px;
@@ -1350,6 +1351,7 @@ tr:hover td {
 	opacity: 0.3;
 }
 
+/* executing options panel*/
 #executing-options {
 	left: 100px;
 	right: 100px;
@@ -1359,7 +1361,6 @@ tr:hover td {
 
 #executing-options .svgDiv {
 	position: absolute;
-	background-color: #CCC;
 	padding: 1px;
 	left: 270px;
 	right: 0px;
@@ -1373,7 +1374,6 @@ tr:hover td {
 	top: 0px;
 	bottom: 0px;
 	padding: 5px;
-	background-color: #F0F0F0;
 }
 
 #executing-options .list {
@@ -2671,6 +2671,72 @@ tr.row td.tb-name {
 	float: left;
 }
 
+#advanced-btn {
+	float: left;
+	margin-left: 20px;
+}
+
+#execute-flow-panel {
+	left: 150px;
+	right: 150px;
+	top: 200px;
+	bottom: 200px;
+	min-width: 600px;
+	min-height: 400px;
+}
+
+#execute-flow-panel .svgDiv {
+	position: absolute;
+	padding: 1px;
+	left: 270px;
+	right: 0px;
+	top: 0px;
+	bottom: 0px;
+	border: none;
+}
+
+#execute-flow-panel .panel {
+	position: absolute;
+	width: 100%;
+	top: 50px;
+	bottom: 65px;
+	border: none;
+}
+
+.contextMenu {
+	position: absolute;
+	background-color: #FFF;
+	border: 1px solid #DDD;
+	-moz-box-shadow: 2px 2px 5px #888;
+	-webkit-box-shadow: 2px 2px 5px #888;
+	box-shadow: 2px 2px 5px #888;
+}
+.contextMenu li.menuitem {
+	background-color: #FFF;
+	padding: 3px 20px;
+	min-width: 50px;
+	font-size: 10pt;
+	cursor: pointer;
+}
+
+.contextMenu li.menuitem .expandSymbol {
+	background-image: url("../../js/jqueryui/themes/custom-theme/images/ui-icons_cccccc_256x240.png");
+	background-position: -32px -16px;
+	height: 16px;
+	width: 16px;
+	float:right;
+}
+
+.contextMenu li.break {
+	border-bottom: 1px solid #BBB;
+	margin: 2px 5px;
+}
+
+.contextMenu li.menuitem:hover {
+	background-color: #555;
+	color: #FFF;
+}
+
 /* old styles */
 .azkaban-charts .hitarea {
 	background-image: url("../../js/jqueryui/themes/custom-theme/images/ui-icons_cccccc_256x240.png");
@@ -2681,6 +2747,11 @@ tr.row td.tb-name {
 	cursor: pointer;
 }
 
+#executionGraphOptions {
+	width: 270px;
+	height: 100%;
+}
+
 .azkaban-charts .expandable-hitarea { background-position: -32px -16px; }
 .azkaban-charts .expandable-hitarea.collapse { background-position: 0 -16px; }
 /* clean up */

src/web/css/azkaban2.css 2690(+2690 -0)

diff --git a/src/web/css/azkaban2.css b/src/web/css/azkaban2.css
new file mode 100644
index 0000000..47cf2e0
--- /dev/null
+++ b/src/web/css/azkaban2.css
@@ -0,0 +1,2690 @@
+/* GLOBAL RESET */
+html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td {margin: 0; padding: 0; border: 0; outline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; -webkit-text-size-adjust: 100%; }
+ol, ul {list-style: none;}
+table {border-collapse: separate; border-spacing: 0;}
+caption, th, td {text-align: left; font-weight: normal;}
+blockquote:before, blockquote:after, q:before, q:after {content: "";}
+blockquote, q {quotes: "" "";}
+input[data-ime-mode-disabled] { ime-mode: disabled !important; }
+input[type=file] { ime-mode: disabled !important; }
+
+body {
+  background-color: #f0f0f0;
+  font-family: Helvetica, Arial, Sans-Serif;
+}
+
+body.nonelastic {
+  overflow: hidden;
+}
+
+textarea {
+	border: 2px inset;
+}
+
+dt.disabled {
+	color: #CCC;
+}
+label.disabled {
+	color: #CCC;
+}
+
+.header {
+  background-image: -o-linear-gradient(bottom, rgb(56,56,56) 33%, rgb(73,73,73) 66%);
+  background-image: -moz-linear-gradient(bottom, rgb(56,56,56) 33%, rgb(73,73,73) 66%);
+  background-image: -webkit-linear-gradient(bottom, rgb(56,56,56) 33%, rgb(73,73,73) 66%);
+  background-image: -ms-linear-gradient(bottom, rgb(56,56,56) 33%, rgb(73,73,73) 66%);
+  background-image: -webkit-gradient(
+   	linear,
+   	left bottom,
+   	left top,
+   	color-stop(0.33, rgb(56,56,56)),
+   	color-stop(0.66, rgb(73,73,73))
+  );
+  background-image: linear-gradient(bottom, rgb(56,56,56) 33%, rgb(73,73,73) 66%); 
+  border-top: 5px solid #ff3601;
+  box-shadow: 0 1px 4px 1px #000;
+  height: 80px;
+  overflow: hidden;
+  position: relative;
+}
+
+.logo {
+  background: url(../../images/logo.png) top left no-repeat;
+  float: left;
+  font-family: "Helvetica Neue";
+  font-size: 156.25%;
+  font-weight: bold;
+  margin: 15px 0.6% 0 4.75%;
+  padding: 5px 0 11px 42px;
+}
+     
+.logo a {
+  color: #fff;
+  text-decoration: none;
+  font-family: Helvetica, Arial, Sans-Serif;
+}
+
+.enviro {
+  float: left;
+  margin-top: 25px;
+}
+     
+.enviro-name {
+  color: #ff3601;
+  font-family: Helvetica, Arial, Sans-Serif;
+  font-size: 118.75%;
+  font-weight: bold;
+}
+     
+.enviro-server {
+  color: #999;
+  font-family: Helvetica, Arial, Sans-Serif;
+  font-size: 75%;
+}
+
+.nav {
+  float: left;  
+  font-family: Arial;
+  font-size: 81.25%;
+  margin-left: 9.583333%;
+  overflow: hidden;
+}
+     
+.nav li {
+  float:left;
+  height: 48px;     
+  padding: 30px 12px 0 12px;
+}
+     
+.nav li:hover {
+  background-color: rgba(0, 0, 0, 0.1);
+  cursor: pointer;
+}
+
+.nav .selected {
+  background-color: rgba(0, 0, 0, 0.1);
+}
+
+.nav .selected:hover,
+.nav .selected a:hover {
+  cursor: default;
+}
+     
+.nav a {
+  color: #ccc;
+  text-decoration: none;
+}
+     
+.nav .selected a {
+  border-bottom: 1px solid #ff3601;
+  color: #fff;
+  font-weight: bold;
+}
+
+.content {
+  background-color: #E0E0E0;
+  border: 1px solid #cdcdcd;
+  margin: 0 50px 10px;
+  min-height: 150px;
+}
+
+.content.history {
+  min-height: 75px;
+}
+
+.section-ft {
+  border-top: 1px solid #cdcdcd;
+}
+
+.section-ft,
+.section-hd {
+  overflow: hidden;
+  padding: 25px 2.7272727%;
+}
+     
+.section-hd h2 {
+  clear: both;
+  float: left;
+  font-size: 125%;
+  font-weight: bold;
+}
+
+.section-hd h2 span{
+  padding-left: 5px;
+  font-weight: normal;
+  font-size: 90%;
+}
+
+.section-hd h2 a {
+  text-decoration:none;
+  color: #000;
+}
+
+.section-hd h2 a:hover {
+  color: #009FC9;
+}
+
+.section-hd h3 {
+  clear: both;
+  font-weight: bold;
+}
+
+.section-hd h3 a {
+  text-decoration:none;
+  color: #000;
+}
+
+.section-hd h3 a:hover {
+  color: #009FC9;
+}
+
+.section-hd h3 span {
+  padding-left: 5px;
+  font-weight: normal;
+  font-size: 90%;
+}
+
+.section-sub-hd {
+	clear: both;
+}
+
+.section-hd h4 {
+  float: left;
+  font-weight: bold;
+  font-size:11pt;
+  margin-right: 5px;
+}
+
+.section-hd h4 a {
+  text-decoration:none;
+  color: #888;
+}
+
+.section-hd h4 a:hover {
+  color: #009FC9;
+}
+
+.section-hd h4 span {
+  padding-left: 5px;
+  font-weight: normal;
+  font-size: 10pt;
+}
+
+.section-hd h4.separator {
+	color: #AAA;
+	padding-left: 5px;
+	font-weight: normal;
+  	font-size: 10pt;
+}
+
+table {
+  background-color: #fff;
+  font-family: Arial;
+  width: 100%;
+}
+
+th {
+  background-image: -o-linear-gradient(bottom, rgb(56,56,56) 33%, rgb(73,73,73) 66%);
+  background-image: -moz-linear-gradient(bottom, rgb(56,56,56) 33%, rgb(73,73,73) 66%);
+  background-image: -webkit-linear-gradient(bottom, rgb(56,56,56) 33%, rgb(73,73,73) 66%);
+  background-image: -ms-linear-gradient(bottom, rgb(56,56,56) 33%, rgb(73,73,73) 66%);
+  background-image: -webkit-gradient(
+  	linear,
+   	left bottom,
+   	left top,
+   	color-stop(0.33, rgb(56,56,56)),
+   	color-stop(0.66, rgb(73,73,73))
+  );
+  background-image: linear-gradient(bottom, rgb(56,56,56) 33%, rgb(73,73,73) 66%);
+  color: #fff;
+  font-weight: bold;
+  line-height: 1em;
+  font-size: 10.5pt;
+}
+     
+th,
+td {
+  border: 1px solid #cdcdcd;
+  border-left: none;
+  border-bottom: none;
+  padding: 5px;
+  font-size: 10pt;
+}
+
+td a {
+	color: #000;
+	text-decoration: none;
+	margin-left: 10px;
+}
+
+td a:hover {
+	color: #009FC9;
+}
+
+table .last {
+  border-right: none;
+}
+
+tr:hover td {
+  background-color: #E1E3E2;
+}
+
+
+.all-jobs .tb-name {
+  padding-left: 2.7272727%;
+  width: 64.818182%;
+  border-bottom-width: 0;
+  border-bottom-style: none;
+}
+
+.all-jobs .tb-up-date {
+  width: 160px;
+}
+
+.all-jobs .tb-owner {
+  width: 10%;
+}
+
+.all-jobs .tb-pname {
+
+}
+
+.all-jobs .tb-pvalue {
+
+}
+
+/* messaging */
+.messaging {
+  color: #fff;
+  display: none;
+  font-weight: bold;
+  height: 30px;
+  margin: 2px 4.75% 0;
+  padding: 25px 0 20px;
+  position: absolute;
+  text-align: center;
+  width: 90.3%;
+}
+
+#messageClose {
+  float: right;
+  margin-right: 25px;
+}
+
+#messageClose:hover {
+  cursor: pointer;
+}
+
+.messaging.success {
+  background-color: #4e911e;
+  display: block;
+}
+
+.messaging.error {
+  background-color: #F80700;
+  display: block;
+}
+
+.rightbutton {
+	padding-top: 20px;
+	right: 10px;
+	margin-left: 5px;
+	margin-right: 5px;
+}
+
+/* buttons */
+.btn1,
+.btn2,
+.btn3,
+.btn4,
+.btn5,
+.btn6,
+.btn7,
+.btn-disabled {
+  -moz-border-radius: 3px;
+  -webkit-border-radius: 3px;
+  border-radius: 3px;
+  border-style: solid;
+  border-width: 1px;
+  cursor: pointer;
+  font-size: 12px;
+  font-weight: bold;
+  line-height: 1.35;
+  margin: 0;
+  padding: 3px 10px 2px;
+  text-decoration: none;
+}
+
+/* green */
+.btn1 {
+  background: -moz-linear-gradient(center top , #AFD47B 0pt, #AFD47B 1px, #8BC03F 1px, #69A219 100%) repeat scroll 0 0 transparent;
+  background: -webkit-gradient(linear, center top, center bottom, color-stop(0,#AFD47B), color-stop(5%,#8BC03F),color-stop(100%,#69A219));
+  border-color: #669933;
+  color: #fff;
+}
+.btn1:hover {
+  background: -moz-linear-gradient(center top , #AFE47B 0pt, #AFE47B 1px, #8BD03F 1px, #69B219 100%) repeat scroll 0 0 transparent;
+  background: -webkit-gradient(linear, center top, center bottom, color-stop(0,#AFE47B), color-stop(5%,#8BD03F),color-stop(100%,#69B219));
+}
+
+.section-hd .btn2,
+.section-hd .btn4,
+.section-hd .btn5,
+.section-hd .btn6,
+.section-ft .btn4, 
+.section-ft .btn5{
+  float: right;
+  margin-right: 10px;
+}
+
+.section-hd .btn1,
+.section-ft .btn1 {
+  float: right;
+  margin-right: 25px;
+}
+.section-hd .btn2,
+.section-ft .btn2 {
+  float: right;
+  margin-right: 25px;
+}
+
+/* blue */
+.btn2 {
+  background: -moz-linear-gradient(center top , #73AEC9 0pt, #73AEC9 1px, #338AB0 1px, #0571A6 100%) repeat scroll 0 0 transparent;
+  background: -webkit-gradient(linear, center top, center bottom, color-stop(0,#73AEC9), color-stop(5%,#338AB0),color-stop(100%,#0571A6));
+  border-color: #045A8B;
+  color: #fff;
+}
+.btn2:hover {
+  background: -moz-linear-gradient(center top , #83BED9 0pt, #83BED9 1px, #43AAC0 1px, #1581B6 100%) repeat scroll 0 0 transparent;
+  background: -webkit-gradient(linear, center top, center bottom, color-stop(0,#83BED9), color-stop(5%,#43AAC0),color-stop(100%,#1581B6));
+}
+/* grey */
+.btn3 {
+  background: #CECECE;
+  background: -moz-linear-gradient(top, #F2F2F2 0, #F2F2F2 1px, #E4E4E4 1px, #CECECE 100%);
+  background: -o-linear-gradient(top, #F2F2F2 0, #F2F2F2 1px, #E4E4E4 1px, #CECECE 100%);
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0,#F2F2F2), color-stop(5%,#F2F2F2), color-stop(5%,#E4E4E4), color-stop(100%,#CECECE));
+  background: linear-gradient(top, #F2F2F2 0, #F2F2F2 1px, #E4E4E4 1px, #CECECE 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#E4E4E4', endColorstr='#CECECE',GradientType=0 );
+  border-color: #999;
+  color: #666;
+}
+/* white */
+.btn4 {
+  background: -moz-linear-gradient(center top , white 0pt, #ECECEC 100%) repeat scroll 0 0 transparent;
+  background: -webkit-gradient(linear, center top, center bottom, from(#FFF), to(#ECECEC));
+  background: linear-gradient(top, #FFF 0, #FFF 1px, #E4E4E4 1px, #CECECE 100%);
+  
+  border-color: #ccc;
+  color: #585858;
+  display: inline-block;
+  font-weight: normal;
+}
+
+/* grey */
+.btn7 {
+	background: #f2f5f6; /* Old browsers */
+	background: -moz-linear-gradient(top, #f2f5f6 0%, #e3eaed 37%, #c8d7dc 100%); /* FF3.6+ */
+	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f2f5f6), color-stop(37%,#e3eaed), color-stop(100%,#c8d7dc)); /* Chrome,Safari4+ */
+	background: -webkit-linear-gradient(top, #f2f5f6 0%,#e3eaed 37%,#c8d7dc 100%); /* Chrome10+,Safari5.1+ */
+	background: -o-linear-gradient(top, #f2f5f6 0%,#e3eaed 37%,#c8d7dc 100%); /* Opera 11.10+ */
+	background: -ms-linear-gradient(top, #f2f5f6 0%,#e3eaed 37%,#c8d7dc 100%); /* IE10+ */
+	background: linear-gradient(to bottom, #f2f5f6 0%,#e3eaed 37%,#c8d7dc 100%); /* W3C */
+	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2f5f6', endColorstr='#c8d7dc',GradientType=0 ); /* IE6-9 */
+	  
+	border-color: #9BA7AA;
+	color: #61696B;
+	display: inline-block;
+	font-weight: bold;
+}
+.btn7:hover {
+	background: #fcfeff; /* Old browsers */
+	background: -moz-linear-gradient(top, #fcfeff 0%, #f2f9fc 37%, #deeff4 100%); /* FF3.6+ */
+	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fcfeff), color-stop(37%,#f2f9fc), color-stop(100%,#deeff4)); /* Chrome,Safari4+ */
+	background: -webkit-linear-gradient(top, #fcfeff 0%,#f2f9fc 37%,#deeff4 100%); /* Chrome10+,Safari5.1+ */
+	background: -o-linear-gradient(top, #fcfeff 0%,#f2f9fc 37%,#deeff4 100%); /* Opera 11.10+ */
+	background: -ms-linear-gradient(top, #fcfeff 0%,#f2f9fc 37%,#deeff4 100%); /* IE10+ */
+	background: linear-gradient(to bottom, #fcfeff 0%,#f2f9fc 37%,#deeff4 100%); /* W3C */
+	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcfeff', endColorstr='#deeff4',GradientType=0 ); /* IE6-9 */
+}
+
+/* grey right */
+.btn5 {
+  background: #CECECE;
+  background: -moz-linear-gradient(top, #F2F2F2 0, #F2F2F2 1px, #E4E4E4 1px, #CECECE 100%);
+  background: -o-linear-gradient(top, #F2F2F2 0, #F2F2F2 1px, #E4E4E4 1px, #CECECE 100%);
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0,#F2F2F2), color-stop(5%,#F2F2F2), color-stop(5%,#E4E4E4), color-stop(100%,#CECECE));
+  background: linear-gradient(top, #F2F2F2 0, #F2F2F2 1px, #E4E4E4 1px, #CECECE 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#E4E4E4', endColorstr='#CECECE',GradientType=0 );
+  border-color: #999;
+  color: #666;
+}
+.btn3:hover {
+  background: -moz-linear-gradient(center top , white 0pt, #ECECEC 100%) repeat scroll 0 0 transparent;
+  background: -webkit-gradient(linear, center top, center bottom, from(#FFF), to(#ECECEC));
+}
+
+.btn-disabled {
+  background: #CECECE;
+  background: -moz-linear-gradient(top, #F2F2F2 0, #F2F2F2 1px, #E4E4E4 1px, #CECECE 100%);
+  background: -o-linear-gradient(top, #F2F2F2 0, #F2F2F2 1px, #E4E4E4 1px, #CECECE 100%);
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0,#F2F2F2), color-stop(5%,#F2F2F2), color-stop(5%,#E4E4E4), color-stop(100%,#CECECE));
+  background: linear-gradient(top, #F2F2F2 0, #F2F2F2 1px, #E4E4E4 1px, #CECECE 100%);
+  color: #EEE;
+}
+
+/* red */
+.btn6 {
+  background: #cc9999;
+  background: -moz-linear-gradient(top, #cc6161 0, #cc6161 1px, #cc0000 1px, #931100 100%);
+  background: -o-linear-gradient(top, #cc6161 0, #cc6161 1px, #cc0000 1px, #931100 100%);
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0,#cc6161), color-stop(5%,#cc6161), color-stop(5%,#cc0000), color-stop(100%,#931100));
+  background: linear-gradient(top, #cc6161 0, #cc6161 1px, #cc0000 1px, #931100 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cc0000', endColorstr='#931100',GradientType=0 );
+  border-color: #931100;
+  color: #fff;
+}
+
+.btn6:hover {
+  background: #cc9999;
+  background: -moz-linear-gradient(top, #cc6161 0, #cc6161 1px, #CC4343 1px, #912C21 100%);
+  background: -o-linear-gradient(top, #cc6161 0, #cc6161 1px, #CC4343 1px, #912C21 100%);
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0,#cc6161), color-stop(5%,#cc6161), color-stop(5%,#CC4343), color-stop(100%,#912C21));
+  background: linear-gradient(top, #cc6161 0, #cc6161 1px, #CC4343 1px, #931100 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#CC4343', endColorstr='#912C21',GradientType=0 );
+  border-color: #912C21;
+  color: #fff;
+}
+
+/* confirm modal */
+
+.modalContainer2 {
+  display: none;
+  position: absolute;
+}
+
+.modalBackground2 {
+	position: absolute;
+	display: none;
+	left: 0px;
+	right: 0px;
+	top: 0px;
+	bottom: 0px;
+	background-color: rgba(0, 0, 0, 0.4);
+}
+
+.search-input {
+  border: 1px solid;
+  border-color: #7C7C7C #C3C3C3 #DDDDDD;
+  float: right;
+  height: 18px;
+  line-height: 12px;
+  padding: 4px 2px 0;
+  width: 310px;
+}
+
+.search-btn {
+  background: -moz-linear-gradient(center top , #E8E8E8 0pt, #CCC 100%) repeat scroll 0 0 transparent;
+  background: -webkit-gradient(linear, center top, center bottom, from(#E8E8E8), to(#CCC));
+  border: 1px solid #999;
+  border-top-right-radius: 3px;
+  border-bottom-right-radius: 3px;
+  border-left: none;
+  color: #666;
+  float: right;
+  font-weight: bold;
+  height: 24px;
+  font-size: 10pt;
+}
+
+.search-btn:hover {
+  background: -moz-linear-gradient(center top , #F0F0F0 0pt, #DDD 100%) repeat scroll 0 0 transparent;
+  background: -webkit-gradient(linear, center top, center bottom, from(#F0F0F0), to(#DDD));
+  cursor: pointer;
+}
+
+.advfilter-btn {
+  background: -moz-linear-gradient(center top , #E8E8E8 0pt, #CCC 100%) repeat scroll 0 0 transparent;
+  background: -webkit-gradient(linear, center top, center bottom, from(#E8E8E8), to(#CCC));
+  border: 1px solid #999;
+  border-top-right-radius: 3px;
+  border-bottom-right-radius: 3px;
+  border-left: none;
+  color: #666;
+  float: right;
+  font-weight: bold;
+  height: 24px;
+  font-size: 10pt;
+}
+
+.advfilter-btn:hover {
+  background: -moz-linear-gradient(center top , #F0F0F0 0pt, #DDD 100%) repeat scroll 0 0 transparent;
+  background: -webkit-gradient(linear, center top, center bottom, from(#F0F0F0), to(#DDD));
+  cursor: pointer;
+}
+
+
+#scheduled-jobs-content,
+#executing-jobs-content {
+  display: none;
+}
+
+.subpage-nav {
+  float: left;
+  overflow: hidden;
+  padding-top: 4px;
+  width: 250px;
+}
+
+.subpage-nav li {
+  float: left;
+  padding: 0 10px;
+  border-right: 1px solid #848484;
+}
+
+.subpage-nav .last {
+  border-right: none;
+}
+
+.subpage-nav a {
+  color: #006699;
+  text-decoration: none;
+}
+
+.subpage-nav .selected {
+  color: #000;
+  font-weight: bold;
+}
+
+.job-properties  {
+  clear: both;
+  font-size: 13px;
+  margin-top: 50px;
+  overflow: hidden;
+}
+
+.job-properties dt {
+  clear: both;
+  float: left;
+  font-weight: bold;
+  padding-bottom: 3px;
+  width: 110px;
+}
+
+.job-properties dd {
+  float: left;
+  padding-bottom: 3px;
+}
+
+.tb-key {
+  padding-left: 2.72727%;
+  width: 40%;
+}
+
+.tb-value {
+  padding-left: 5%;
+}
+
+.no-jobs {
+  padding: 0 0 25px 2.72727%;
+}
+
+.modal {
+  display: none;
+  background-color: #fff;
+  border: 1px solid #DDD;
+  -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  overflow: hidden;
+}
+
+.modal p {
+	margin-left: 30px;
+}
+
+.modal h3 {
+  border-bottom: 1px solid #d0d0d0;
+  font-weight: bold;
+  margin: 20px 20px 10px 20px;
+  padding-bottom: 8px; 
+}
+
+.modal h4 {
+  font-weight: bold;
+  margin: 20px 20px 10px 40px;
+  padding-bottom: 8px;
+}
+
+.modal .message {
+  padding: 20px;
+}
+
+.modal .actions {
+  clear: both;
+  background-color: #f0f0f0;
+  margin-top: 10px;
+  overflow: hidden;
+  padding: 16px 16px 20px 0;
+}
+
+.modalContainer2.modal .actions {
+  position: absolute;
+  background-color: #f0f0f0;
+  margin-top: 10px;
+  overflow: hidden;
+  padding: 16px 16px 20px 0;
+  bottom: 0px;
+  right: 0px;
+  left: 0px;
+}
+
+.modal .btn1,
+.modal .btn2,
+.modal .btn3,
+.modal .btn6 {
+  float: right;
+  margin-left: 10px;
+}
+
+.modal-close {
+  color: #666;
+  font-weight: bold;
+  text-decoration: none;
+  position: absolute;
+  top: 10px;
+  right: 17px;
+}
+
+.modal dt {
+  clear: both;
+  float: left;
+  padding: 0 10px 6px 0;
+  text-align: right;
+  font-weight: bold;
+  font-size: 11pt;
+  width: 150px;
+}
+
+.modal dd {
+  float: left;
+  padding-bottom: 6px;
+}
+
+#change-permission dt {
+  clear: none;
+  width: 75px;
+  padding: 0 0 0 0;
+}
+
+#change-permission dt.nextline {
+	clear: both;
+}
+
+#user-box {
+	background-color: #FFF;
+	border-width: 1px;
+	border-color: #CCC;
+	width: 300px;
+	margin-left: 10px;
+}
+
+#create-project #overwrite {
+  width: 12px;
+}
+
+.simplemodal-wrap {
+  overflow: visible !important;
+}
+
+#schedule-job .message {
+  padding-top: 0;
+}
+
+.message p {
+  margin-bottom: 15px;
+}
+
+#create-project dt {
+  width: 100px;
+}
+
+#create-project input {
+  width: 280px;
+}
+
+#ui-datepicker-div {
+  display: none;
+}
+
+.filter_statuses {
+  float: right;
+  margin-right: 25px;
+}
+
+.joblist:hover a {
+  display: inline;
+}
+
+/* clean up */
+.state-icon {
+  background-image: url("../../js/jqueryui/themes/custom-theme/images/ui-icons_cccccc_256x240.png");
+  cursor: pointer;
+  display: block;
+  float: left;
+  height: 16px;
+  margin-right: 5px;
+  width: 16px;
+}
+
+.flowSubmenu li {
+	clear: both;
+}
+
+.flowSubmenu a {
+	float: left;
+	width: 70%;
+}
+
+.context-sub-icon {
+  float: right;
+  background-image: url("../../js/jqueryui/themes/custom-theme/images/ui-icons_cccccc_256x240.png");
+  cursor: pointer;
+  display: block;
+  height: 16px;
+  margin-right: 5px;
+  width: 16px;
+  background-position: -32px -16px;
+}
+
+.collapse.context-sub-icon {
+  	background-position: 0 -16px;
+}
+
+.collapse.state-icon {
+	background-position: 0 -16px;
+}
+
+.collapse tr {
+	border-bottom: none;
+}
+
+.expand .state-icon {
+	background-position: -32px -16px;
+}
+
+.wait .state-icon {
+	background-position: -64px -80px
+}
+
+.tb-name a {
+	font-size: 10pt;
+	text-decoration: none;
+	color: #000;
+}
+
+.tb-name a:hover {
+	color: #009FC9;
+}
+
+.azkaban-charts,
+.azkaban-charts td {
+	width: 100%;
+}
+
+.azkaban-charts td {
+  border: none;
+  padding: 0;
+}
+
+.treeline {
+	background: url(../../images/treeview-default-line.gif) 0 0 no-repeat;
+	float: left;
+	height: 22px;
+}
+
+.treeline.last { background-position: 0 -1766px }
+
+.joblist {
+  margin-left: 10px;
+}
+
+.joblist a {
+  color: #006699;
+  padding-left: 15px;
+}
+
+.joblist .job-name {
+  color: #666;
+  text-decoration: none;
+}
+
+.joblist .hidden {
+  display: none;
+}
+
+#login {
+	width: 500px;
+	margin: 50px auto;
+}
+
+.login-form {
+    margin-top: 10px;
+}
+
+.login-form p {
+	margin-top: 10px;
+}
+
+.login-textbox {
+	width: 300px;
+	border-style: solid;
+	border-color: #CCC;
+	height: 20px;
+	font-size: 11pt;
+	position: relative;
+	float: left;
+}
+
+.login-password {
+	width: 100%;
+	height: 300px;
+}
+
+.login-label {
+	clear: both;
+	text-align: right;
+	width: 120px;
+	float: left;
+	margin: 10px;
+	font-size: 11pt;
+	font-weight: bold;
+}
+
+.login-submit {
+	clear: both;
+    color: #333;   
+    font: bold 12pt 'trebuchet ms',helvetica,sans-serif;
+    margin-top: 20px;
+    padding: 3px 20px;
+    
+}
+
+.box-title {
+  margin-top: 15px;
+  padding: 5px 12px;
+  font-size: 14pt;
+  font-weight: bold;
+}
+
+.box-success-message {
+  background-color: #4e911e;
+  margin: 0px 2px;
+  padding: 2px 12px;
+  color: white;
+}
+
+.box-error-message {
+  background-color: #C00000;
+  margin: 0px 2px;
+  padding: 2px 12px;
+  color: white;
+}
+
+.shadow-box {
+  -moz-box-shadow: 5px 5px 5px #CCC;
+  -webkit-box-shadow: 5px 5px 5px #CCC;
+  box-shadow: 5px 5px 5px #CCC;
+  background-color: white;
+  border-style: solid;
+  border-width: 1px;
+  border-color: #AAA;
+}
+
+.shadow-box-header {
+	margin-left: 20px;
+	margin-right: 20px;
+	border-bottom-width: 1px;
+	border-bottom-style: solid;
+	border-bottom-color: #AAA;
+}
+
+.shadow-box-content {
+	margin-left: 20px;
+	margin-right: 20px;
+}
+
+.shadow-box-footer {
+  clear: both;
+  background-color: #EEE;
+  height: 50px;
+}
+
+.shadow-box-footer .button1 {
+	float: right;
+	margin-right: 10px;
+	margin-top: 10px;
+	padding-left: 15px;
+	padding-right: 15px;
+}
+
+#user-id {
+  position: absolute;
+  right:40px;
+  top: 28px;
+  font-size: 100%;
+  height: 40px;
+  margin: 3px;
+}
+
+#user-id a {
+  color: #CCC;
+  text-decoration: none;
+  cursor: pointer;
+}
+
+#user-id a:hover {
+  text-decoration: underline;
+}
+
+#user-down {
+  float: right;
+  background-image: url("../js/jqueryui/themes/custom-theme/images/ui-icons_cccccc_256x240.png");
+  height: 16px;
+  width: 16px;
+  background-position: -64px -16px;
+}
+
+#user-down:hover {
+  cursor: pointer;
+}
+
+#user-menu {
+	position: absolute;
+	background: #222;
+	width: 75px;
+	padding-left: 5px;
+	padding-top: 2px;
+	padding-bottom: 2px;
+	-moz-border-radius: 4px;
+	border-radius: 4px;
+	top: 20px;
+}
+
+/*project manager page*/
+#project-summary {
+	margin-left: 30px;
+	margin-bottom: 10px;
+	width: 60%;
+}
+
+#project-users {
+	float: right;
+	margin-right: 30px;
+	margin-bottom: 10px;
+	width: 30%;
+}
+
+#adminActions {
+	
+}
+
+#job-summary {
+	margin-left: 30px;
+	margin-bottom: 10px;
+	width:90%;
+}
+
+#job-summary table tr td a {
+	text-decoration: none;
+	color: #555;
+	margin-left: 0px;
+	margin-right: 10px;
+}
+
+#job-summary table tr td span {
+	color: #555;
+}
+
+#job-summary table tr td a:hover {
+	text-decoration: none;
+	color: #009FC9;
+}
+
+#job-summary .first {
+	width: 100px;
+}
+
+.summary-table {
+	font-size: 12px;
+	background: none;
+	border-style: none;
+	border-width: 0px;
+}
+.summary-table .first {
+	min-width: 100px;
+	font-weight: bold;
+}
+
+.summary-table td {
+	border-style: none;
+}
+
+.summary-table td.left{
+	text-align: left;
+}
+
+.user-table {
+	font-size: 12px;
+	background: none;
+	border-style: none;
+	border-width: 0px;
+}
+.user-table .first {
+	width: 150px;
+	font-weight: bold;
+}
+
+.user-table td {
+	border-style: none;
+}
+
+/* Style for job display table */
+.childrow td.innerTd {
+	padding: 0px;
+	height: 100px;
+	width: 100%;
+}
+
+/* Style for job display table */
+.childrow {
+	padding: 0px;
+	width: 100%;
+}
+
+.childrow .innerTable {
+	margin-left:auto;
+	margin-right: auto;
+	text-align: center;
+	width: 90%;
+}
+
+.childrow .expandedFlow {
+	border-style: none;
+	background-color: #FFF;
+}
+
+.childrow:hover td {
+	background-color: #FFF;
+}
+
+.childrow .expandedFlow:hover {
+	border-style: none;
+	background-color: #FFF;
+}
+
+.childrow .expandedFlow td{
+	border-style: solid solid none none;
+}
+
+.childrow .innerTable {
+	border-style: none none solid solid;
+	border-width: 1px;
+	border-color: #CDCDCD;
+}
+
+.childrow .innerTable tr {
+}
+
+.childrow .innerTable td {
+	border-style: solid solid none none;
+	border-width: 1px 1px medium medium;
+	border-color: #CDCDCD;
+}
+
+.childrow .innerTable a {
+	cursor: pointer;
+}
+
+.childrow .innerTable a:hover {
+	color: #009FC9;
+}
+
+.childrow .innerTable a.dependent {
+	color: #3B8194;
+}
+
+.childrow .innerTable a.dependency {
+	color: #0099CC;
+}
+
+.childrow .innerJobRow {
+	border-top: none;
+	height: 100px;
+}
+
+.headertabs {
+	height: 26px;
+	width:100%;
+	background-image: -o-linear-gradient(bottom, rgb(56,56,56) 33%, rgb(73,73,73) 66%);
+	background-image: -moz-linear-gradient(bottom, rgb(56,56,56) 33%, rgb(73,73,73) 66%);
+  background-image: -webkit-linear-gradient(bottom, rgb(56,56,56) 33%, rgb(73,73,73) 66%);
+  background-image: -ms-linear-gradient(bottom, rgb(56,56,56) 33%, rgb(73,73,73) 66%);
+  background-image: -webkit-gradient(
+  	linear,
+  	left bottom,
+  	left top,
+  	color-stop(0.33, rgb(56,56,56)),
+  	color-stop(0.66, rgb(73,73,73))
+  );
+  background-image: linear-gradient(bottom, rgb(56,56,56) 33%, rgb(73,73,73) 66%);
+  color: #fff;
+  font-weight: bold;
+  line-height: 1em;
+  font-size: 10.5pt;
+}
+
+.headertabs ul li {
+	float: left;
+	margin-top: 5px;
+	margin-left: 12px;
+}
+
+.headertabs ul.buttons {
+	float: right;
+	margin-right: 10px;
+}
+
+.headertabs ul.buttons li {
+	margin-top: 1px;
+	margin-left: 2px;
+}
+
+.headertabs ul li.lidivider {
+	color: #808080;
+}
+
+.headertabs ul li:hover {
+	
+}
+
+/* Flow view tabs */
+.headertabs ul li a {
+	color: #aaa;
+}
+
+.headertabs ul li a:hover {
+	color: #fff;
+}
+
+/* Flow view tabs */
+.headertabs ul li a.selected {
+	color: #fff;
+}
+
+.actualcontent {
+	clear: both;
+}
+
+/* Graph SVG */
+#graphView {
+	position: absolute;
+	top: 210px;
+	bottom: 5px;
+	left: 50px;
+	right: 50px;
+	padding: 10px;
+	background: #E0E0E0;
+}
+
+#jobListView {
+	position: absolute;
+	top: 210px;
+	bottom: 5px;
+	left: 50px;
+	right: 50px;
+	padding: 0px;
+	background: #E0E0E0;
+	overflow-y: auto;
+}
+
+.logView {
+	position: absolute;
+	top: 210px;
+	bottom: 5px;
+	left: 50px;
+	right: 50px;
+	background: #E0E0E0;
+}
+
+#flowLogView {
+	top: 210px;
+	bottom: 5px;
+}
+
+#jobLogView {
+	top: 210px;
+	bottom: 5px;
+}
+
+.logHeader {
+	height: 30px;
+	margin: 0px;
+	width: 100%;
+	background-color: #CCC;
+}
+
+.logButtonRow {
+	padding-top: 4px;
+	padding-left: 4px;
+}
+
+.logViewer {
+	position: absolute;
+	top: 35px;
+	bottom: 5px;
+	left: 5px;
+	right: 5px;
+	background-color: #FFF;
+	overflow:auto;
+}
+
+.logLink {
+	text-align: center;
+}
+
+.logLink a {
+	text-decoration: underline;
+	margin: 0px;
+}
+
+.log {
+	padding-left: 15px;
+	font-family: "courier";
+	font-size: 10pt;
+}
+
+#logTable td.time {
+	width: 160px;
+}
+
+#logTable td.user {
+	width: 80px;
+}
+
+#logTable td.type {
+	width: 160px;
+}
+
+.relative {
+	position: relative;
+	width: 100%;
+	height: 100%;
+}
+
+#editIcon {
+	text-align: center;
+}
+
+#toolsBar .btn3{
+	float: left;
+	margin-left: 3px;
+}
+
+.svgGraph {
+	width: 100%;
+	height: 100%;
+	background: #fff;
+}
+
+
+.svgDiv {
+	position: absolute;
+	top: 0px;
+	right: 0px;
+	left: 260px;
+	bottom: 0px;
+}
+
+.radioLabel.disabled {
+	opacity: 0.3;
+}
+
+#executing-options {
+	left: 100px;
+	right: 100px;
+	top: 50px;
+	bottom: 40px;
+}
+
+#executing-options .svgDiv {
+	position: absolute;
+	background-color: #CCC;
+	padding: 1px;
+	left: 270px;
+	right: 0px;
+	top: 0px;
+	bottom: 0px;
+}
+
+#executing-options .jobList {
+	position: absolute;
+	width: 255px;
+	top: 0px;
+	bottom: 0px;
+	padding: 5px;
+	background-color: #F0F0F0;
+}
+
+#executing-options .list {
+	width: 255px;
+}
+
+#executing-options ul.optionsPicker {
+	margin-left: 30px;
+}
+
+#executing-options ul.optionsPicker li {
+	float: left;
+	font-size: 12pt;
+	font-weight: bold;
+	margin-right: 15px;
+	cursor: pointer;
+	color: #CCC;
+}
+
+#executing-options ul.optionsPicker li.selected {
+	text-decoration: underline;
+	color: #000;
+}
+
+#executing-options ul.optionsPicker li.selected:hover {
+	color: #000;
+}
+
+#executing-options ul.optionsPicker li:hover {
+	color: #888;
+}
+
+#executing-options .optionsPane {
+	position: absolute;
+	top: 85px;
+	background-color: #FFF;
+	left: 0px;
+	right: 0px;
+	bottom: 0px;
+}
+
+#executing-options .panel {
+	position: absolute;
+	width: 100%;
+	top: 0px;
+	bottom: 65px;
+}
+
+#executing-options .generalPanel.panel {
+	background-color: #F4F4F4;
+	padding-top: 15px;
+}
+
+#executing-options h3 {
+	margin-left: 20px;
+	font-size: 14pt;
+	border-bottom: 1px solid #CCC;
+}
+
+#executing-options h4 {
+	margin-left: 20px;
+	font-size: 12pt;
+	border-bottom: 1px solid #CCC;
+}
+
+#sla-options {
+	left: 100px;
+	right: 100px;
+	top: 50px;
+	bottom: 40px;
+}
+
+#sla-options .svgDiv {
+	position: absolute;
+	background-color: #CCC;
+	padding: 1px;
+	left: 270px;
+	right: 0px;
+	top: 0px;
+	bottom: 0px;
+}
+
+#sla-options .jobList {
+	position: absolute;
+	width: 255px;
+	top: 0px;
+	bottom: 0px;
+	padding: 5px;
+	background-color: #F0F0F0;
+}
+
+#sla-options .list {
+	width: 255px;
+}
+
+#sla-options ul.optionsPicker {
+	margin-left: 30px;
+}
+
+#sla-options ul.optionsPicker li {
+	float: left;
+	font-size: 12pt;
+	font-weight: bold;
+	margin-right: 15px;
+	cursor: pointer;
+	color: #CCC;
+}
+
+#sla-options ul.optionsPicker li.selected {
+	text-decoration: underline;
+	color: #000;
+}
+
+#sla-options ul.optionsPicker li.selected:hover {
+	color: #000;
+}
+
+#sla-options ul.optionsPicker li:hover {
+	color: #888;
+}
+
+#sla-options .optionsPane {
+	position: absolute;
+	top: 85px;
+	background-color: #FFF;
+	left: 0px;
+	right: 0px;
+	bottom: 0px;
+}
+
+#sla-options .panel {
+	position: absolute;
+	width: 100%;
+	top: 0px;
+	bottom: 65px;
+}
+
+#sla-options .generalPanel.panel {
+	background-color: #F4F4F4;
+	padding-top: 15px;
+}
+
+#sla-options h3 {
+	margin-left: 20px;
+	font-size: 14pt;
+	border-bottom: 1px solid #CCC;
+}
+
+#sla-options h4 {
+	margin-left: 20px;
+	font-size: 12pt;
+	border-bottom: 1px solid #CCC;
+}
+
+
+#job-edit-pane {
+	left: 100px;
+	right: 100px;
+	top: 50px;
+	bottom: 40px;
+}
+
+#job-edit-pane .list {
+	width: 255px;
+}
+
+#job-edit-pane .optionsPane {
+	position: absolute;
+	top: 85px;
+	background-color: #FFF;
+	left: 0px;
+	right: 0px;
+	bottom: 0px;
+}
+
+#job-edit-pane .panel {
+	position: absolute;
+	width: 100%;
+	top: 0px;
+	bottom: 65px;
+}
+
+#job-edit-pane .generalPanel.panel {
+	background-color: #F4F4F4;
+	padding-top: 15px;
+}
+
+#job-edit-pane h3 {
+	margin-left: 20px;
+	font-size: 14pt;
+	border-bottom: 1px solid #CCC;
+}
+
+#job-edit-pane h4 {
+	margin-left: 20px;
+	font-size: 12pt;
+	border-bottom: 1px solid #CCC;
+}
+
+#schedule-options {
+	left: 100px;
+	right: 100px;
+	top: 50px;
+	bottom: 40px;
+}
+
+#schedule-options .svgDiv {
+	position: absolute;
+	background-color: #CCC;
+	padding: 1px;
+	left: 270px;
+	right: 0px;
+	top: 0px;
+	bottom: 0px;
+}
+
+#schedule-options .jobList {
+	position: absolute;
+	width: 255px;
+	top: 0px;
+	bottom: 0px;
+	padding: 5px;
+	background-color: #F0F0F0;
+}
+
+#schedule-options .list {
+	width: 255px;
+}
+
+#schedule-options ul.optionsPicker {
+	margin-left: 30px;
+}
+
+#schedule-options ul.optionsPicker li {
+	float: left;
+	font-size: 12pt;
+	font-weight: bold;
+	margin-right: 15px;
+	cursor: pointer;
+	color: #CCC;
+}
+
+#schedule-options ul.optionsPicker li.selected {
+	text-decoration: underline;
+	color: #000;
+}
+
+#schedule-options ul.optionsPicker li.selected:hover {
+	color: #000;
+}
+
+#schedule-options ul.optionsPicker li:hover {
+	color: #888;
+}
+
+#schedule-options .optionsPane {
+	position: absolute;
+	top: 85px;
+	background-color: #FFF;
+	left: 0px;
+	right: 0px;
+	bottom: 0px;
+}
+
+#schedule-options .panel {
+	position: absolute;
+	width: 100%;
+	top: 0px;
+	bottom: 65px;
+}
+
+#schedule-options .generalPanel.panel {
+	background-color: #F4F4F4;
+	padding-top: 15px;
+}
+
+#schedule-options h3 {
+	margin-left: 20px;
+	font-size: 14pt;
+	border-bottom: 1px solid #CCC;
+}
+
+#schedule-options h4 {
+	margin-left: 20px;
+	font-size: 12pt;
+	border-bottom: 1px solid #CCC;
+}
+
+#graphPanel {
+	background-color: #F0F0F0;
+}
+
+#generalPanel {
+	overflow: auto;
+}
+
+#generalPanel dt {
+	width: 150px;
+	font-size: 10pt;
+	font-weight: bold;
+	margin-top: 5px;
+}
+
+#generalPanel textarea {
+	width: 500px;
+}
+
+#generalPanel table #addRow {
+	cursor: pointer;
+}
+
+#generalPanel table tr {
+	height: 24px;
+}
+
+#generalPanel table .editable {
+
+}
+
+#generalPanel table .editable input {
+	border: 1px solid #009FC9;
+	height: 16px;
+}
+
+#generalPanel table .name {
+	width: 40%;
+}
+
+#generalPanel span.addIcon {
+	display: block;
+	width: 16px;
+	height: 16px;
+	background-image: url("./images/addIcon.png");
+}
+
+#generalPanel span.removeIcon {
+	display: block;
+	visibility:hidden;
+	disabled: true;
+	width: 16px;
+	height: 16px;
+	background-image: url("./images/removeIcon.png");
+	cursor: pointer;
+}
+
+#generalPanel .editable:hover span.removeIcon {
+	visibility:visible;
+}
+
+#generalPanel {
+}
+
+#generalPanel span {
+	float: left;
+	margin-left: 5px;
+}
+
+#generalPanel dd {
+	font-size: 10pt;
+}
+
+#flowPropertyOverride {
+	clear: both;
+	padding-top: 30px;
+}
+
+#flowPropertyOverride .tableDiv {
+	padding-right: 20px;
+	padding-left: 20px;
+}
+
+#jobList {
+	position: absolute;
+	top: 0px;
+	left: 0px;
+	height: 100%;
+	width: 250px;
+}
+
+.resetPanZoomBtn {
+	position: absolute;
+	bottom: 90px;
+}
+
+#nodeOptions {
+	position: absolute;
+	bottom: 10px;
+}
+
+#flowProperties {
+	position: absolute:
+	height: 100px;
+	width: 100%;
+	background-color: #000;
+	top: 100px;
+}
+
+#scheduleGraphPanel {
+	background-color: #F0F0F0;
+}
+
+#scheduleGeneralPanel {
+	overflow: auto;
+}
+
+#scheduleGeneralPanel dt {
+	width: 150px;
+	font-size: 10pt;
+	font-weight: bold;
+	margin-top: 5px;
+}
+
+#scheduleGeneralPanel textarea {
+	width: 500px;
+}
+
+#scheduleGeneralPanel table #addRow {
+	cursor: pointer;
+}
+
+#scheduleGeneralPanel table tr {
+	height: 24px;
+}
+
+#scheduleGeneralPanel table .editable {
+
+}
+
+#scheduleGeneralPanel table .editable input {
+	border: 1px solid #009FC9;
+	height: 16px;
+}
+
+#scheduleGeneralPanel table .name {
+	width: 40%;
+}
+
+#scheduleGeneralPanel span.addIcon {
+	display: block;
+	width: 16px;
+	height: 16px;
+	background-image: url("./images/addIcon.png");
+}
+
+#scheduleGeneralPanel span.removeIcon {
+	display: block;
+	visibility:hidden;
+	disabled: true;
+	width: 16px;
+	height: 16px;
+	background-image: url("./images/removeIcon.png");
+	cursor: pointer;
+}
+
+#scheduleGeneralPanel .editable:hover span.removeIcon {
+	visibility:visible;
+}
+
+#scheduleGeneralPanel {
+}
+
+#scheduleGeneralPanel span {
+	float: left;
+	margin-left: 5px;
+}
+
+#scheduleGeneralPanel dd {
+	font-size: 10pt;
+}
+
+#scheduleFlowPropertyOverride {
+	clear: both;
+	padding-top: 30px;
+}
+
+#scheduleFlowPropertyOverride .tableDiv {
+	padding-right: 20px;
+	padding-left: 20px;
+}
+
+#scheduleJobList {
+	position: absolute;
+	top: 0px;
+	left: 0px;
+	height: 100%;
+	width: 250px;
+}
+
+.filter {
+	width: 100%;
+}
+
+
+.list {
+	position: absolute;
+	background-color: #fff;
+	margin-right: 10px;
+	border: solid;
+	border-color: #CCC;
+	border-width: 1px;
+	overflow: auto;
+	top: 26px;
+	width: 100%;
+	bottom: 120px;
+}
+
+.list ul {
+	white-space: nowrap
+}
+
+.list ul li {
+	margin: 4px 5px;
+	border-bottom: 1px solid #EEE;
+	cursor: pointer;
+	background-position: 16px 0px;
+}
+
+.list ul li:hover {
+	background-color: #E1E3E2;
+	color: #009FC9;
+}
+
+.list ul li.selected {
+	background-color: #009FC9;
+	color: #EEE;
+}
+
+.list ul li.nodedisabled {
+	opacity: 0.3;
+}
+
+.list ul li.DISABLED {
+	opacity: 0.3;
+}
+
+.list ul li.DISABLED .icon {
+	background-position: 16px 0px;
+}
+
+.list ul li.READY .icon {
+	background-position: 16px 0px;
+}
+
+.list ul li.RUNNING .icon {
+	background-position: 32px 0px;
+}
+
+.list ul li.SUCCEEDED .icon {
+	background-position: 48px 0px;
+}
+
+.list ul li.FAILED .icon {
+	background-position: 0px 0px;
+}
+
+.list ul li.KILLED .icon {
+	background-position: 0px 0px;
+}
+
+.list ul li a {
+	font-size: 10pt;
+	margin-left: 5px;
+}
+
+.list ul li a span {
+	background-color: #FF0;
+	color: black;
+}
+
+.list ul li .icon {
+	float: left;
+	width: 16px;
+	height: 16px;
+	background-image: url("./images/dot-icon.png");
+	background-position: 16px 0px;
+}
+
+#messageDialog .messageDiv {
+	margin: 20px;
+}
+
+table.parameters tr td.first {
+	font-weight: bold;
+}
+
+table.parameters tr td {
+	font-size: 11pt;
+	padding-left: 10px;
+}
+
+#pdescription {
+	width: 70%;
+}
+
+.editTextArea {
+	width: 100%;
+}
+
+#edit {
+	width: 100px;
+	text-align: center;
+}
+
+#group-permissions-table {
+	margin-top: 20px;
+}
+
+.permission-table .tb-username {
+	margin: 0px;
+}
+
+.permission-table .tb-perm {
+	width: 60px;
+	margin: 0px;
+}
+
+.permission-table .tb-admin {
+	width: 60px;
+	margin: 0px;
+}
+
+.permission-table .tb-read {
+	width: 60px;
+	margin: 0px;
+}
+
+.permission-table .tb-write {
+	width: 60px;
+	margin: 0px;
+}
+
+.permission-table .tb-execute {
+	width: 60px;
+	margin: 0px;
+}
+
+.permission-table .tb-schedule {
+	margin: 0px;
+	width: 60px;
+}
+
+.permission-table .tb-action {
+	margin: 0px;
+	width: 100px;
+}
+
+.permission-table thead tr th.tb-username {
+	padding-left: 15px;
+	text-align:left;
+}
+
+.permission-table thead tr th {
+	text-align:center;
+}
+
+.permission-table tbody tr td.tb-name {
+	text-align:left;
+}
+
+.permission-table tbody tr td {
+	text-align:center;
+}
+
+svg .edge {
+	stroke: #777;
+	stroke-width: 2;
+}
+
+svg .edge:hover {
+	stroke: #009FC9;
+	stroke-width: 4;
+}
+
+svg .node.disabled {
+	opacity: 0.3;
+}
+
+svg .node .backboard {
+	fill: #FFF;
+	opacity: 0.05;
+}
+
+svg .node:hover {
+	cursor: pointer;
+}
+
+svg .node:hover .backboard {
+	opacity: 0.7;
+}
+
+svg .selected .backboard {
+	opacity: 0.4;
+}
+
+svg .node circle {
+	fill: #888;
+	stroke: #777;
+	stroke-width: 2;
+}
+
+svg .node:hover circle {
+	stroke: #009FC9;
+}
+
+svg .node:hover text {
+	fill: #009FC9;
+}
+
+svg .selected text {
+	fill: #338AB0;
+}
+
+svg .selected circle {
+	stroke: #009FC9;
+	stroke-width: 4;
+}
+
+svg .READY circle {
+	fill: #CCC;
+}
+
+svg .RUNNING circle {
+	fill: #009FC9;
+}
+
+svg .FAILED circle {
+	fill: #CC0000;
+}
+
+svg .KILLED circle {
+	fill: #CC0000;
+}
+
+svg .SUCCEEDED circle {
+	fill: #00CC33;
+}
+
+svg .DISABLED circle {
+	opacity: 0.3;
+}
+
+svg .SKIPPED circle {
+	opacity: 0.3;
+}
+
+#Used for charts
+svg circle.READY {
+	stroke: #CCC;
+	stroke-width: 2px;
+	fill: #FFF;
+}
+
+svg circle.RUNNING {
+	stroke: #009FC9;
+	stroke-width: 2px;
+	fill: #FFF;
+}
+
+svg circle.FAILED {
+	stroke: #CC0000;
+	stroke-width: 2px;
+	fill: #FFF;
+}
+
+svg circle.KILLED {
+	stroke: #CC0000;
+	stroke-width: 2px;
+	fill: #FFF;
+}
+
+svg circle.SUCCEEDED {
+	stroke: #00CC33;
+	stroke-width: 2px;
+	fill: #FFF;
+}
+
+svg circle.DISABLED {
+	stroke: #CCC;
+	opacity: 0.3;
+	stroke-width: 2px;
+	fill: #FFF;
+}
+
+svg circle.SKIPPED {
+	stroke: #CCC;
+	opacity: 0.3;
+	stroke-width: 2px;
+	fill: #FFF;
+}
+
+span.sublabel {
+	font-size: 8pt;
+	margin-left: 12px;
+	color: #333;
+}
+
+#td-adduser {
+	text-align: left;
+	padding-left: 12px;
+}
+
+#pageSelection {
+}
+
+#pageSelection ul {
+	margin-top: 5px;
+}
+
+#pageSelection ul li:hover {
+	background-color: #D5F2FF;
+}
+
+#pageSelection ul li.first {
+	border-left: 1px solid #CCC; 
+}
+
+#pageSelection ul li {
+	float: left;
+	background-color: #FFF;
+	border-top: 1px solid #CCC;
+	border-bottom: 1px solid #CCC;
+	border-right: 1px solid #CCC;
+	cursor: pointer;
+	padding-top: 8px;
+	padding-bottom: 8px;
+	font-size: 11pt;
+	text-decoration: none;
+	color: #3398cc;
+}
+
+#pageSelection ul li.disabled {
+	cursor: default;
+	color: #CCC;
+}
+
+#pageSelection ul li a{
+	font-size: 11pt;
+	text-decoration: none;
+	color: inherit;
+	cursor: inherit;
+	padding: 8px 12px;
+}
+
+#pageSelection ul li .arrow{
+	top: 0px;
+	margin: 0px 6px;
+}
+
+#pageSelection ul li.selected{
+	background-color: #c7eeff;
+}
+
+#flow-status {
+	position: absolute;
+	top: 115px;
+	right: 55px;
+	width: 420px;
+}
+
+#flow-status table {
+	float: left;
+	border: none;
+	background: none;
+	width: 190px;
+	margin-left: 10px;
+}
+
+#flow-status table.status {
+	width: 200px;
+}
+
+#flow-status table.status td {
+	font-size: 11.5pt;
+}
+
+#flow-status td.first {
+	font-weight: bold;
+}
+
+#flow-status table tr {
+}
+
+#flow-status table td {
+	border: none;
+	padding: 1px;
+	font-size: 12px;
+}
+
+
+#flow-status table td.SKIPPED {
+	color:  #AAA;
+}
+
+#flow-status table td.SUCCEEDED {
+	color:  #4e911e;
+}
+
+#flow-status table td.RUNNING {
+	color:  #009FC9;
+}
+
+#flow-status table td.FAILED {
+	color: #CC0000;
+}
+
+#flow-status table td.PAUSED {
+	color: #FF6600;
+}
+
+#flow-status table td.FAILED_FINISHING {
+	color:  #CC0000;
+}
+
+#flow-status table td.KILLED {
+	color:  #CC0000;
+}
+
+#flowStatus {
+	font-weight: bold;
+}
+
+.executionInfo table th.date {
+	width: 140px;
+}
+
+.executionInfo table th.execid {
+	width: 80px;
+}
+
+.executionInfo table th.project {
+	width: 200px;
+}
+
+.executionInfo table th.user {
+	width: 60px;
+}
+
+.executionInfo table th.elapse {
+	width: 90px;
+}
+
+.executionInfo table th.status {
+	width: 100px;
+}
+
+.executionInfo table th.logs {
+	width: 10px;
+}
+
+.executionInfo table th.timeline {
+	width: 280px;
+}
+
+.executionInfo table th.action {
+	width: 20px;
+}
+
+.executionInfo table td.timeline {
+	padding: 0px;
+	height: 100%;
+	vertical-align: bottom;
+	margin: 0px;
+}
+
+.executionInfo table td.execId {
+	font-weight: bold;
+}
+
+.executionInfo table td {
+	padding-left: 3px;
+	height: 20px;
+}
+
+td .status {
+	-moz-border-radius: 2px;
+	border-radius: 2px;
+
+	padding: 2px 2px;
+	color: #FFF;
+	text-align: center;
+	margin-top: 2px;
+}
+
+td .status.SUCCEEDED {
+	background-color: #82B859;
+}
+
+td .status.FAILED {
+	background-color: #C82123;
+}
+
+td .status.READY {
+	background-color: #CCC;
+}
+
+td .status.RUNNING {
+	background-color: #3398CC;	
+}
+
+td .status.FAILED_FINISHING {
+	background-color: #F19153;	
+}
+
+td .status.DISABLED {
+	background-color: #AAA;	
+}
+
+td .status.SKIPPED {
+	background-color: #AAA;	
+}
+
+td .status.KILLED {
+	background-color: #CC0000;
+}
+
+td .status.UNKNOWN {
+	background-color: #CCC;
+}
+
+
+.flow-header {
+	height: 48px;
+}
+
+.outerProgress {
+	width: 280px;
+	margin: 4px;
+	background-color: #e2e4e3;
+	border: 1px solid #FFF;
+}
+
+tr:hover .outerProgress {
+	background-color: #F8F8F8;
+}
+
+.progressBox {
+	height: 24px;
+	background-color: #CCC;
+}
+
+.progressBox.SUCCEEDED {
+	background-color: #4e911e;
+	background: -moz-linear-gradient(top, #5bb41c 0, #598d1e 100%);
+    background: -o-linear-gradient(top, #5bb41c 0, #598d1e 100%);
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(0,#5bb41c), color-stop(100%,#598d1e));
+    background: linear-gradient(top, #5bb41c 0, #598d1e 100%);
+}
+
+.progressBox.FAILED {
+	background-color: #9e3600;
+	background: -moz-linear-gradient(top, #d43c00 0, #9e3600 100%);
+    background: -o-linear-gradient(top, #d43c00 0, #9e3600 100%);
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(0,#d43c00), color-stop(100%,#9e3600));
+    background: linear-gradient(top, #d43c00 0, #9e3600 100%);
+}
+
+.progressBox.RUNNING {
+	background-color: #009FC9;
+	background: -moz-linear-gradient(top, #009FC9 0, #007b9b 100%);
+    background: -o-linear-gradient(top, #009FC9 0, #007b9b 100%);
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(0,#009FC9), color-stop(100%,#007b9b));
+    background: linear-gradient(top, #009FC9 0, #007b9b 100%);
+}
+
+h3.subhead {
+	margin: 15px 20px 8px 20px;
+	font-size: 14pt;
+	font-weight: bold;
+}
+
+ul.subMenu {
+	margin-left: 15px;
+}
+
+ul.disableMenu {
+	margin-left: 15px;
+}
+
+.warn {
+	margin-left: 30px;
+	height: 40px;
+}
+
+.warning-icon {
+	float: left;
+	background-image: url("./images/redwarning.png");
+	width: 48px;
+	height: 43px;
+}
+
+.warning-message {
+	float: left;
+	margin-left: 10px;
+	margin-top: 10px;
+}
+
+span .nowrap {
+	white-space: nowrap;
+}
+
+.sched-form {
+	margin: 20px 20px;
+}
+
+#timeGraph {
+	width: 100%;
+	height: 300px;
+	background-color: #fff;
+	margin-bottom: 5px;
+}
+
+#dayByDayPanel {
+	
+}
+
+#dayGraph {
+	background-color: #fff;
+}
+
+#historyTimeLine {
+	position: absolute;
+	top: 160px;
+	bottom: 5px;
+	left: 50px;
+	right: 50px;
+	padding: 10px;
+	background: #E0E0E0;
+}
+
+.comment {
+	font-size: 11pt;
+	margin: 0px 20px;
+}
+
+.comment-small {
+	font-size: 11pt;
+	margin: 0px 20px;
+}
+
+.admin {
+	margin: 20px;
+}
+
+.admin-panel {
+	border-top: 2px groove #FFF;
+	margin: 40px 5px;
+	padding-top: 10px;
+	padding-bottom: 10px;
+}
+
+.admin-panel label {
+	font-size: 10pt;
+}
+
+.admin-panel input[type="radio"] {
+	margin-left: 50px;
+}
+
+
+.admin-panel h3 {
+	font-size: 12pt;
+	font-weight: bold;
+	margin: 3px 30px;
+}
+
+.admin-setup-points {
+	font-size: 10pt;
+	margin: 8px 25px;
+	list-style-type: disc;
+}
+
+.upload {
+	margin: 10px 20px;
+}
+
+.upload fieldset {
+	float: left;
+}
+
+.upload a {
+	float: left;
+}
+
+.upload .installed {
+	float: left;
+	font-size: 9pt;
+	margin-left: 20px;
+}
+
+#upload-jar-btn {
+	float: left;
+}
+
+#dbconnection {
+	margin-left: 40px;
+}
+
+#dbconnection label {
+	font-size: 10pt;
+	width: 100px;
+}
+
+#dbconnection table {
+	margin-top: 5px;
+}
+
+#dbconnection table tr td{
+	padding: 0;
+	border-top: none;
+	border-right: none;
+}
+
+#dbconnection table tr td.left{
+	width: 100px;
+}
+
+#dbconnection table tr td.param{
+	width: 310px;
+}
+
+#dbconnection table tr td.desc{
+	text-align:left;
+	font-style: italic;
+}
+
+#dbconnection table tr td input{
+	width: 300px;
+}
+
+#save-connection-button {
+	float: left;
+	margin-top: 5px;
+}
+
+#save-results {
+	float: left;
+	font-size: 10pt;
+	padding-top: 10px;
+	padding-left: 20px;
+	padding-bottom: 10px;
+}
+
+#save-results .fail{
+	background-color: #FF0000;
+	color: #FFFFFF;
+}
+
+.block {
+	display: block;
+}
+
+.bold {
+	font-weight: bold;
+}
+
+/*Azkaban Hover Menu */
+#flow-tabs .row .tb-name {
+	
+}
+
+.job-hover-menu {
+	float: right;
+}
+
+.job-hover-menu div {
+	margin-left: 2px;
+	float: left;
+}
+
+/*Azkaban Hover Menu */
+.jobfolder {
+	padding-top: 3px;
+	height: 22px;
+	float: left;
+}
+
+tr.row td.tb-name {
+	padding-top: 0px;
+	padding-bottom: 0px;
+}
+
+.expandedFlow td.tb-job-name {
+	padding-top: 0px;
+	padding-bottom: 0px;
+	height: 25px;
+}
+
+.expandedFlow td.tb-job-name:hover {
+	background-color: #E1E3E2;
+}
+
+.expandedFlow td.tb-job-name a{
+	padding-top: 3px;
+	padding-bottom: 0px;
+	float: left;
+}
+
+.contextMenu {
+	
+}
+
+/* old styles */
+.azkaban-charts .hitarea {
+	background-image: url("../../js/jqueryui/themes/custom-theme/images/ui-icons_cccccc_256x240.png");
+	background-position: 0 -16px;
+	height: 16px;
+	margin-left: 15px;
+	width: 16px;
+	cursor: pointer;
+}
+
+.azkaban-charts .expandable-hitarea { background-position: -32px -16px; }
+.azkaban-charts .expandable-hitarea.collapse { background-position: 0 -16px; }
+/* clean up */
diff --git a/src/web/js/azkaban.context.menu.js b/src/web/js/azkaban.context.menu.js
new file mode 100644
index 0000000..cdb2c9c
--- /dev/null
+++ b/src/web/js/azkaban.context.menu.js
@@ -0,0 +1,19 @@
+$.namespace('azkaban');
+
+var flowExecuteDialogView;
+azkaban.FlowExecuteDialogView= Backbone.View.extend({
+  events : {
+  },
+  initialize : function(settings) {
+  },
+  render: function() {
+  },
+  showContextMenu: function(menuData) {
+  	//$('#execute-flow-panel').show();
+  	$(this.el).show();
+  },
+  hideContextMenu: function(menuData) {
+  	//$('#execute-flow-panel').hide();
+  	$(this.el).hide();
+  }
+});
\ No newline at end of file
diff --git a/src/web/js/azkaban.flow.execute.view.js b/src/web/js/azkaban.flow.execute.view.js
new file mode 100644
index 0000000..ff2931d
--- /dev/null
+++ b/src/web/js/azkaban.flow.execute.view.js
@@ -0,0 +1,347 @@
+$.namespace('azkaban');
+
+function recurseAllAncestors(nodes, disabledMap, id, disable) {
+	var node = nodes[id];
+	
+	if (node.inNodes) {
+		for (var key in node.inNodes) {
+			disabledMap[key] = disable;
+			recurseAllAncestors(nodes, disabledMap, key, disable);
+		}
+	}
+}
+
+function recurseAllDescendents(nodes, disabledMap, id, disable) {
+	var node = nodes[id];
+	
+	if (node.outNodes) {
+		for (var key in node.outNodes) {
+			disabledMap[key] = disable;
+			recurseAllDescendents(nodes, disabledMap, key, disable);
+		}
+	}
+}
+
+var flowExecuteDialogView;
+azkaban.FlowExecuteDialogView= Backbone.View.extend({
+  events : {
+  	"click .simplemodal-close": "hideExecutionOptionPanel",
+  	"click .modal-close" : "hideExecutionOptionPanel"
+  },
+  initialize : function(settings) {
+  },
+  render: function() {
+  },
+  show: function(data) {
+  	var projectId = data.project;
+  	var flowId = data.flow;
+  	var jobId = data.job;
+  
+  	var loadedId = executableGraphModel.get("flowId");
+  	if (loadedId != flowId) {
+  		this.loadGraph(projectId, flowId);
+  	}
+  
+	if (jobId) {
+		this.showExecuteJob(projectId, flowId, jobId, data.withDep);
+	}
+	else {
+		this.showExecuteFlow(projectId, flowId);
+	}
+  },
+  showExecuteFlow: function(projectId, flowId) {
+	$("#execute-flow-panel-title").text("Execute Flow " + flowId);
+	this.showExecutionOptionPanel();
+  },
+  showExecuteJob: function(projectId, flowId, jobId, withDep) {
+	$("#execute-message").text("Execute the complete flow '" + flowId + "'.");
+  },
+  showExecutionOptionPanel: function() {
+  	$('#modalBackground').show();
+  	$('#execute-flow-panel').show();
+  },
+  hideExecutionOptionPanel: function() {
+  	$('#modalBackground').hide();
+  	$('#execute-flow-panel').hide();
+  },
+  loadGraph: function(projectId, flowId) {
+  	console.log("Loading flow " + flowId);
+  	var managerUrl = contextURL + "/manager";
+  	var fetchData = {
+  		"ajax" : "fetchflowgraph",
+  		"project" : projectId,
+  		"flow" : flowId
+  	};
+
+  	$.get(
+		managerUrl,
+		fetchData,
+		function(data) {
+			if (data.error) {
+				alert(data.error);
+			}
+			else {
+				var disabled = data.disabled ? data.disabled : {};
+			
+				executableGraphModel.set({flowId: data.flowId, data:data, disabled: disabled});
+				executableGraphModel.trigger("change:graph");
+			}
+		},
+		"json"
+	);
+  }
+});
+
+var sideMenuDialogView;
+azkaban.SideMenuDialogView= Backbone.View.extend({
+	events : {
+		"click .menuHeader" : "expandItem"
+  	},
+  	initialize : function(settings) {
+  		var children = $(this.el).children();
+  		for (var i = 0; i < children.length; ++i ) {
+  			var child = children[i];
+  			if ((i % 2) == 0) {
+  				$(child).addClass("menuHeader");
+  			}
+  			else {
+  				$(child).addClass("menuContent");
+  				$(child).hide();
+  				
+  			
+  			}
+  		}
+  	},
+  	expandItem : function(self) {
+  		
+  	}
+});
+
+var contextMenuView;
+azkaban.ContextMenuView = Backbone.View.extend({
+	events :  {
+	},
+	initialize : function(settings) {
+		var div = this.el;
+		$('body').click(function(e) {
+			$(".contextMenu").remove();
+		});
+		$('body').bind("contextmenu", function(e) {$(".contextMenu").remove()});
+		this.svgGraph = settings.graph;
+	},
+	show : function(evt, menu) {
+		console.log("Show context menu");
+		$(".contextMenu").remove();
+		var x = evt.pageX;
+		var y = evt.pageY;
+
+		var contextMenu = this.setupMenu(menu);
+		$(contextMenu).css({top: y, left: x});
+		$(this.el).after(contextMenu);
+	},
+	hide : function(evt) {
+		console.log("Hide context menu");
+		$(".contextMenu").remove();
+	},
+	handleClick: function(evt) {
+		console.log("handling click");
+	},
+	setupMenu: function(menu) {
+		var contextMenu = document.createElement("div");
+		$(contextMenu).addClass("contextMenu");
+		var ul = document.createElement("ul");
+		$(contextMenu).append(ul);
+
+		for (var i = 0; i < menu.length; ++i) {
+			var menuItem = document.createElement("li");
+			if (menu[i].break) {
+				$(menuItem).addClass("break");
+			}
+			else {
+				var title = menu[i].title;
+				var callback = menu[i].callback;
+				$(menuItem).addClass("menuitem");
+				$(menuItem).text(title);
+				menuItem.callback = callback;
+				$(menuItem).click(function() { 
+					$(contextMenu).hide(); 
+					this.callback.call();});
+					
+				if (menu[i].submenu) {
+					var expandSymbol = document.createElement("div");
+					$(expandSymbol).addClass("expandSymbol");
+					$(menuItem).append(expandSymbol);
+					
+					var subMenu = this.setupMenu(menu[i].submenu);
+					$(subMenu).addClass("subMenu");
+					subMenu.parent = contextMenu;
+					menuItem.subMenu = subMenu;
+					$(subMenu).hide();
+					$(this.el).after(subMenu);
+					
+					$(menuItem).mouseenter(function() {
+						$(".subMenu").hide();
+						var menuItem = this;
+						menuItem.selected = true;
+						setTimeout(function() {
+							if (menuItem.selected) {
+								var offset = $(menuItem).offset();
+								var left = offset.left;
+								var top = offset.top;
+								var width = $(menuItem).width();
+								var subMenu = menuItem.subMenu;
+								
+								var newLeft = left + width - 5;
+								$(subMenu).css({left: newLeft, top: top});
+								$(subMenu).show();
+							}
+						}, 500);
+					});
+					$(menuItem).mouseleave(function() {this.selected = false;});
+				}
+			}
+
+			$(ul).append(menuItem);
+		}
+
+		return contextMenu;
+	}
+});
+
+var handleJobMenuClick = function(action, el, pos) {
+	var jobid = el[0].jobid;
+	
+	var requestURL = contextURL + "/manager?project=" + projectId + "&flow=" + flowName + "&job=" + jobid;
+	if (action == "open") {
+		window.location.href = requestURL;
+	}
+	else if(action == "openwindow") {
+		window.open(requestURL);
+	}
+}
+
+var executableGraphModel;
+azkaban.GraphModel = Backbone.Model.extend({});
+
+var enableAll = function() {
+	disabled = {};
+	executableGraphModel.set({disabled: disabled});
+	executableGraphModel.trigger("change:disabled");
+}
+
+var disableAll = function() {
+	var disabled = executableGraphModel.get("disabled");
+
+	var nodes = executableGraphModel.get("nodes");
+	for (var key in nodes) {
+		disabled[key] = true;
+	}
+
+	executableGraphModel.set({disabled: disabled});
+	executableGraphModel.trigger("change:disabled");
+}
+
+var touchNode = function(jobid, disable) {
+	var disabled = executableGraphModel.get("disabled");
+
+	disabled[jobid] = disable;
+	executableGraphModel.set({disabled: disabled});
+	executableGraphModel.trigger("change:disabled");
+}
+
+var touchParents = function(jobid, disable) {
+	var disabled = executableGraphModel.get("disabled");
+	var nodes = executableGraphModel.get("nodes");
+	var inNodes = nodes[jobid].inNodes;
+
+	if (inNodes) {
+		for (var key in inNodes) {
+		  disabled[key] = disable;
+		}
+	}
+	
+	executableGraphModel.set({disabled: disabled});
+	executableGraphModel.trigger("change:disabled");
+}
+
+var touchChildren = function(jobid, disable) {
+	var disabledMap = executableGraphModel.get("disabled");
+	var nodes = executableGraphModel.get("nodes");
+	var outNodes = nodes[jobid].outNodes;
+
+	if (outNodes) {
+		for (var key in outNodes) {
+		  disabledMap[key] = disable;
+		}
+	}
+	
+	executableGraphModel.set({disabled: disabledMap});
+	executableGraphModel.trigger("change:disabled");
+}
+
+var touchAncestors = function(jobid, disable) {
+	var disabled = executableGraphModel.get("disabled");
+	var nodes = executableGraphModel.get("nodes");
+	
+	recurseAllAncestors(nodes, disabled, jobid, disable);
+	
+	executableGraphModel.set({disabled: disabled});
+	executableGraphModel.trigger("change:disabled");
+}
+
+var touchDescendents = function(jobid, disable) {
+	var disabled = executableGraphModel.get("disabled");
+	var nodes = executableGraphModel.get("nodes");
+	
+	recurseAllDescendents(nodes, disabled, jobid, disable);
+	
+	executableGraphModel.set({disabled: disabled});
+	executableGraphModel.trigger("change:disabled");
+}
+
+var nodeClickCallback = function(event) {
+	console.log("Node clicked callback");
+	var jobId = event.currentTarget.jobid;
+	var flowId = executableGraphModel.get("flowId");
+	var requestURL = contextURL + "/manager?project=" + projectId + "&flow=" + flowId + "&job=" + jobId;
+
+	var menu = [	{title: "Open in New Window...", callback: function() {window.location.href=requestURL;}},
+			{break: 1},
+			{title: "Enable", callback: function() {touchNode(jobId, false);}, submenu: [
+									{title: "Parents", callback: function(){touchParents(jobId, false);}},
+									{title: "Ancestors", callback: function(){touchAncestors(jobId, false);}},
+									{title: "Children", callback: function(){touchChildren(jobId, false);}},
+									{title: "Descendents", callback: function(){touchDescendents(jobId, false);}},
+									{title: "Enable All", callback: function(){enableAll();}}
+								]
+			},
+			{title: "Disable", callback: function() {touchNode(jobId, true)}, submenu: [
+									{title: "Parents", callback: function(){touchParents(jobId, true);}},
+									{title: "Ancestors", callback: function(){touchAncestors(jobId, true);}},
+									{title: "Children", callback: function(){touchChildren(jobId, true);}},
+									{title: "Descendents", callback: function(){touchDescendents(jobId, true);}},
+									{title: "Disable All", callback: function(){disableAll();}}
+								]
+			}
+	];
+
+	contextMenuView.show(event, menu);
+}
+
+var edgeClickCallback = function(event) {
+	console.log("Edge clicked callback");
+}
+
+var graphClickCallback = function(event) {
+	console.log("Graph clicked callback");
+}
+
+$(function() {
+	flowExecuteDialogView = new azkaban.FlowExecuteDialogView({el:$('#execute-flow-panel')});
+	executableGraphModel = new azkaban.GraphModel();
+	svgGraphView = new azkaban.SvgGraphView({el:$('#svgDivCustom'), model: executableGraphModel, topGId:"topG", graphMargin: 10, rightClick: { "node": nodeClickCallback, "edge": edgeClickCallback, "graph": graphClickCallback }});
+	
+	sideMenuDialogView = new azkaban.SideMenuDialogView({el:$('#graphOptions')});
+	var svgGraph = document.getElementById('svgGraph');
+	contextMenuView = new azkaban.ContextMenuView({el:$('#contextMenu'), graph: svgGraph});
+});
diff --git a/src/web/js/azkaban.flow.graph.view.js b/src/web/js/azkaban.flow.graph.view.js
index a26ca3a..7d7b9f9 100644
--- a/src/web/js/azkaban.flow.graph.view.js
+++ b/src/web/js/azkaban.flow.graph.view.js
@@ -21,6 +21,14 @@ azkaban.SvgGraphView = Backbone.View.extend({
 		this.contextMenu = settings.rightClick;
 		
 		var gNode = document.createElementNS(this.svgns, 'g');
+		if (settings.topGId) {
+			gNode.setAttribute("id", settings.topGId);
+		}
+		if (settings.clickCallback) {
+			this.clickCallback = settings.clickCallback;
+			$(this.el).click(this.clickCallback);
+		}
+
 		svg.appendChild(gNode);
 		this.mainG = gNode;
 
@@ -159,6 +167,9 @@ azkaban.SvgGraphView = Backbone.View.extend({
 		if (self.currentTarget.jobid) {
 			this.model.set({"selected": self.currentTarget.jobid});
 		}
+		if (this.clickCallback) {
+			this.clickCallback(self);
+		}
 	},
 	drawEdge: function(self, edge) {
 		var svg = self.svgGraph;
diff --git a/src/web/js/azkaban.project.view.js b/src/web/js/azkaban.project.view.js
index 5dd066b..d880221 100644
--- a/src/web/js/azkaban.project.view.js
+++ b/src/web/js/azkaban.project.view.js
@@ -206,7 +206,6 @@ azkaban.FlowTableView= Backbone.View.extend({
     var projectName = evt.currentTarget.projectName;
   	var flowId = evt.currentTarget.flowId;
   	var jobName = evt.currentTarget.jobName;
-  	console.log("job run options " + projectName + ":" + flowId + ":" + jobName);
   	
   	var hover = evt.type == "mouseover";
   	
@@ -319,7 +318,6 @@ azkaban.FlowTableView= Backbone.View.extend({
   executeFlow: function(evt) {
     console.log("Execute Flow");
     var flowId = evt.currentTarget.flowId;
-    $("#execute-message").text("Execute the complete flow '" + flowId + "'.");
     
     var executingData = {
   		project: projectId,
@@ -330,31 +328,7 @@ azkaban.FlowTableView= Backbone.View.extend({
     this.executeFlowDialog(executingData);
   },
   executeFlowDialog: function(executingData) {
-  	var flowId = executingData.flow;
-  	var executionIds = flowExecutingStatus(projectId, flowId);
-  	
-    if (executionIds && executionIds.length > 0) {
-    	$("#executeErrorMsg").text("Flow '" + flowId + "' is already running. Click on Execute to proceed anyways.");
-    }
-    else {
-    	$("#executeErrorMsg").hide();
-    }
-
- 	$('#flow-execute').modal({
-      closeHTML: "<a href='#' title='Close' class='modal-close'>x</a>",
-      position: ["20%",],
-      containerId: 'confirm-container',
-      containerCss: {
-        'height': '220px',
-        'width': '565px'
-      },
-      onShow: function (dialog) {
-        var modal = this;
-        $('#execute-btn').click(function() {
-        	executeFlow(executingData);
-        });
-      }
-    });
+  	flowExecuteDialogView.show(executingData);
   },
   render: function() {
   }
diff --git a/src/web/js/azkaban.svg.graph.view.js b/src/web/js/azkaban.svg.graph.view.js
new file mode 100644
index 0000000..fbd877b
--- /dev/null
+++ b/src/web/js/azkaban.svg.graph.view.js
@@ -0,0 +1,338 @@
+function hasClass(el, name) 
+{
+	var classes = el.getAttribute("class");
+	if (classes == null) {
+		return false;
+	}
+   return new RegExp('(\\s|^)'+name+'(\\s|$)').test(classes);
+}
+
+function addClass(el, name)
+{
+   if (!hasClass(el, name)) { 
+   		var classes = el.getAttribute("class");
+   		classes += classes ? ' ' + name : '' +name;
+   		el.setAttribute("class", classes);
+   }
+}
+
+function removeClass(el, name)
+{
+   if (hasClass(el, name)) {
+      var classes = el.getAttribute("class");
+      el.setAttribute("class", classes.replace(new RegExp('(\\s|^)'+name+'(\\s|$)'),' ').replace(/^\s+|\s+$/g, ''));
+   }
+}
+
+
+var svgGraphView;
+azkaban.SvgGraphView = Backbone.View.extend({
+	events: {
+		"click g" : "clickGraph",
+		"contextmenu svg" : "rightClick",
+		"contextmenu g" : "rightClick",
+		"contextmenu polyline": "rightClick"
+	},
+	initialize: function(settings) {
+		this.model.bind('change:selected', this.changeSelected, this);
+		this.model.bind('change:graph', this.render, this);
+		this.model.bind('resetPanZoom', this.resetPanZoom, this);
+		this.model.bind('change:update', this.handleStatusUpdate, this);
+		this.model.bind('change:disabled', this.handleDisabledChange, this);
+		this.model.bind('change:updateAll', this.handleUpdateAllStatus, this);
+		
+		this.graphMargin = settings.graphMargin ? settings.graphMargin : 200;
+		this.svgns = "http://www.w3.org/2000/svg";
+		this.xlinksn = "http://www.w3.org/1999/xlink";
+		
+		var graphDiv = this.el[0];
+		var svg = $(this.el).find('svg')[0];
+		this.svgGraph = svg;
+		
+		var gNode = document.createElementNS(this.svgns, 'g');
+		svg.appendChild(gNode);
+		this.mainG = gNode;
+		if (settings.rightClick) {
+			this.rightClick = settings.rightClick;
+		}
+		$(svg).svgNavigate();
+	},
+	initializeDefs: function(self) {
+		var def = document.createElementNS(svgns, 'defs');
+		def.setAttributeNS(null, "id", "buttonDefs");
+
+		// ArrowHead
+		var arrowHeadMarker = document.createElementNS(svgns, 'marker');
+		arrowHeadMarker.setAttribute("id", "triangle");
+		arrowHeadMarker.setAttribute("viewBox", "0 0 10 10");
+		arrowHeadMarker.setAttribute("refX", "5");
+		arrowHeadMarker.setAttribute("refY", "5");
+		arrowHeadMarker.setAttribute("markerUnits", "strokeWidth");
+		arrowHeadMarker.setAttribute("markerWidth", "4");
+		arrowHeadMarker.setAttribute("markerHeight", "3");
+		arrowHeadMarker.setAttribute("orient", "auto");
+		var path = document.createElementNS(svgns, 'polyline');
+		arrowHeadMarker.appendChild(path);
+		path.setAttribute("points", "0,0 10,5 0,10 1,5");
+
+		def.appendChild(arrowHeadMarker);
+		
+		this.svgGraph.appendChild(def);
+	},
+	render: function(self) {
+		console.log("graph render");
+
+		// Clean everything
+		while (this.mainG.lastChild) {
+			this.mainG.removeChild(this.mainG.lastChild);
+		}
+
+		var data = this.model.get("data");
+		var nodes = data.nodes;
+		var edges = data.edges;
+		if (nodes.length == 0) {
+			console.log("No results");
+			return;
+		};
+	
+		nodes.sort();
+		edges.sort();
+		// layout
+		layoutGraph(nodes, edges);
+		
+		var bounds = {};
+		this.nodes = {};
+		for (var i = 0; i < nodes.length; ++i) {
+			this.nodes[nodes[i].id] = nodes[i];
+		}
+		
+		for (var i = 0; i < edges.length; ++i) {
+			var inNodes = this.nodes[edges[i].target].inNodes;
+			if (!inNodes) {
+				inNodes = {};
+				this.nodes[edges[i].target].inNodes = inNodes;
+			}
+			inNodes[edges[i].from] = this.nodes[edges[i].from];
+			
+			var outNodes = this.nodes[edges[i].from].outNodes;
+			if (!outNodes) {
+				outNodes = {};
+				this.nodes[edges[i].from].outNodes = outNodes;
+			}
+			outNodes[edges[i].target] = this.nodes[edges[i].target];
+
+			this.drawEdge(this, edges[i]);
+		}
+		
+		this.gNodes = {};
+		for (var i = 0; i < nodes.length; ++i) {
+			this.drawNode(this, nodes[i], bounds);
+		}
+		
+		this.model.set({"nodes": this.nodes, "edges": edges});
+		
+		var margin = this.graphMargin;
+		bounds.minX = bounds.minX ? bounds.minX - margin : -margin;
+		bounds.minY = bounds.minY ? bounds.minY - margin : -margin;
+		bounds.maxX = bounds.maxX ? bounds.maxX + margin : margin;
+		bounds.maxY = bounds.maxY ? bounds.maxY + margin : margin;
+		
+		this.assignInitialStatus(self);
+		this.handleDisabledChange(self);
+		this.graphBounds = bounds;
+		this.resetPanZoom(0);
+	},
+	handleDisabledChange: function(evt) {
+		var disabledMap = this.model.get("disabled");
+
+		for(var id in this.nodes) {
+			 var g = this.gNodes[id];
+			if (disabledMap[id]) {
+				this.nodes[id].disabled = true;
+				addClass(g, "disabled");
+			}
+		    else {
+		    	this.nodes[id].disabled = false;
+		    	removeClass(g, "disabled");
+			}
+		}
+	},
+	assignInitialStatus: function(evt) {
+		var data = this.model.get("data");
+		for (var i = 0; i < data.nodes.length; ++i) {
+			var updateNode = data.nodes[i];
+			var g = this.gNodes[updateNode.id];
+			addClass(g, updateNode.status);
+		}
+	},
+	changeSelected: function(self) {
+		console.log("change selected");
+		var selected = this.model.get("selected");
+		var previous = this.model.previous("selected");
+		
+		if (previous) {
+			// Unset previous
+			var g = this.gNodes[previous];
+			removeClass(g, "selected");
+		}
+		
+		if (selected) {
+			var g = this.gNodes[selected];
+			var node = this.nodes[selected];
+			
+			addClass(g, "selected");
+			
+			var offset = 200;
+			var widthHeight = offset*2;
+			var x = node.x - offset;
+			var y = node.y - offset;
+			
+			$(this.svgGraph).svgNavigate("transformToBox", {x: x, y: y, width: widthHeight, height: widthHeight});
+		}
+	},
+	handleStatusUpdate: function(evt) {
+		var updateData = this.model.get("update");
+		if (updateData.nodes) {
+			for (var i = 0; i < updateData.nodes.length; ++i) {
+				var updateNode = updateData.nodes[i];
+				
+				var g = this.gNodes[updateNode.id];
+				this.handleRemoveAllStatus(g);
+				
+				addClass(g, updateNode.status);
+			}
+		}
+	},
+	handleRemoveAllStatus: function(gNode) {
+		for (var j = 0; j < statusList.length; ++j) {
+			var status = statusList[j];
+			removeClass(gNode, status);
+		}
+	},
+	clickGraph: function(self) {
+		console.log("click");
+		if (self.currentTarget.jobid) {
+			this.model.set({"selected": self.currentTarget.jobid});
+		}
+	},
+	rightClick: function(self) {
+		if (this.rightClick) {
+			var callbacks = this.rightClick;
+			var currentTarget = self.currentTarget;
+			if (callbacks.node && currentTarget.jobid) {
+				callbacks.node(self);
+			}
+			else if (callbacks.edge && (currentTarget.nodeName == "polyline" || currentTarget.nodeName == "line")) {
+				callbacks.edge(self);
+			}
+			else if (callbacks.graph) {
+				callbacks.graph(self);
+			}
+			return false;
+		}
+	
+		return true;
+	},	
+	drawEdge: function(self, edge) {
+		var svg = self.svgGraph;
+		var svgns = self.svgns;
+		
+		var startNode = this.nodes[edge.from];
+		var endNode = this.nodes[edge.target];
+		
+		if (edge.guides) {
+			var pointString = "" + startNode.x + "," + startNode.y + " ";
+
+			for (var i = 0; i < edge.guides.length; ++i ) {
+				edgeGuidePoint = edge.guides[i];
+				pointString += edgeGuidePoint.x + "," + edgeGuidePoint.y + " ";
+			}
+			
+			pointString += endNode.x + "," + endNode.y;
+			var polyLine = document.createElementNS(svgns, "polyline");
+			polyLine.setAttributeNS(null, "class", "edge");
+			polyLine.setAttributeNS(null, "points", pointString);
+			polyLine.setAttributeNS(null, "style", "fill:none;");
+			self.mainG.appendChild(polyLine);
+		}
+		else { 
+			var line = document.createElementNS(svgns, 'line');
+			line.setAttributeNS(null, "class", "edge");
+			line.setAttributeNS(null, "x1", startNode.x);
+			line.setAttributeNS(null, "y1", startNode.y);
+			line.setAttributeNS(null, "x2", endNode.x);
+			line.setAttributeNS(null, "y2", endNode.y);
+			
+			self.mainG.appendChild(line);
+		}
+	},
+	drawNode: function(self, node, bounds) {
+		var svg = self.svgGraph;
+		var svgns = self.svgns;
+
+		var xOffset = 10;
+		var yOffset = 10;
+		
+		var nodeG = document.createElementNS(svgns, "g");
+		nodeG.setAttributeNS(null, "class", "jobnode");
+		nodeG.setAttributeNS(null, "font-family", "helvetica");
+		nodeG.setAttributeNS(null, "transform", "translate(" + node.x + "," + node.y + ")");
+		this.gNodes[node.id] = nodeG;
+		
+		var innerG = document.createElementNS(svgns, "g");
+		innerG.setAttributeNS(null, "transform", "translate(-10,-10)");
+		
+		var circle = document.createElementNS(svgns, 'circle');
+		circle.setAttributeNS(null, "cy", 10);
+		circle.setAttributeNS(null, "cx", 10);
+		circle.setAttributeNS(null, "r", 12);
+		circle.setAttributeNS(null, "style", "width:inherit;stroke-opacity:1");
+		
+		
+		var text = document.createElementNS(svgns, 'text');
+		var textLabel = document.createTextNode(node.label);
+		text.appendChild(textLabel);
+		text.setAttributeNS(null, "x", 4);
+		text.setAttributeNS(null, "y", 15);
+		text.setAttributeNS(null, "height", 10); 
+				
+		this.addBounds(bounds, {minX:node.x - xOffset, minY: node.y - yOffset, maxX: node.x + xOffset, maxY: node.y + yOffset});
+		
+		var backRect = document.createElementNS(svgns, 'rect');
+		backRect.setAttributeNS(null, "x", 0);
+		backRect.setAttributeNS(null, "y", 2);
+		backRect.setAttributeNS(null, "class", "backboard");
+		backRect.setAttributeNS(null, "width", 10);
+		backRect.setAttributeNS(null, "height", 15);
+		
+		innerG.appendChild(circle);
+		innerG.appendChild(backRect);
+		innerG.appendChild(text);
+		innerG.jobid = node.id;
+
+		nodeG.appendChild(innerG);
+		self.mainG.appendChild(nodeG);
+
+		// Need to get text width after attaching to SVG.
+		var computeText = text.getComputedTextLength();
+		var halfWidth = computeText/2;
+		text.setAttributeNS(null, "x", -halfWidth + 10);
+		backRect.setAttributeNS(null, "x", -halfWidth);
+		backRect.setAttributeNS(null, "width", computeText + 20);
+
+		nodeG.setAttributeNS(null, "class", "node");
+		nodeG.jobid=node.id;
+	},
+	addBounds: function(toBounds, addBounds) {
+		toBounds.minX = toBounds.minX ? Math.min(toBounds.minX, addBounds.minX) : addBounds.minX;
+		toBounds.minY = toBounds.minY ? Math.min(toBounds.minY, addBounds.minY) : addBounds.minY;
+		toBounds.maxX = toBounds.maxX ? Math.max(toBounds.maxX, addBounds.maxX) : addBounds.maxX;
+		toBounds.maxY = toBounds.maxY ? Math.max(toBounds.maxY, addBounds.maxY) : addBounds.maxY;
+	},
+	resetPanZoom : function(duration) {
+		var bounds = this.graphBounds;
+		var param = {x: bounds.minX, y: bounds.minY, width: (bounds.maxX - bounds.minX), height: (bounds.maxY - bounds.minY), duration: duration };
+
+		$(this.svgGraph).svgNavigate("transformToBox", param);
+	}
+});
\ No newline at end of file
diff --git a/src/web/js/svgNavigate.js b/src/web/js/svgNavigate.js
index 076f700..68121f9 100644
--- a/src/web/js/svgNavigate.js
+++ b/src/web/js/svgNavigate.js
@@ -1,6 +1,9 @@
 (function($) {	
 
 	var mouseUp = function(evt) {
+		if (evt.button > 1) {
+			return;
+		}
 		var target = evt.target;
 		target.mx = evt.clientX;
 		target.my = evt.clientY;
@@ -8,6 +11,9 @@
 	}
 	
 	var mouseDown = function(evt) {
+		if (evt.button > 1) {
+                        return;
+                }
 		//alert("mouseDown");
 		var target = evt.target;
 		target.mx = evt.clientX;
@@ -358,4 +364,4 @@
 			$.error('Method ' + method + ' does not exist on svgNavigate');
 		}
 	};
-})(jQuery);
\ No newline at end of file
+})(jQuery);