flink-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From trohrm...@apache.org
Subject [20/47] flink git commit: [FLINK-2793] [runtime-web] Redirect to leader in non-standalone mode
Date Tue, 20 Oct 2015 07:59:11 GMT
http://git-wip-us.apache.org/repos/asf/flink/blob/77fc0cc4/flink-runtime-web/src/main/resources/web/js/index.js
----------------------------------------------------------------------
diff --git a/flink-runtime-web/src/main/resources/web/js/index.js b/flink-runtime-web/src/main/resources/web/js/index.js
new file mode 100644
index 0000000..d370765
--- /dev/null
+++ b/flink-runtime-web/src/main/resources/web/js/index.js
@@ -0,0 +1,1420 @@
+angular.module('flinkApp', ['ui.router', 'angularMoment']).run(["$rootScope", function($rootScope) {
+  $rootScope.sidebarVisible = false;
+  return $rootScope.showSidebar = function() {
+    $rootScope.sidebarVisible = !$rootScope.sidebarVisible;
+    return $rootScope.sidebarClass = 'force-show';
+  };
+}]).value('flinkConfig', {
+  "refresh-interval": 10000
+}).run(["JobsService", "MainService", "flinkConfig", "$interval", function(JobsService, MainService, flinkConfig, $interval) {
+  MainService.loadConfig().then(function(config) {
+    angular.extend(flinkConfig, config);
+    JobsService.listJobs();
+    return $interval(function() {
+      return JobsService.listJobs();
+    }, flinkConfig["refresh-interval"]);
+  });
+  Highcharts.setOptions({
+    global: {
+      useUTC: false
+    }
+  });
+  Highcharts.createElement('link', {
+    href: '//fonts.googleapis.com/css?family=Dosis:400,600',
+    rel: 'stylesheet',
+    type: 'text/css'
+  }, null, document.getElementsByTagName('head')[0]);
+  Highcharts.theme = {
+    colors: ["#7cb5ec", "#f7a35c", "#90ee7e", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee", "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"],
+    chart: {
+      backgroundColor: null,
+      style: {
+        fontFamily: "Dosis, sans-serif"
+      }
+    },
+    title: {
+      style: {
+        fontSize: '16px',
+        fontWeight: 'bold',
+        textTransform: 'uppercase'
+      }
+    },
+    tooltip: {
+      borderWidth: 0,
+      backgroundColor: 'rgba(219,219,216,0.8)',
+      shadow: false
+    },
+    legend: {
+      itemStyle: {
+        fontWeight: 'bold',
+        fontSize: '13px'
+      }
+    },
+    xAxis: {
+      gridLineWidth: 1,
+      labels: {
+        style: {
+          fontSize: '12px'
+        }
+      }
+    },
+    yAxis: {
+      minorTickInterval: 'auto',
+      title: {
+        style: {
+          textTransform: 'uppercase'
+        }
+      },
+      labels: {
+        style: {
+          fontSize: '12px'
+        }
+      }
+    },
+    plotOptions: {
+      candlestick: {
+        lineColor: '#404048'
+      }
+    },
+    background2: '#F0F0EA'
+  };
+  return Highcharts.setOptions(Highcharts.theme);
+}]).config(["$uiViewScrollProvider", function($uiViewScrollProvider) {
+  return $uiViewScrollProvider.useAnchorScroll();
+}]).config(["$stateProvider", "$urlRouterProvider", function($stateProvider, $urlRouterProvider) {
+  $stateProvider.state("overview", {
+    url: "/overview",
+    views: {
+      main: {
+        templateUrl: "partials/overview.html",
+        controller: 'OverviewController'
+      }
+    }
+  }).state("running-jobs", {
+    url: "/running-jobs",
+    views: {
+      main: {
+        templateUrl: "partials/jobs/running-jobs.html",
+        controller: 'RunningJobsController'
+      }
+    }
+  }).state("completed-jobs", {
+    url: "/completed-jobs",
+    views: {
+      main: {
+        templateUrl: "partials/jobs/completed-jobs.html",
+        controller: 'CompletedJobsController'
+      }
+    }
+  }).state("single-job", {
+    url: "/jobs/{jobid}",
+    abstract: true,
+    views: {
+      main: {
+        templateUrl: "partials/jobs/job.html",
+        controller: 'SingleJobController'
+      }
+    }
+  }).state("single-job.plan", {
+    url: "",
+    abstract: true,
+    views: {
+      details: {
+        templateUrl: "partials/jobs/job.plan.html",
+        controller: 'JobPlanController'
+      }
+    }
+  }).state("single-job.plan.overview", {
+    url: "",
+    views: {
+      'node-details': {
+        templateUrl: "partials/jobs/job.plan.node-list.overview.html",
+        controller: 'JobPlanOverviewController'
+      }
+    }
+  }).state("single-job.plan.accumulators", {
+    url: "/accumulators",
+    views: {
+      'node-details': {
+        templateUrl: "partials/jobs/job.plan.node-list.accumulators.html",
+        controller: 'JobPlanAccumulatorsController'
+      }
+    }
+  }).state("single-job.timeline", {
+    url: "/timeline",
+    views: {
+      details: {
+        templateUrl: "partials/jobs/job.timeline.html"
+      }
+    }
+  }).state("single-job.timeline.vertex", {
+    url: "/{vertexId}",
+    views: {
+      vertex: {
+        templateUrl: "partials/jobs/job.timeline.vertex.html",
+        controller: 'JobTimelineVertexController'
+      }
+    }
+  }).state("single-job.statistics", {
+    url: "/statistics",
+    views: {
+      details: {
+        templateUrl: "partials/jobs/job.statistics.html"
+      }
+    }
+  }).state("single-job.exceptions", {
+    url: "/exceptions",
+    views: {
+      details: {
+        templateUrl: "partials/jobs/job.exceptions.html",
+        controller: 'JobExceptionsController'
+      }
+    }
+  }).state("single-job.properties", {
+    url: "/properties",
+    views: {
+      details: {
+        templateUrl: "partials/jobs/job.properties.html",
+        controller: 'JobPropertiesController'
+      }
+    }
+  }).state("single-job.config", {
+    url: "/config",
+    views: {
+      details: {
+        templateUrl: "partials/jobs/job.config.html"
+      }
+    }
+  }).state("all-manager", {
+    url: "/taskmanagers",
+    views: {
+      main: {
+        templateUrl: "partials/taskmanager/index.html",
+        controller: 'AllTaskManagersController'
+      }
+    }
+  }).state("single-manager", {
+    url: "/taskmanager/{taskmanagerid}",
+    views: {
+      main: {
+        templateUrl: "partials/taskmanager/taskmanager.html",
+        controller: 'SingleTaskManagerController'
+      }
+    }
+  }).state("single-manager.metrics", {
+    url: "/metrics",
+    views: {
+      details: {
+        templateUrl: "partials/taskmanager/taskmanager.metrics.html"
+      }
+    }
+  }).state("single-manager.log", {
+    url: "/logfile",
+    views: {
+      details: {
+        templateUrl: "partials/taskmanager/taskmanager.logfile.html"
+      }
+    }
+  }).state("single-manager.stdout", {
+    url: "/stdout",
+    views: {
+      details: {
+        templateUrl: "partials/taskmanager/taskmanager.stdout.html"
+      }
+    }
+  }).state("jobmanager", {
+    url: "/jobmanager",
+    views: {
+      main: {
+        templateUrl: "partials/jobmanager/index.html"
+      }
+    }
+  }).state("jobmanager.config", {
+    url: "/config",
+    views: {
+      details: {
+        templateUrl: "partials/jobmanager/config.html",
+        controller: 'JobManagerConfigController'
+      }
+    }
+  }).state("jobmanager.stdout", {
+    url: "/stdout",
+    views: {
+      details: {
+        templateUrl: "partials/jobmanager/stdout.html",
+        controller: 'JobManagerStdoutController'
+      }
+    }
+  }).state("jobmanager.log", {
+    url: "/log",
+    views: {
+      details: {
+        templateUrl: "partials/jobmanager/log.html",
+        controller: 'JobManagerLogsController'
+      }
+    }
+  });
+  return $urlRouterProvider.otherwise("/overview");
+}]);
+
+angular.module('flinkApp').directive('bsLabel', ["JobsService", function(JobsService) {
+  return {
+    transclude: true,
+    replace: true,
+    scope: {
+      getLabelClass: "&",
+      status: "@"
+    },
+    template: "<span title='{{status}}' ng-class='getLabelClass()'><ng-transclude></ng-transclude></span>",
+    link: function(scope, element, attrs) {
+      return scope.getLabelClass = function() {
+        return 'label label-' + JobsService.translateLabelState(attrs.status);
+      };
+    }
+  };
+}]).directive('indicatorPrimary', ["JobsService", function(JobsService) {
+  return {
+    replace: true,
+    scope: {
+      getLabelClass: "&",
+      status: '@'
+    },
+    template: "<i title='{{status}}' ng-class='getLabelClass()' />",
+    link: function(scope, element, attrs) {
+      return scope.getLabelClass = function() {
+        return 'fa fa-circle indicator indicator-' + JobsService.translateLabelState(attrs.status);
+      };
+    }
+  };
+}]).directive('tableProperty', function() {
+  return {
+    replace: true,
+    scope: {
+      value: '='
+    },
+    template: "<td title=\"{{value || 'None'}}\">{{value || 'None'}}</td>"
+  };
+});
+
+angular.module('flinkApp').filter("amDurationFormatExtended", ["angularMomentConfig", function(angularMomentConfig) {
+  var amDurationFormatExtendedFilter;
+  amDurationFormatExtendedFilter = function(value, format, durationFormat) {
+    if (typeof value === "undefined" || value === null) {
+      return "";
+    }
+    return moment.duration(value, format).format(durationFormat, {
+      trim: false
+    });
+  };
+  amDurationFormatExtendedFilter.$stateful = angularMomentConfig.statefulFilters;
+  return amDurationFormatExtendedFilter;
+}]).filter("humanizeText", function() {
+  return function(text) {
+    if (text) {
+      return text.replace(/&gt;/g, ">").replace(/<br\/>/g, "");
+    } else {
+      return '';
+    }
+  };
+}).filter("bytes", function() {
+  return function(bytes, precision) {
+    var number, units;
+    if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) {
+      return "-";
+    }
+    if (typeof precision === "undefined") {
+      precision = 1;
+    }
+    units = ["bytes", "kB", "MB", "GB", "TB", "PB"];
+    number = Math.floor(Math.log(bytes) / Math.log(1024));
+    return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) + " " + units[number];
+  };
+});
+
+angular.module('flinkApp').service('MainService', ["$http", "flinkConfig", "$q", function($http, flinkConfig, $q) {
+  this.loadConfig = function() {
+    var deferred;
+    deferred = $q.defer();
+    $http.get("config").success(function(data, status, headers, config) {
+      return deferred.resolve(data);
+    });
+    return deferred.promise;
+  };
+  return this;
+}]);
+
+angular.module('flinkApp').controller('JobManagerConfigController', ["$scope", "JobManagerConfigService", function($scope, JobManagerConfigService) {
+  return JobManagerConfigService.loadConfig().then(function(data) {
+    if ($scope.jobmanager == null) {
+      $scope.jobmanager = {};
+    }
+    return $scope.jobmanager['config'] = data;
+  });
+}]).controller('JobManagerLogsController', ["$scope", "JobManagerLogsService", function($scope, JobManagerLogsService) {
+  JobManagerLogsService.loadLogs().then(function(data) {
+    if ($scope.jobmanager == null) {
+      $scope.jobmanager = {};
+    }
+    return $scope.jobmanager['log'] = data;
+  });
+  return $scope.reloadData = function() {
+    return JobManagerLogsService.loadLogs().then(function(data) {
+      return $scope.jobmanager['log'] = data;
+    });
+  };
+}]).controller('JobManagerStdoutController', ["$scope", "JobManagerStdoutService", function($scope, JobManagerStdoutService) {
+  JobManagerStdoutService.loadStdout().then(function(data) {
+    if ($scope.jobmanager == null) {
+      $scope.jobmanager = {};
+    }
+    return $scope.jobmanager['stdout'] = data;
+  });
+  return $scope.reloadData = function() {
+    return JobManagerStdoutService.loadStdout().then(function(data) {
+      return $scope.jobmanager['stdout'] = data;
+    });
+  };
+}]);
+
+angular.module('flinkApp').service('JobManagerConfigService', ["$http", "flinkConfig", "$q", function($http, flinkConfig, $q) {
+  var config;
+  config = {};
+  this.loadConfig = function() {
+    var deferred;
+    deferred = $q.defer();
+    $http.get("jobmanager/config").success(function(data, status, headers, config) {
+      config = data;
+      return deferred.resolve(data);
+    });
+    return deferred.promise;
+  };
+  return this;
+}]).service('JobManagerLogsService', ["$http", "flinkConfig", "$q", function($http, flinkConfig, $q) {
+  var logs;
+  logs = {};
+  this.loadLogs = function() {
+    var deferred;
+    deferred = $q.defer();
+    $http.get("jobmanager/log").success(function(data, status, headers, config) {
+      logs = data;
+      return deferred.resolve(data);
+    });
+    return deferred.promise;
+  };
+  return this;
+}]).service('JobManagerStdoutService', ["$http", "flinkConfig", "$q", function($http, flinkConfig, $q) {
+  var stdout;
+  stdout = {};
+  this.loadStdout = function() {
+    var deferred;
+    deferred = $q.defer();
+    $http.get("jobmanager/stdout").success(function(data, status, headers, config) {
+      stdout = data;
+      return deferred.resolve(data);
+    });
+    return deferred.promise;
+  };
+  return this;
+}]);
+
+angular.module('flinkApp').controller('RunningJobsController', ["$scope", "$state", "$stateParams", "JobsService", function($scope, $state, $stateParams, JobsService) {
+  $scope.jobObserver = function() {
+    return $scope.jobs = JobsService.getJobs('running');
+  };
+  JobsService.registerObserver($scope.jobObserver);
+  $scope.$on('$destroy', function() {
+    return JobsService.unRegisterObserver($scope.jobObserver);
+  });
+  return $scope.jobObserver();
+}]).controller('CompletedJobsController', ["$scope", "$state", "$stateParams", "JobsService", function($scope, $state, $stateParams, JobsService) {
+  $scope.jobObserver = function() {
+    return $scope.jobs = JobsService.getJobs('finished');
+  };
+  JobsService.registerObserver($scope.jobObserver);
+  $scope.$on('$destroy', function() {
+    return JobsService.unRegisterObserver($scope.jobObserver);
+  });
+  return $scope.jobObserver();
+}]).controller('SingleJobController', ["$scope", "$state", "$stateParams", "JobsService", "$rootScope", "flinkConfig", "$interval", function($scope, $state, $stateParams, JobsService, $rootScope, flinkConfig, $interval) {
+  var refresher;
+  console.log('SingleJobController');
+  $scope.jobid = $stateParams.jobid;
+  $scope.job = null;
+  $scope.plan = null;
+  $scope.vertices = null;
+  JobsService.loadJob($stateParams.jobid).then(function(data) {
+    $scope.job = data;
+    $scope.plan = data.plan;
+    return $scope.vertices = data.vertices;
+  });
+  refresher = $interval(function() {
+    return JobsService.loadJob($stateParams.jobid).then(function(data) {
+      $scope.job = data;
+      return $scope.$broadcast('reload');
+    });
+  }, flinkConfig["refresh-interval"]);
+  return $scope.$on('$destroy', function() {
+    $scope.job = null;
+    $scope.plan = null;
+    $scope.vertices = null;
+    return $interval.cancel(refresher);
+  });
+}]).controller('JobPlanController', ["$scope", "$state", "$stateParams", "JobsService", function($scope, $state, $stateParams, JobsService) {
+  console.log('JobPlanController');
+  $scope.nodeid = null;
+  $scope.nodeUnfolded = false;
+  $scope.stateList = JobsService.stateList();
+  $scope.changeNode = function(nodeid) {
+    if (nodeid !== $scope.nodeid) {
+      $scope.nodeid = nodeid;
+      $scope.vertex = null;
+      $scope.subtasks = null;
+      $scope.accumulators = null;
+      return $scope.$broadcast('reload');
+    } else {
+      $scope.nodeid = null;
+      $scope.nodeUnfolded = false;
+      $scope.vertex = null;
+      $scope.subtasks = null;
+      return $scope.accumulators = null;
+    }
+  };
+  $scope.deactivateNode = function() {
+    $scope.nodeid = null;
+    $scope.nodeUnfolded = false;
+    $scope.vertex = null;
+    $scope.subtasks = null;
+    return $scope.accumulators = null;
+  };
+  return $scope.toggleFold = function() {
+    return $scope.nodeUnfolded = !$scope.nodeUnfolded;
+  };
+}]).controller('JobPlanOverviewController', ["$scope", "JobsService", function($scope, JobsService) {
+  console.log('JobPlanOverviewController');
+  if ($scope.nodeid && (!$scope.vertex || !$scope.vertex.st)) {
+    JobsService.getSubtasks($scope.nodeid).then(function(data) {
+      return $scope.subtasks = data;
+    });
+  }
+  return $scope.$on('reload', function(event) {
+    console.log('JobPlanOverviewController');
+    if ($scope.nodeid) {
+      return JobsService.getSubtasks($scope.nodeid).then(function(data) {
+        return $scope.subtasks = data;
+      });
+    }
+  });
+}]).controller('JobPlanAccumulatorsController', ["$scope", "JobsService", function($scope, JobsService) {
+  console.log('JobPlanAccumulatorsController');
+  if ($scope.nodeid && (!$scope.vertex || !$scope.vertex.accumulators)) {
+    JobsService.getAccumulators($scope.nodeid).then(function(data) {
+      $scope.accumulators = data.main;
+      return $scope.subtaskAccumulators = data.subtasks;
+    });
+  }
+  return $scope.$on('reload', function(event) {
+    console.log('JobPlanAccumulatorsController');
+    if ($scope.nodeid) {
+      return JobsService.getAccumulators($scope.nodeid).then(function(data) {
+        $scope.accumulators = data.main;
+        return $scope.subtaskAccumulators = data.subtasks;
+      });
+    }
+  });
+}]).controller('JobTimelineVertexController', ["$scope", "$state", "$stateParams", "JobsService", function($scope, $state, $stateParams, JobsService) {
+  console.log('JobTimelineVertexController');
+  JobsService.getVertex($stateParams.vertexId).then(function(data) {
+    return $scope.vertex = data;
+  });
+  return $scope.$on('reload', function(event) {
+    console.log('JobTimelineVertexController');
+    return JobsService.getVertex($stateParams.vertexId).then(function(data) {
+      return $scope.vertex = data;
+    });
+  });
+}]).controller('JobExceptionsController', ["$scope", "$state", "$stateParams", "JobsService", function($scope, $state, $stateParams, JobsService) {
+  return JobsService.loadExceptions().then(function(data) {
+    return $scope.exceptions = data;
+  });
+}]).controller('JobPropertiesController', ["$scope", "JobsService", function($scope, JobsService) {
+  console.log('JobPropertiesController');
+  return $scope.changeNode = function(nodeid) {
+    if (nodeid !== $scope.nodeid) {
+      $scope.nodeid = nodeid;
+      return JobsService.getNode(nodeid).then(function(data) {
+        return $scope.node = data;
+      });
+    } else {
+      $scope.nodeid = null;
+      return $scope.node = null;
+    }
+  };
+}]);
+
+angular.module('flinkApp').directive('vertex', ["$state", function($state) {
+  return {
+    template: "<svg class='timeline secondary' width='0' height='0'></svg>",
+    scope: {
+      data: "="
+    },
+    link: function(scope, elem, attrs) {
+      var analyzeTime, containerW, svgEl;
+      svgEl = elem.children()[0];
+      containerW = elem.width();
+      angular.element(svgEl).attr('width', containerW);
+      analyzeTime = function(data) {
+        var chart, svg, testData;
+        d3.select(svgEl).selectAll("*").remove();
+        testData = [];
+        angular.forEach(data.subtasks, function(subtask, i) {
+          var times;
+          times = [
+            {
+              label: "Scheduled",
+              color: "#666",
+              borderColor: "#555",
+              starting_time: subtask.timestamps["SCHEDULED"],
+              ending_time: subtask.timestamps["DEPLOYING"],
+              type: 'regular'
+            }, {
+              label: "Deploying",
+              color: "#aaa",
+              borderColor: "#555",
+              starting_time: subtask.timestamps["DEPLOYING"],
+              ending_time: subtask.timestamps["RUNNING"],
+              type: 'regular'
+            }
+          ];
+          if (subtask.timestamps["FINISHED"] > 0) {
+            times.push({
+              label: "Running",
+              color: "#ddd",
+              borderColor: "#555",
+              starting_time: subtask.timestamps["RUNNING"],
+              ending_time: subtask.timestamps["FINISHED"],
+              type: 'regular'
+            });
+          }
+          return testData.push({
+            label: "(" + subtask.subtask + ") " + subtask.host,
+            times: times
+          });
+        });
+        chart = d3.timeline().stack().tickFormat({
+          format: d3.time.format("%L"),
+          tickSize: 1
+        }).prefix("single").labelFormat(function(label) {
+          return label;
+        }).margin({
+          left: 100,
+          right: 0,
+          top: 0,
+          bottom: 0
+        }).itemHeight(30).relativeTime();
+        return svg = d3.select(svgEl).datum(testData).call(chart);
+      };
+      analyzeTime(scope.data);
+    }
+  };
+}]).directive('timeline', ["$state", function($state) {
+  return {
+    template: "<svg class='timeline' width='0' height='0'></svg>",
+    scope: {
+      vertices: "=",
+      jobid: "="
+    },
+    link: function(scope, elem, attrs) {
+      var analyzeTime, containerW, svgEl, translateLabel;
+      svgEl = elem.children()[0];
+      containerW = elem.width();
+      angular.element(svgEl).attr('width', containerW);
+      translateLabel = function(label) {
+        return label.replace("&gt;", ">");
+      };
+      analyzeTime = function(data) {
+        var chart, svg, testData;
+        d3.select(svgEl).selectAll("*").remove();
+        testData = [];
+        angular.forEach(data, function(vertex) {
+          if (vertex['start-time'] > -1) {
+            if (vertex.type === 'scheduled') {
+              return testData.push({
+                times: [
+                  {
+                    label: translateLabel(vertex.name),
+                    color: "#cccccc",
+                    borderColor: "#555555",
+                    starting_time: vertex['start-time'],
+                    ending_time: vertex['end-time'],
+                    type: vertex.type
+                  }
+                ]
+              });
+            } else {
+              return testData.push({
+                times: [
+                  {
+                    label: translateLabel(vertex.name),
+                    color: "#d9f1f7",
+                    borderColor: "#62cdea",
+                    starting_time: vertex['start-time'],
+                    ending_time: vertex['end-time'],
+                    link: vertex.id,
+                    type: vertex.type
+                  }
+                ]
+              });
+            }
+          }
+        });
+        chart = d3.timeline().stack().click(function(d, i, datum) {
+          if (d.link) {
+            return $state.go("single-job.timeline.vertex", {
+              jobid: scope.jobid,
+              vertexId: d.link
+            });
+          }
+        }).tickFormat({
+          format: d3.time.format("%L"),
+          tickSize: 1
+        }).prefix("main").margin({
+          left: 0,
+          right: 0,
+          top: 0,
+          bottom: 0
+        }).itemHeight(30).showBorderLine().showHourTimeline();
+        return svg = d3.select(svgEl).datum(testData).call(chart);
+      };
+      scope.$watch(attrs.vertices, function(data) {
+        if (data) {
+          return analyzeTime(data);
+        }
+      });
+    }
+  };
+}]).directive('jobPlan', ["$timeout", function($timeout) {
+  return {
+    template: "<svg class='graph' width='500' height='400'><g /></svg> <svg class='tmp' width='1' height='1'><g /></svg> <div class='btn-group zoom-buttons'> <a class='btn btn-default zoom-in' ng-click='zoomIn()'><i class='fa fa-plus' /></a> <a class='btn btn-default zoom-out' ng-click='zoomOut()'><i class='fa fa-minus' /></a> </div>",
+    scope: {
+      plan: '=',
+      setNode: '&'
+    },
+    link: function(scope, elem, attrs) {
+      var containerW, createEdge, createLabelEdge, createLabelNode, createNode, d3mainSvg, d3mainSvgG, d3tmpSvg, drawGraph, extendLabelNodeForIteration, g, getNodeType, isSpecialIterationNode, jobid, loadJsonToDagre, mainG, mainSvgElement, mainTmpElement, mainZoom, searchForNode, shortenString, subgraphs;
+      g = null;
+      mainZoom = d3.behavior.zoom();
+      subgraphs = [];
+      jobid = attrs.jobid;
+      mainSvgElement = elem.children()[0];
+      mainG = elem.children().children()[0];
+      mainTmpElement = elem.children()[1];
+      d3mainSvg = d3.select(mainSvgElement);
+      d3mainSvgG = d3.select(mainG);
+      d3tmpSvg = d3.select(mainTmpElement);
+      containerW = elem.width();
+      angular.element(elem.children()[0]).width(containerW);
+      scope.zoomIn = function() {
+        var translate, v1, v2;
+        if (mainZoom.scale() < 2.99) {
+          translate = mainZoom.translate();
+          v1 = translate[0] * (mainZoom.scale() + 0.1 / (mainZoom.scale()));
+          v2 = translate[1] * (mainZoom.scale() + 0.1 / (mainZoom.scale()));
+          mainZoom.scale(mainZoom.scale() + 0.1);
+          mainZoom.translate([v1, v2]);
+          return d3mainSvgG.attr("transform", "translate(" + v1 + "," + v2 + ") scale(" + mainZoom.scale() + ")");
+        }
+      };
+      scope.zoomOut = function() {
+        var translate, v1, v2;
+        if (mainZoom.scale() > 0.31) {
+          mainZoom.scale(mainZoom.scale() - 0.1);
+          translate = mainZoom.translate();
+          v1 = translate[0] * (mainZoom.scale() - 0.1 / (mainZoom.scale()));
+          v2 = translate[1] * (mainZoom.scale() - 0.1 / (mainZoom.scale()));
+          mainZoom.translate([v1, v2]);
+          return d3mainSvgG.attr("transform", "translate(" + v1 + "," + v2 + ") scale(" + mainZoom.scale() + ")");
+        }
+      };
+      createLabelEdge = function(el) {
+        var labelValue;
+        labelValue = "";
+        if ((el.ship_strategy != null) || (el.local_strategy != null)) {
+          labelValue += "<div class='edge-label'>";
+          if (el.ship_strategy != null) {
+            labelValue += el.ship_strategy;
+          }
+          if (el.temp_mode !== undefined) {
+            labelValue += " (" + el.temp_mode + ")";
+          }
+          if (el.local_strategy !== undefined) {
+            labelValue += ",<br>" + el.local_strategy;
+          }
+          labelValue += "</div>";
+        }
+        return labelValue;
+      };
+      isSpecialIterationNode = function(info) {
+        return info === "partialSolution" || info === "nextPartialSolution" || info === "workset" || info === "nextWorkset" || info === "solutionSet" || info === "solutionDelta";
+      };
+      getNodeType = function(el, info) {
+        if (info === "mirror") {
+          return 'node-mirror';
+        } else if (isSpecialIterationNode(info)) {
+          return 'node-iteration';
+        } else {
+          return 'node-normal';
+        }
+      };
+      createLabelNode = function(el, info, maxW, maxH) {
+        var labelValue, stepName;
+        labelValue = "<div href='#/jobs/" + jobid + "/vertex/" + el.id + "' class='node-label " + getNodeType(el, info) + "'>";
+        if (info === "mirror") {
+          labelValue += "<h3 class='node-name'>Mirror of " + el.operator + "</h3>";
+        } else {
+          labelValue += "<h3 class='node-name'>" + el.operator + "</h3>";
+        }
+        if (el.description === "") {
+          labelValue += "";
+        } else {
+          stepName = el.description;
+          stepName = shortenString(stepName);
+          labelValue += "<h4 class='step-name'>" + stepName + "</h4>";
+        }
+        if (el.step_function != null) {
+          labelValue += extendLabelNodeForIteration(el.id, maxW, maxH);
+        } else {
+          if (isSpecialIterationNode(info)) {
+            labelValue += "<h5>" + info + " Node</h5>";
+          }
+          if (el.parallelism !== "") {
+            labelValue += "<h5>Parallelism: " + el.parallelism + "</h5>";
+          }
+          if (el.operator !== undefined) {
+            labelValue += "<h5>Operation: " + shortenString(el.operator_strategy) + "</h5>";
+          }
+        }
+        labelValue += "</div>";
+        return labelValue;
+      };
+      extendLabelNodeForIteration = function(id, maxW, maxH) {
+        var labelValue, svgID;
+        svgID = "svg-" + id;
+        labelValue = "<svg class='" + svgID + "' width=" + maxW + " height=" + maxH + "><g /></svg>";
+        return labelValue;
+      };
+      shortenString = function(s) {
+        var sbr;
+        if (s.charAt(0) === "<") {
+          s = s.replace("<", "&lt;");
+          s = s.replace(">", "&gt;");
+        }
+        sbr = "";
+        while (s.length > 30) {
+          sbr = sbr + s.substring(0, 30) + "<br>";
+          s = s.substring(30, s.length);
+        }
+        sbr = sbr + s;
+        return sbr;
+      };
+      createNode = function(g, data, el, isParent, maxW, maxH) {
+        if (isParent == null) {
+          isParent = false;
+        }
+        if (el.id === data.partial_solution) {
+          return g.setNode(el.id, {
+            label: createLabelNode(el, "partialSolution", maxW, maxH),
+            labelType: 'html',
+            "class": getNodeType(el, "partialSolution")
+          });
+        } else if (el.id === data.next_partial_solution) {
+          return g.setNode(el.id, {
+            label: createLabelNode(el, "nextPartialSolution", maxW, maxH),
+            labelType: 'html',
+            "class": getNodeType(el, "nextPartialSolution")
+          });
+        } else if (el.id === data.workset) {
+          return g.setNode(el.id, {
+            label: createLabelNode(el, "workset", maxW, maxH),
+            labelType: 'html',
+            "class": getNodeType(el, "workset")
+          });
+        } else if (el.id === data.next_workset) {
+          return g.setNode(el.id, {
+            label: createLabelNode(el, "nextWorkset", maxW, maxH),
+            labelType: 'html',
+            "class": getNodeType(el, "nextWorkset")
+          });
+        } else if (el.id === data.solution_set) {
+          return g.setNode(el.id, {
+            label: createLabelNode(el, "solutionSet", maxW, maxH),
+            labelType: 'html',
+            "class": getNodeType(el, "solutionSet")
+          });
+        } else if (el.id === data.solution_delta) {
+          return g.setNode(el.id, {
+            label: createLabelNode(el, "solutionDelta", maxW, maxH),
+            labelType: 'html',
+            "class": getNodeType(el, "solutionDelta")
+          });
+        } else {
+          return g.setNode(el.id, {
+            label: createLabelNode(el, "", maxW, maxH),
+            labelType: 'html',
+            "class": getNodeType(el, "")
+          });
+        }
+      };
+      createEdge = function(g, data, el, existingNodes, pred, missingNodes) {
+        var missingNode;
+        if (existingNodes.indexOf(pred.id) !== -1) {
+          return g.setEdge(pred.id, el.id, {
+            label: createLabelEdge(pred),
+            labelType: 'html',
+            arrowhead: 'normal'
+          });
+        } else {
+          missingNode = searchForNode(data, pred.id);
+          if (!(!missingNode || missingNodes.indexOf(missingNode.id) > -1)) {
+            missingNodes.push(missingNode.id);
+            g.setNode(missingNode.id, {
+              label: createLabelNode(missingNode, "mirror"),
+              labelType: 'html',
+              "class": getNodeType(missingNode, 'mirror')
+            });
+            return g.setEdge(missingNode.id, el.id, {
+              label: createLabelEdge(missingNode),
+              labelType: 'html'
+            });
+          }
+        }
+      };
+      loadJsonToDagre = function(g, data) {
+        var el, existingNodes, isParent, k, l, len, len1, maxH, maxW, missingNodes, pred, r, ref, sg, toIterate;
+        existingNodes = [];
+        missingNodes = [];
+        if (data.nodes != null) {
+          toIterate = data.nodes;
+        } else {
+          toIterate = data.step_function;
+          isParent = true;
+        }
+        for (k = 0, len = toIterate.length; k < len; k++) {
+          el = toIterate[k];
+          maxW = 0;
+          maxH = 0;
+          if (el.step_function) {
+            sg = new dagreD3.graphlib.Graph({
+              multigraph: true,
+              compound: true
+            }).setGraph({
+              nodesep: 20,
+              edgesep: 0,
+              ranksep: 20,
+              rankdir: "LR",
+              marginx: 10,
+              marginy: 10
+            });
+            subgraphs[el.id] = sg;
+            loadJsonToDagre(sg, el);
+            r = new dagreD3.render();
+            d3tmpSvg.select('g').call(r, sg);
+            maxW = sg.graph().width;
+            maxH = sg.graph().height;
+            angular.element(mainTmpElement).empty();
+          }
+          createNode(g, data, el, isParent, maxW, maxH);
+          existingNodes.push(el.id);
+          if (el.inputs != null) {
+            ref = el.inputs;
+            for (l = 0, len1 = ref.length; l < len1; l++) {
+              pred = ref[l];
+              createEdge(g, data, el, existingNodes, pred, missingNodes);
+            }
+          }
+        }
+        return g;
+      };
+      searchForNode = function(data, nodeID) {
+        var el, i, j;
+        for (i in data.nodes) {
+          el = data.nodes[i];
+          if (el.id === nodeID) {
+            return el;
+          }
+          if (el.step_function != null) {
+            for (j in el.step_function) {
+              if (el.step_function[j].id === nodeID) {
+                return el.step_function[j];
+              }
+            }
+          }
+        }
+      };
+      drawGraph = function(data) {
+        var i, newScale, renderer, sg, xCenterOffset, yCenterOffset;
+        g = new dagreD3.graphlib.Graph({
+          multigraph: true,
+          compound: true
+        }).setGraph({
+          nodesep: 70,
+          edgesep: 0,
+          ranksep: 50,
+          rankdir: "LR",
+          marginx: 40,
+          marginy: 40
+        });
+        loadJsonToDagre(g, data);
+        renderer = new dagreD3.render();
+        d3mainSvgG.call(renderer, g);
+        for (i in subgraphs) {
+          sg = subgraphs[i];
+          d3mainSvg.select('svg.svg-' + i + ' g').call(renderer, sg);
+        }
+        newScale = 0.5;
+        xCenterOffset = Math.floor((angular.element(mainSvgElement).width() - g.graph().width * newScale) / 2);
+        yCenterOffset = Math.floor((angular.element(mainSvgElement).height() - g.graph().height * newScale) / 2);
+        mainZoom.scale(newScale).translate([xCenterOffset, yCenterOffset]);
+        d3mainSvgG.attr("transform", "translate(" + xCenterOffset + ", " + yCenterOffset + ") scale(" + mainZoom.scale() + ")");
+        mainZoom.on("zoom", function() {
+          var ev;
+          ev = d3.event;
+          return d3mainSvgG.attr("transform", "translate(" + ev.translate + ") scale(" + ev.scale + ")");
+        });
+        mainZoom(d3mainSvg);
+        return d3mainSvgG.selectAll('.node').on('click', function(d) {
+          return scope.setNode({
+            nodeid: d
+          });
+        });
+      };
+      scope.$watch(attrs.plan, function(newPlan) {
+        if (newPlan) {
+          return drawGraph(newPlan);
+        }
+      });
+    }
+  };
+}]);
+
+angular.module('flinkApp').service('JobsService', ["$http", "flinkConfig", "$log", "amMoment", "$q", "$timeout", function($http, flinkConfig, $log, amMoment, $q, $timeout) {
+  var currentJob, currentPlan, deferreds, jobObservers, jobs, notifyObservers;
+  currentJob = null;
+  currentPlan = null;
+  deferreds = {};
+  jobs = {
+    running: [],
+    finished: [],
+    cancelled: [],
+    failed: []
+  };
+  jobObservers = [];
+  notifyObservers = function() {
+    return angular.forEach(jobObservers, function(callback) {
+      return callback();
+    });
+  };
+  this.registerObserver = function(callback) {
+    return jobObservers.push(callback);
+  };
+  this.unRegisterObserver = function(callback) {
+    var index;
+    index = jobObservers.indexOf(callback);
+    return jobObservers.splice(index, 1);
+  };
+  this.stateList = function() {
+    return ['SCHEDULED', 'DEPLOYING', 'RUNNING', 'FINISHED', 'FAILED', 'CANCELING', 'CANCELED'];
+  };
+  this.translateLabelState = function(state) {
+    switch (state.toLowerCase()) {
+      case 'finished':
+        return 'success';
+      case 'failed':
+        return 'danger';
+      case 'scheduled':
+        return 'default';
+      case 'deploying':
+        return 'info';
+      case 'running':
+        return 'primary';
+      case 'canceling':
+        return 'warning';
+      case 'pending':
+        return 'info';
+      case 'total':
+        return 'black';
+      default:
+        return 'default';
+    }
+  };
+  this.setEndTimes = function(list) {
+    return angular.forEach(list, function(item, jobKey) {
+      if (!(item['end-time'] > -1)) {
+        return item['end-time'] = item['start-time'] + item['duration'];
+      }
+    });
+  };
+  this.processVertices = function(data) {
+    angular.forEach(data.vertices, function(vertex, i) {
+      return vertex.type = 'regular';
+    });
+    return data.vertices.unshift({
+      name: 'Scheduled',
+      'start-time': data.timestamps['CREATED'],
+      'end-time': data.timestamps['CREATED'] + 1,
+      type: 'scheduled'
+    });
+  };
+  this.listJobs = function() {
+    var deferred;
+    deferred = $q.defer();
+    $http.get("joboverview").success((function(_this) {
+      return function(data, status, headers, config) {
+        angular.forEach(data, function(list, listKey) {
+          switch (listKey) {
+            case 'running':
+              return jobs.running = _this.setEndTimes(list);
+            case 'finished':
+              return jobs.finished = _this.setEndTimes(list);
+            case 'cancelled':
+              return jobs.cancelled = _this.setEndTimes(list);
+            case 'failed':
+              return jobs.failed = _this.setEndTimes(list);
+          }
+        });
+        deferred.resolve(jobs);
+        return notifyObservers();
+      };
+    })(this));
+    return deferred.promise;
+  };
+  this.getJobs = function(type) {
+    return jobs[type];
+  };
+  this.getAllJobs = function() {
+    return jobs;
+  };
+  this.loadJob = function(jobid) {
+    currentJob = null;
+    deferreds.job = $q.defer();
+    $http.get("jobs/" + jobid).success((function(_this) {
+      return function(data, status, headers, config) {
+        _this.setEndTimes(data.vertices);
+        _this.processVertices(data);
+        return $http.get("jobs/" + jobid + "/config").success(function(jobConfig) {
+          data = angular.extend(data, jobConfig);
+          currentJob = data;
+          return deferreds.job.resolve(currentJob);
+        });
+      };
+    })(this));
+    return deferreds.job.promise;
+  };
+  this.getNode = function(nodeid) {
+    var deferred, seekNode;
+    seekNode = function(nodeid, data) {
+      var j, len, node, sub;
+      for (j = 0, len = data.length; j < len; j++) {
+        node = data[j];
+        if (node.id === nodeid) {
+          return node;
+        }
+        if (node.step_function) {
+          sub = seekNode(nodeid, node.step_function);
+        }
+        if (sub) {
+          return sub;
+        }
+      }
+      return null;
+    };
+    deferred = $q.defer();
+    deferreds.job.promise.then((function(_this) {
+      return function(data) {
+        var foundNode;
+        foundNode = seekNode(nodeid, currentJob.plan.nodes);
+        foundNode.vertex = _this.seekVertex(nodeid);
+        return deferred.resolve(foundNode);
+      };
+    })(this));
+    return deferred.promise;
+  };
+  this.seekVertex = function(nodeid) {
+    var j, len, ref, vertex;
+    ref = currentJob.vertices;
+    for (j = 0, len = ref.length; j < len; j++) {
+      vertex = ref[j];
+      if (vertex.id === nodeid) {
+        return vertex;
+      }
+    }
+    return null;
+  };
+  this.getVertex = function(vertexid) {
+    var deferred;
+    deferred = $q.defer();
+    deferreds.job.promise.then((function(_this) {
+      return function(data) {
+        var vertex;
+        vertex = _this.seekVertex(vertexid);
+        return $http.get("jobs/" + currentJob.jid + "/vertices/" + vertexid + "/subtasktimes").success(function(data) {
+          vertex.subtasks = data.subtasks;
+          return deferred.resolve(vertex);
+        });
+      };
+    })(this));
+    return deferred.promise;
+  };
+  this.getSubtasks = function(vertexid) {
+    var deferred;
+    deferred = $q.defer();
+    deferreds.job.promise.then((function(_this) {
+      return function(data) {
+        return $http.get("jobs/" + currentJob.jid + "/vertices/" + vertexid).success(function(data) {
+          var subtasks;
+          subtasks = data.subtasks;
+          return deferred.resolve(subtasks);
+        });
+      };
+    })(this));
+    return deferred.promise;
+  };
+  this.getAccumulators = function(vertexid) {
+    var deferred;
+    deferred = $q.defer();
+    deferreds.job.promise.then((function(_this) {
+      return function(data) {
+        return $http.get("jobs/" + currentJob.jid + "/vertices/" + vertexid + "/accumulators").success(function(data) {
+          var accumulators;
+          accumulators = data['user-accumulators'];
+          return $http.get("jobs/" + currentJob.jid + "/vertices/" + vertexid + "/subtasks/accumulators").success(function(data) {
+            var subtaskAccumulators;
+            subtaskAccumulators = data.subtasks;
+            return deferred.resolve({
+              main: accumulators,
+              subtasks: subtaskAccumulators
+            });
+          });
+        });
+      };
+    })(this));
+    return deferred.promise;
+  };
+  this.loadExceptions = function() {
+    var deferred;
+    deferred = $q.defer();
+    deferreds.job.promise.then((function(_this) {
+      return function(data) {
+        return $http.get("jobs/" + currentJob.jid + "/exceptions").success(function(exceptions) {
+          currentJob.exceptions = exceptions;
+          return deferred.resolve(exceptions);
+        });
+      };
+    })(this));
+    return deferred.promise;
+  };
+  return this;
+}]);
+
+angular.module('flinkApp').controller('OverviewController', ["$scope", "OverviewService", "JobsService", "$interval", "flinkConfig", function($scope, OverviewService, JobsService, $interval, flinkConfig) {
+  var refresh;
+  $scope.jobObserver = function() {
+    $scope.runningJobs = JobsService.getJobs('running');
+    return $scope.finishedJobs = JobsService.getJobs('finished');
+  };
+  JobsService.registerObserver($scope.jobObserver);
+  $scope.$on('$destroy', function() {
+    return JobsService.unRegisterObserver($scope.jobObserver);
+  });
+  $scope.jobObserver();
+  OverviewService.loadOverview().then(function(data) {
+    return $scope.overview = data;
+  });
+  refresh = $interval(function() {
+    return OverviewService.loadOverview().then(function(data) {
+      return $scope.overview = data;
+    });
+  }, flinkConfig["refresh-interval"]);
+  return $scope.$on('$destroy', function() {
+    return $interval.cancel(refresh);
+  });
+}]);
+
+angular.module('flinkApp').service('OverviewService', ["$http", "flinkConfig", "$q", function($http, flinkConfig, $q) {
+  var overview;
+  overview = {};
+  this.loadOverview = function() {
+    var deferred;
+    deferred = $q.defer();
+    $http.get("overview").success(function(data, status, headers, config) {
+      overview = data;
+      return deferred.resolve(data);
+    });
+    return deferred.promise;
+  };
+  return this;
+}]);
+
+angular.module('flinkApp').controller('AllTaskManagersController', ["$scope", "TaskManagersService", "$interval", "flinkConfig", function($scope, TaskManagersService, $interval, flinkConfig) {
+  var refresh;
+  TaskManagersService.loadManagers().then(function(data) {
+    return $scope.managers = data;
+  });
+  refresh = $interval(function() {
+    return TaskManagersService.loadManagers().then(function(data) {
+      return $scope.managers = data;
+    });
+  }, flinkConfig["refresh-interval"]);
+  return $scope.$on('$destroy', function() {
+    return $interval.cancel(refresh);
+  });
+}]).controller('SingleTaskManagerController', ["$scope", "$stateParams", "SingleTaskManagerService", "$interval", "flinkConfig", function($scope, $stateParams, SingleTaskManagerService, $interval, flinkConfig) {
+  var refresh;
+  $scope.metrics = {};
+  SingleTaskManagerService.loadMetrics($stateParams.taskmanagerid).then(function(data) {
+    return $scope.metrics = data[0];
+  });
+  refresh = $interval(function() {
+    return SingleTaskManagerService.loadMetrics($stateParams.taskmanagerid).then(function(data) {
+      return $scope.metrics = data[0];
+    });
+  }, flinkConfig["refresh-interval"]);
+  return $scope.$on('$destroy', function() {
+    return $interval.cancel(refresh);
+  });
+}]);
+
+angular.module('flinkApp').directive('livechart', function() {
+  return {
+    link: function(scope, element, attrs) {
+      var getChartOptions, getChartType, getKey1, getKey2, getKey3, getKey4, getYAxisTitle, updateCharts;
+      getChartType = function() {
+        if (attrs.key === "cpuLoad") {
+          return "spline";
+        } else {
+          return "area";
+        }
+      };
+      getYAxisTitle = function() {
+        if (attrs.key === "cpuLoad") {
+          return "CPU Usage(%)";
+        } else {
+          return "Memory(MB)";
+        }
+      };
+      getKey1 = function() {
+        return "memory.total." + attrs.key;
+      };
+      getKey2 = function() {
+        return "memory.heap." + attrs.key;
+      };
+      getKey3 = function() {
+        return "memory.non-heap." + attrs.key;
+      };
+      getKey4 = function() {
+        return "cpuLoad";
+      };
+      getChartOptions = function() {
+        return {
+          title: {
+            text: ' '
+          },
+          chart: {
+            type: getChartType(),
+            zoomType: 'x'
+          },
+          xAxis: {
+            type: 'datetime'
+          },
+          yAxis: {
+            title: {
+              text: getYAxisTitle()
+            },
+            min: attrs.key === "cpuLoad" ? 0 : void 0,
+            max: attrs.key === "cpuLoad" ? 100 : void 0
+          },
+          series: [
+            {
+              name: "Memory: Total",
+              id: getKey1(),
+              data: [],
+              color: "#7cb5ec"
+            }, {
+              name: "Memory: Heap",
+              id: getKey2(),
+              data: [],
+              color: "#434348"
+            }, {
+              name: "Memory: Non-Heap",
+              id: getKey3(),
+              data: [],
+              color: "#90ed7d"
+            }, {
+              name: "CPU Usage",
+              id: getKey4(),
+              data: [],
+              color: "#f7a35c",
+              showInLegend: false
+            }
+          ],
+          legend: {
+            enabled: false
+          },
+          tooltip: {
+            shared: true
+          },
+          exporting: {
+            enabled: false
+          },
+          credits: {
+            enabled: false
+          }
+        };
+      };
+      if (element.highcharts() == null) {
+        element.highcharts(getChartOptions());
+      }
+      scope.$watch(attrs.data, function(value) {
+        return updateCharts(value);
+      });
+      return updateCharts = function(value) {
+        return (function(value) {
+          var chart, divider, heartbeat;
+          heartbeat = value.timeSinceLastHeartbeat;
+          chart = element.highcharts();
+          if (attrs.key === "cpuLoad") {
+            return chart.get(getKey4()).addPoint([heartbeat, +((value.metrics.gauges[getKey4()].value * 100).toFixed(2))], true, false);
+          } else {
+            divider = 1048576;
+            chart.get(getKey1()).addPoint([heartbeat, +((value.metrics.gauges[getKey1()].value / divider).toFixed(2))], true, false);
+            chart.get(getKey2()).addPoint([heartbeat, +((value.metrics.gauges[getKey2()].value / divider).toFixed(2))], true, false);
+            return chart.get(getKey3()).addPoint([heartbeat, +((value.metrics.gauges[getKey3()].value / divider).toFixed(2))], true, false);
+          }
+        })(value);
+      };
+    }
+  };
+});
+
+angular.module('flinkApp').service('TaskManagersService', ["$http", "flinkConfig", "$q", function($http, flinkConfig, $q) {
+  this.loadManagers = function() {
+    var deferred;
+    deferred = $q.defer();
+    $http.get("taskmanagers").success(function(data, status, headers, config) {
+      return deferred.resolve(data['taskmanagers']);
+    });
+    return deferred.promise;
+  };
+  return this;
+}]).service('SingleTaskManagerService', ["$http", "flinkConfig", "$q", function($http, flinkConfig, $q) {
+  this.loadMetrics = function(taskmanagerid) {
+    var deferred;
+    deferred = $q.defer();
+    $http.get("taskmanagers/" + taskmanagerid).success(function(data, status, headers, config) {
+      return deferred.resolve(data['taskmanagers']);
+    });
+    return deferred.promise;
+  };
+  return this;
+}]);
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmNvZmZlZSIsImluZGV4LmpzIiwiY29tbW9uL2RpcmVjdGl2ZXMuY29mZmVlIiwiY29tbW9uL2RpcmVjdGl2ZXMuanMiLCJjb21tb24vZmlsdGVycy5jb2ZmZWUiLCJjb21tb24vZmlsdGVycy5qcyIsImNvbW1vbi9zZXJ2aWNlcy5jb2ZmZWUiLCJjb21tb24vc2VydmljZXMuanMiLCJtb2R1bGVzL2pvYm1hbmFnZXIvam9ibWFuYWdlci5jdHJsLmNvZmZlZSIsIm1vZHVsZXMvam9ibWFuYWdlci9qb2JtYW5hZ2VyLmN0cmwuanMiLCJtb2R1bGVzL2pvYm1hbmFnZXIvam9ibWFuYWdlci5zdmMuY29mZmVlIiwibW9kdWxlcy9qb2JtYW5hZ2VyL2pvYm1hbmFnZXIuc3ZjLmpzIiwibW9kdWxlcy9qb2JzL2pvYnMuY3RybC5jb2ZmZWUiLCJtb2R1bGVzL2pvYnMvam9icy5jdHJsLmpzIiwibW9kdWxlcy9qb2JzL2pvYnMuZGlyLmNvZmZlZSIsIm1vZHVsZXMvam9icy9qb2JzLmRpci5qcyIsIm1vZHVsZXMvam9icy9qb2JzLnN2Yy5jb2ZmZWUiLCJtb2R1bGVzL2pvYnMvam9icy5zdmMuanMiLCJtb2R1bGVzL292ZXJ2aWV3L292ZXJ2aWV3LmN0cmwuY29mZmVlIiwibW9kdWxlcy9vdmVydmlldy9vdmVydmlldy5jdHJsLmpzIiwibW9kdWxlcy9vdmVydmlldy9vdmVydmlldy5zdmMuY29mZmVlIiwibW9kdWxlcy9vdmVydmlldy9vdmVydmlldy5zdmMuanMiLCJtb2R1bGVzL3Rhc2ttYW5hZ2VyL3Rhc2ttYW5
 hZ2VyLmN0cmwuY29mZmVlIiwibW9kdWxlcy90YXNrbWFuYWdlci90YXNrbWFuYWdlci5jdHJsLmpzIiwibW9kdWxlcy90YXNrbWFuYWdlci90YXNrbWFuYWdlci5kaXIuY29mZmVlIiwibW9kdWxlcy90YXNrbWFuYWdlci90YXNrbWFuYWdlci5kaXIuanMiLCJtb2R1bGVzL3Rhc2ttYW5hZ2VyL3Rhc2ttYW5hZ2VyLnN2Yy5jb2ZmZWUiLCJtb2R1bGVzL3Rhc2ttYW5hZ2VyL3Rhc2ttYW5hZ2VyLnN2Yy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFrQkEsUUFBUSxPQUFPLFlBQVksQ0FBQyxhQUFhLGtCQUl4QyxtQkFBSSxTQUFDLFlBQUQ7RUFDSCxXQUFXLGlCQUFpQjtFQ3JCNUIsT0RzQkEsV0FBVyxjQUFjLFdBQUE7SUFDdkIsV0FBVyxpQkFBaUIsQ0FBQyxXQUFXO0lDckJ4QyxPRHNCQSxXQUFXLGVBQWU7O0lBSTdCLE1BQU0sZUFBZTtFQUNwQixvQkFBb0I7R0FLckIsK0RBQUksU0FBQyxhQUFhLGFBQWEsYUFBYSxXQUF4QztFQUNILFlBQVksYUFBYSxLQUFLLFNBQUMsUUFBRDtJQUM1QixRQUFRLE9BQU8sYUFBYTtJQUU1QixZQUFZO0lDNUJaLE9EOEJBLFVBQVUsV0FBQTtNQzdCUixPRDhCQSxZQUFZO09BQ1osWUFBWTs7RUFFaEIsV0FBVyxXQUFXO0lBQ3BCLFFBQVE7TUFDTixRQUFROzs7RUFZWixXQUFXLGNBQWMsUUFBUTtJQUNoQyxNQUFNO0lBQ04sS0FBSztJQUNMLE1BQU07S0FDSixNQUFNLFNBQVMscUJBQXFCLFFBQVE7RUFFL0MsV0FBVyxRQUFRO0lBQ2xCLFFBQVEsQ0FBQyxXQUFXLFdBQVcsV0FB
 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
 TTtjQUFhLElBQUk7Y0FBVyxNQUFNO2NBQUksT0FBTztjQUFXLGNBQWM7OztVQUUvRSxRQUFRO1lBQUMsU0FBUzs7VUFDbEIsU0FBUztZQUFDLFFBQVE7O1VBQ2xCLFdBQVc7WUFBQyxTQUFTOztVQUNyQixTQUFTO1lBQUMsU0FBUzs7OztNQUdyQixJQUFJLFFBQUEsZ0JBQUEsTUFBSjtRQUNFLFFBQVEsV0FBVzs7TUFFckIsTUFBTSxPQUFPLE1BQU0sTUFBTSxTQUFDLE9BQUQ7UUN1QnZCLE9EdEJBLGFBQWE7O01Dd0JmLE9EckJBLGVBQWUsU0FBQyxPQUFEO1FDc0JiLE9EckJFLENBQUEsU0FBQyxPQUFEO1VBQ0EsSUFBQSxPQUFBLFNBQUE7VUFBQSxZQUFZLE1BQU07VUFDbEIsUUFBUSxRQUFRO1VBQ2hCLElBQUcsTUFBTSxRQUFPLFdBQWhCO1lDdUJFLE9EdEJBLE1BQU0sSUFBSSxXQUFXLFNBQVMsQ0FDNUIsV0FBVyxFQUFFLENBQUMsTUFBTSxRQUFRLE9BQU8sV0FBVyxRQUFRLEtBQUssUUFBUSxNQUNsRSxNQUFNO2lCQUhYO1lBS0UsVUFBVTtZQUNWLE1BQU0sSUFBSSxXQUFXLFNBQVMsQ0FDNUIsV0FBVyxFQUFFLENBQUMsTUFBTSxRQUFRLE9BQU8sV0FBVyxRQUFRLFNBQVMsUUFBUSxNQUN0RSxNQUFNO1lBQ1QsTUFBTSxJQUFJLFdBQVcsU0FBUyxDQUM1QixXQUFXLEVBQUUsQ0FBQyxNQUFNLFFBQVEsT0FBTyxXQUFXLFFBQVEsU0FBUyxRQUFRLE1BQ3RFLE1BQU07WUNpQlQsT0RoQkEsTUFBTSxJQUFJLFdBQVcsU0FBUyxDQUM1QixXQUFXLEVBQUUsQ0FBQyxNQUFNLFFBQVEsT0FBTyxXQUFXLFFBQVEsU0FBUyxRQ
 UFRLE1BQ3RFLE1BQU07O1dBakJWOzs7OztBQ3NDWDtBQzdGQSxRQUFRLE9BQU8sWUFFZCxRQUFRLHNEQUF1QixTQUFDLE9BQU8sYUFBYSxJQUFyQjtFQUM5QixLQUFDLGVBQWUsV0FBQTtJQUNkLElBQUE7SUFBQSxXQUFXLEdBQUc7SUFFZCxNQUFNLElBQUksZ0JBQ1QsUUFBUSxTQUFDLE1BQU0sUUFBUSxTQUFTLFFBQXhCO01DcEJQLE9EcUJBLFNBQVMsUUFBUSxLQUFLOztJQ25CeEIsT0RxQkEsU0FBUzs7RUNuQlgsT0RxQkE7SUFFRCxRQUFRLDJEQUE0QixTQUFDLE9BQU8sYUFBYSxJQUFyQjtFQUNuQyxLQUFDLGNBQWMsU0FBQyxlQUFEO0lBQ2IsSUFBQTtJQUFBLFdBQVcsR0FBRztJQUVkLE1BQU0sSUFBSSxrQkFBa0IsZUFDM0IsUUFBUSxTQUFDLE1BQU0sUUFBUSxTQUFTLFFBQXhCO01DdEJQLE9EdUJBLFNBQVMsUUFBUSxLQUFLOztJQ3JCeEIsT0R1QkEsU0FBUzs7RUNyQlgsT0R1QkE7O0FDckJGIiwiZmlsZSI6ImluZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiI1xyXG4jIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcclxuIyBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcclxuIyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxyXG4jIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbG
 VcclxuIyB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXHJcbiMgXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXHJcbiMgd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG4jXHJcbiMgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG4jXHJcbiMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxyXG4jIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcclxuIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cclxuIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXHJcbiMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiNcclxuXHJcbmFuZ3VsYXIubW9kdWxlKCdmbGlua0FwcCcsIFsndWkucm91dGVyJywgJ2FuZ3VsYXJNb21lbnQnXSlcclxuXHJcbiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbi5ydW4gKCRyb290U2NvcGUpIC0+XHJcbiAgJHJvb3RTY29wZS5zaWR
 lYmFyVmlzaWJsZSA9IGZhbHNlXHJcbiAgJHJvb3RTY29wZS5zaG93U2lkZWJhciA9IC0+XHJcbiAgICAkcm9vdFNjb3BlLnNpZGViYXJWaXNpYmxlID0gISRyb290U2NvcGUuc2lkZWJhclZpc2libGVcclxuICAgICRyb290U2NvcGUuc2lkZWJhckNsYXNzID0gJ2ZvcmNlLXNob3cnXHJcblxyXG4jIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG4udmFsdWUgJ2ZsaW5rQ29uZmlnJywge1xyXG4gIFwicmVmcmVzaC1pbnRlcnZhbFwiOiAxMDAwMFxyXG59XHJcblxyXG4jIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG4ucnVuIChKb2JzU2VydmljZSwgTWFpblNlcnZpY2UsIGZsaW5rQ29uZmlnLCAkaW50ZXJ2YWwpIC0+XHJcbiAgTWFpblNlcnZpY2UubG9hZENvbmZpZygpLnRoZW4gKGNvbmZpZykgLT5cclxuICAgIGFuZ3VsYXIuZXh0ZW5kIGZsaW5rQ29uZmlnLCBjb25maWdcclxuXHJcbiAgICBKb2JzU2VydmljZS5saXN0Sm9icygpXHJcblxyXG4gICAgJGludGVydmFsIC0+XHJcbiAgICAgIEpvYnNTZXJ2aWNlLmxpc3RKb2JzKClcclxuICAgICwgZmxpbmtDb25maWdbXCJyZWZyZXNoLWludGVydmFsXCJdXHJcblxyXG4gIEhpZ2hjaGFydHMuc2V0T3B0aW9ucyh7XHJcbiAgICBnbG9iYWw6IHtcclxuICAgICAgdXNlVVRDOiBmYWxzZVxyXG4gICAgfVxyXG4gIH0pXHJcblxyXG4gICNcclxuICAjIEdyaWQtbGlnaHQgdGhlbWUgZm9yIEhpZ2hj
 aGFydHMgSlNcclxuICAjIEBhdXRob3IgVG9yc3RlaW4gSG9uc2lcclxuICAjXHJcbiAgIyBUYWtlbiBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9oaWdoc2xpZGUtc29mdHdhcmUvaGlnaGNoYXJ0cy5jb21cclxuICAjXHJcblxyXG5cclxuICBIaWdoY2hhcnRzLmNyZWF0ZUVsZW1lbnQoJ2xpbmsnLCB7XHJcbiAgXHRocmVmOiAnLy9mb250cy5nb29nbGVhcGlzLmNvbS9jc3M/ZmFtaWx5PURvc2lzOjQwMCw2MDAnLFxyXG4gIFx0cmVsOiAnc3R5bGVzaGVldCcsXHJcbiAgXHR0eXBlOiAndGV4dC9jc3MnXHJcbiAgfSwgbnVsbCwgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXSk7XHJcblxyXG4gIEhpZ2hjaGFydHMudGhlbWUgPSB7XHJcbiAgXHRjb2xvcnM6IFtcIiM3Y2I1ZWNcIiwgXCIjZjdhMzVjXCIsIFwiIzkwZWU3ZVwiLCBcIiM3Nzk4QkZcIiwgXCIjYWFlZWVlXCIsIFwiI2ZmMDA2NlwiLCBcIiNlZWFhZWVcIixcclxuICBcdFx0XCIjNTVCRjNCXCIsIFwiI0RGNTM1M1wiLCBcIiM3Nzk4QkZcIiwgXCIjYWFlZWVlXCJdLFxyXG4gIFx0Y2hhcnQ6IHtcclxuICBcdFx0YmFja2dyb3VuZENvbG9yOiBudWxsLFxyXG4gIFx0XHRzdHlsZToge1xyXG4gIFx0XHRcdGZvbnRGYW1pbHk6IFwiRG9zaXMsIHNhbnMtc2VyaWZcIlxyXG4gIFx0XHR9XHJcbiAgXHR9LFxyXG4gIFx0dGl0bGU6IHtcclxuICBcdFx0c3R5bGU6IHtcclxuICBcdFx0XHRmb250U2l6ZTogJzE2cHgnLFxyXG4gIFx0XHRcd
 GZvbnRXZWlnaHQ6ICdib2xkJyxcclxuICBcdFx0XHR0ZXh0VHJhbnNmb3JtOiAndXBwZXJjYXNlJ1xyXG4gIFx0XHR9XHJcbiAgXHR9LFxyXG4gIFx0dG9vbHRpcDoge1xyXG4gIFx0XHRib3JkZXJXaWR0aDogMCxcclxuICBcdFx0YmFja2dyb3VuZENvbG9yOiAncmdiYSgyMTksMjE5LDIxNiwwLjgpJyxcclxuICBcdFx0c2hhZG93OiBmYWxzZVxyXG4gIFx0fSxcclxuICBcdGxlZ2VuZDoge1xyXG4gIFx0XHRpdGVtU3R5bGU6IHtcclxuICBcdFx0XHRmb250V2VpZ2h0OiAnYm9sZCcsXHJcbiAgXHRcdFx0Zm9udFNpemU6ICcxM3B4J1xyXG4gIFx0XHR9XHJcbiAgXHR9LFxyXG4gIFx0eEF4aXM6IHtcclxuICBcdFx0Z3JpZExpbmVXaWR0aDogMSxcclxuICBcdFx0bGFiZWxzOiB7XHJcbiAgXHRcdFx0c3R5bGU6IHtcclxuICBcdFx0XHRcdGZvbnRTaXplOiAnMTJweCdcclxuICBcdFx0XHR9XHJcbiAgXHRcdH1cclxuICBcdH0sXHJcbiAgXHR5QXhpczoge1xyXG4gIFx0XHRtaW5vclRpY2tJbnRlcnZhbDogJ2F1dG8nLFxyXG4gIFx0XHR0aXRsZToge1xyXG4gIFx0XHRcdHN0eWxlOiB7XHJcbiAgXHRcdFx0XHR0ZXh0VHJhbnNmb3JtOiAndXBwZXJjYXNlJ1xyXG4gIFx0XHRcdH1cclxuICBcdFx0fSxcclxuICBcdFx0bGFiZWxzOiB7XHJcbiAgXHRcdFx0c3R5bGU6IHtcclxuICBcdFx0XHRcdGZvbnRTaXplOiAnMTJweCdcclxuICBcdFx0XHR9XHJcbiAgXHRcdH1cclxuICBcdH0sXHJcbiAgXHRwbG90T3B0aW9ucz
 oge1xyXG4gIFx0XHRjYW5kbGVzdGljazoge1xyXG4gIFx0XHRcdGxpbmVDb2xvcjogJyM0MDQwNDgnXHJcbiAgXHRcdH1cclxuICBcdH0sXHJcblxyXG4gIFx0YmFja2dyb3VuZDI6ICcjRjBGMEVBJ1xyXG5cclxuICB9O1xyXG5cclxuICBIaWdoY2hhcnRzLnNldE9wdGlvbnMoSGlnaGNoYXJ0cy50aGVtZSk7XHJcblxyXG5cclxuIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuLmNvbmZpZyAoJHVpVmlld1Njcm9sbFByb3ZpZGVyKSAtPlxyXG4gICR1aVZpZXdTY3JvbGxQcm92aWRlci51c2VBbmNob3JTY3JvbGwoKVxyXG5cclxuIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuLmNvbmZpZyAoJHN0YXRlUHJvdmlkZXIsICR1cmxSb3V0ZXJQcm92aWRlcikgLT5cclxuICAkc3RhdGVQcm92aWRlci5zdGF0ZSBcIm92ZXJ2aWV3XCIsXHJcbiAgICB1cmw6IFwiL292ZXJ2aWV3XCJcclxuICAgIHZpZXdzOlxyXG4gICAgICBtYWluOlxyXG4gICAgICAgIHRlbXBsYXRlVXJsOiBcInBhcnRpYWxzL292ZXJ2aWV3Lmh0bWxcIlxyXG4gICAgICAgIGNvbnRyb2xsZXI6ICdPdmVydmlld0NvbnRyb2xsZXInXHJcblxyXG4gIC5zdGF0ZSBcInJ1bm5pbmctam9ic1wiLFxyXG4gICAgdXJsOiBcIi9ydW5uaW5nLWpvYnNcIlxyXG4gICAgdmlld3M6XHJcbiAgICAgIG1haW46XHJcbiAgICAgICAgdGVtcGxhdGVVcmw6IFwicGFydGlhbHMvam9icy9ydW5uaW5
 nLWpvYnMuaHRtbFwiXHJcbiAgICAgICAgY29udHJvbGxlcjogJ1J1bm5pbmdKb2JzQ29udHJvbGxlcidcclxuICBcclxuICAuc3RhdGUgXCJjb21wbGV0ZWQtam9ic1wiLFxyXG4gICAgdXJsOiBcIi9jb21wbGV0ZWQtam9ic1wiXHJcbiAgICB2aWV3czpcclxuICAgICAgbWFpbjpcclxuICAgICAgICB0ZW1wbGF0ZVVybDogXCJwYXJ0aWFscy9qb2JzL2NvbXBsZXRlZC1qb2JzLmh0bWxcIlxyXG4gICAgICAgIGNvbnRyb2xsZXI6ICdDb21wbGV0ZWRKb2JzQ29udHJvbGxlcidcclxuXHJcbiAgLnN0YXRlIFwic2luZ2xlLWpvYlwiLFxyXG4gICAgdXJsOiBcIi9qb2JzL3tqb2JpZH1cIlxyXG4gICAgYWJzdHJhY3Q6IHRydWVcclxuICAgIHZpZXdzOlxyXG4gICAgICBtYWluOlxyXG4gICAgICAgIHRlbXBsYXRlVXJsOiBcInBhcnRpYWxzL2pvYnMvam9iLmh0bWxcIlxyXG4gICAgICAgIGNvbnRyb2xsZXI6ICdTaW5nbGVKb2JDb250cm9sbGVyJ1xyXG5cclxuICAuc3RhdGUgXCJzaW5nbGUtam9iLnBsYW5cIixcclxuICAgIHVybDogXCJcIlxyXG4gICAgYWJzdHJhY3Q6IHRydWVcclxuICAgIHZpZXdzOlxyXG4gICAgICBkZXRhaWxzOlxyXG4gICAgICAgIHRlbXBsYXRlVXJsOiBcInBhcnRpYWxzL2pvYnMvam9iLnBsYW4uaHRtbFwiXHJcbiAgICAgICAgY29udHJvbGxlcjogJ0pvYlBsYW5Db250cm9sbGVyJ1xyXG5cclxuICAuc3RhdGUgXCJzaW5nbGUtam9iLnBsYW4ub3ZlcnZpZXdcIixcclxuICAgIHVybDogXCJc
 IlxyXG4gICAgdmlld3M6XHJcbiAgICAgICdub2RlLWRldGFpbHMnOlxyXG4gICAgICAgIHRlbXBsYXRlVXJsOiBcInBhcnRpYWxzL2pvYnMvam9iLnBsYW4ubm9kZS1saXN0Lm92ZXJ2aWV3Lmh0bWxcIlxyXG4gICAgICAgIGNvbnRyb2xsZXI6ICdKb2JQbGFuT3ZlcnZpZXdDb250cm9sbGVyJyBcclxuXHJcbiAgLnN0YXRlIFwic2luZ2xlLWpvYi5wbGFuLmFjY3VtdWxhdG9yc1wiLFxyXG4gICAgdXJsOiBcIi9hY2N1bXVsYXRvcnNcIlxyXG4gICAgdmlld3M6XHJcbiAgICAgICdub2RlLWRldGFpbHMnOlxyXG4gICAgICAgIHRlbXBsYXRlVXJsOiBcInBhcnRpYWxzL2pvYnMvam9iLnBsYW4ubm9kZS1saXN0LmFjY3VtdWxhdG9ycy5odG1sXCJcclxuICAgICAgICBjb250cm9sbGVyOiAnSm9iUGxhbkFjY3VtdWxhdG9yc0NvbnRyb2xsZXInIFxyXG5cclxuICAuc3RhdGUgXCJzaW5nbGUtam9iLnRpbWVsaW5lXCIsXHJcbiAgICB1cmw6IFwiL3RpbWVsaW5lXCJcclxuICAgIHZpZXdzOlxyXG4gICAgICBkZXRhaWxzOlxyXG4gICAgICAgIHRlbXBsYXRlVXJsOiBcInBhcnRpYWxzL2pvYnMvam9iLnRpbWVsaW5lLmh0bWxcIlxyXG5cclxuICAuc3RhdGUgXCJzaW5nbGUtam9iLnRpbWVsaW5lLnZlcnRleFwiLFxyXG4gICAgdXJsOiBcIi97dmVydGV4SWR9XCJcclxuICAgIHZpZXdzOlxyXG4gICAgICB2ZXJ0ZXg6XHJcbiAgICAgICAgdGVtcGxhdGVVcmw6IFwicGFydGlhbHMvam9icy9qb2IudGltZWxpbmUudmVydGV4L
 mh0bWxcIlxyXG4gICAgICAgIGNvbnRyb2xsZXI6ICdKb2JUaW1lbGluZVZlcnRleENvbnRyb2xsZXInXHJcblxyXG4gIC5zdGF0ZSBcInNpbmdsZS1qb2Iuc3RhdGlzdGljc1wiLFxyXG4gICAgdXJsOiBcIi9zdGF0aXN0aWNzXCJcclxuICAgIHZpZXdzOlxyXG4gICAgICBkZXRhaWxzOlxyXG4gICAgICAgIHRlbXBsYXRlVXJsOiBcInBhcnRpYWxzL2pvYnMvam9iLnN0YXRpc3RpY3MuaHRtbFwiXHJcblxyXG4gIC5zdGF0ZSBcInNpbmdsZS1qb2IuZXhjZXB0aW9uc1wiLFxyXG4gICAgdXJsOiBcIi9leGNlcHRpb25zXCJcclxuICAgIHZpZXdzOlxyXG4gICAgICBkZXRhaWxzOlxyXG4gICAgICAgIHRlbXBsYXRlVXJsOiBcInBhcnRpYWxzL2pvYnMvam9iLmV4Y2VwdGlvbnMuaHRtbFwiXHJcbiAgICAgICAgY29udHJvbGxlcjogJ0pvYkV4Y2VwdGlvbnNDb250cm9sbGVyJ1xyXG5cclxuICAuc3RhdGUgXCJzaW5nbGUtam9iLnByb3BlcnRpZXNcIixcclxuICAgIHVybDogXCIvcHJvcGVydGllc1wiXHJcbiAgICB2aWV3czpcclxuICAgICAgZGV0YWlsczpcclxuICAgICAgICB0ZW1wbGF0ZVVybDogXCJwYXJ0aWFscy9qb2JzL2pvYi5wcm9wZXJ0aWVzLmh0bWxcIlxyXG4gICAgICAgIGNvbnRyb2xsZXI6ICdKb2JQcm9wZXJ0aWVzQ29udHJvbGxlcidcclxuXHJcbiAgLnN0YXRlIFwic2luZ2xlLWpvYi5jb25maWdcIixcclxuICAgIHVybDogXCIvY29uZmlnXCJcclxuICAgIHZpZXdzOlxyXG4gICAgICBkZXRhaWxzOl
 xyXG4gICAgICAgIHRlbXBsYXRlVXJsOiBcInBhcnRpYWxzL2pvYnMvam9iLmNvbmZpZy5odG1sXCJcclxuXHJcbiAgLnN0YXRlIFwiYWxsLW1hbmFnZXJcIixcclxuICAgIHVybDogXCIvdGFza21hbmFnZXJzXCJcclxuICAgIHZpZXdzOlxyXG4gICAgICBtYWluOlxyXG4gICAgICAgIHRlbXBsYXRlVXJsOiBcInBhcnRpYWxzL3Rhc2ttYW5hZ2VyL2luZGV4Lmh0bWxcIlxyXG4gICAgICAgIGNvbnRyb2xsZXI6ICdBbGxUYXNrTWFuYWdlcnNDb250cm9sbGVyJ1xyXG5cclxuICAuc3RhdGUgXCJzaW5nbGUtbWFuYWdlclwiLFxyXG4gICAgICB1cmw6IFwiL3Rhc2ttYW5hZ2VyL3t0YXNrbWFuYWdlcmlkfVwiXHJcbiAgICAgIHZpZXdzOlxyXG4gICAgICAgIG1haW46XHJcbiAgICAgICAgICB0ZW1wbGF0ZVVybDogXCJwYXJ0aWFscy90YXNrbWFuYWdlci90YX

<TRUNCATED>

Mime
View raw message