diff --git a/.gitignore b/.gitignore
index aa8b207dbbb31..43253f2328376 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,3 +50,6 @@ network_closure.sh
.kubeconfig
.tags*
+
+# Web UI
+www/master/node_modules/
diff --git a/hack/build-ui.sh b/hack/build-ui.sh
index d38715b60b145..647bd5fff5c6a 100755
--- a/hack/build-ui.sh
+++ b/hack/build-ui.sh
@@ -33,7 +33,7 @@ fi
DATAFILE=pkg/ui/datafile.go
TMP_DATAFILE=/tmp/datafile.go
-go-bindata -nocompress -o $DATAFILE -prefix ${PWD} -pkg ui www/... third_party/swagger-ui/...
+go-bindata -nocompress -o $DATAFILE -prefix ${PWD} -pkg ui www/app/... third_party/swagger-ui/...
cat hooks/boilerplate.go.txt > $TMP_DATAFILE
echo "// generated by hack/build-ui.sh; DO NOT EDIT
diff --git a/pkg/ui/datafile.go b/pkg/ui/datafile.go
index 5c77e6c7d01d9..bfb4d4b9b57ed 100644
--- a/pkg/ui/datafile.go
+++ b/pkg/ui/datafile.go
@@ -59,1437 +59,17711 @@ func (fi bindata_file_info) Sys() interface{} {
return nil
}
-var _www_box_ng = []byte(`
+
+`)
+
+func www_app_assets_img_icons_ic_menu_svg_bytes() ([]byte, error) {
+ return _www_app_assets_img_icons_ic_menu_svg, nil
+}
+
+func www_app_assets_img_icons_ic_menu_svg() (*asset, error) {
+ bytes, err := www_app_assets_img_icons_ic_menu_svg_bytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindata_file_info{name: "www/app/assets/img/icons/ic_menu.svg", size: 791, mode: os.FileMode(436), modTime: time.Unix(1429444413, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+var _www_app_assets_img_icons_ic_menu_24px_svg = []byte(`
+
+
+
+`)
+
+func www_app_assets_img_icons_ic_menu_24px_svg_bytes() ([]byte, error) {
+ return _www_app_assets_img_icons_ic_menu_24px_svg, nil
+}
+
+func www_app_assets_img_icons_ic_menu_24px_svg() (*asset, error) {
+ bytes, err := www_app_assets_img_icons_ic_menu_24px_svg_bytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindata_file_info{name: "www/app/assets/img/icons/ic_menu_24px.svg", size: 841, mode: os.FileMode(436), modTime: time.Unix(1429444413, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+var _www_app_assets_img_icons_list_control_down_png = []byte("\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x000\x00\x00\x000\b\x03\x00\x00\x00`\xdc\t\xb5\x00\x00\x00\x19tEXtSoftware\x00Adobe ImageReadyq\xc9e<\x00\x00\x00'PLTE\xa8\xa8\xa8\xfc\xfc\xfc\xc0\xc0\xc0\xb6\xb6\xb6\xf7\xf7\xf7\xaa\xaa\xaa\xf6\xf6\xf6\xe6\xe6\xe6\xe8\xe8赵\xb5\xc3\xc3\xc3\xe5\xe5\xe5\xff\xff\xffZLu\xde\x00\x00\x00\rtRNS\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00=\xe8\"\x86\x00\x00\x00\x8bIDATx\xda\xec\xd4I\x12\x80 \fD\xd1\x04\x04\x9c\xee\u007f^ˁ\xd2`\xb7\x96k\xc3\xd2\xfao\xa1\t\xca\xfc\xf1\x88\x03\a\xbf\x01}\xd7\x06\xb9\u007f\x02S\x8a\x8d\xc8C*\x1c\x94$bE\x1eD\xac0`\x14\xb1\"\xc7\xf5\xc9H\x81\x06+\xba\xad\x0f\xca\xdf\xc1\nԷ_\xe9*`\u007f\x9b\xc3)p\u007f\x1f\\\x15\xa4\a\x93>\x04\xe9\xd1j\xec\x82\xf4p\x97\xaa@=^\xbe]\xc0\x9el\xeb*p\xcf\xd6[\x03\xe9\xe9}P\xf5\x9f\x80\x03\a\xafg\x11`\x00\xb0\xe4e\a\x17\x87\xea}\x00\x00\x00\x00IEND\xaeB`\x82")
+
+func www_app_assets_img_icons_list_control_down_png_bytes() ([]byte, error) {
+ return _www_app_assets_img_icons_list_control_down_png, nil
+}
+
+func www_app_assets_img_icons_list_control_down_png() (*asset, error) {
+ bytes, err := www_app_assets_img_icons_list_control_down_png_bytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindata_file_info{name: "www/app/assets/img/icons/list_control_down.png", size: 309, mode: os.FileMode(436), modTime: time.Unix(1429444413, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+var _www_app_assets_img_kubernetes_svg = []byte(`
+`)
+
+func www_app_assets_img_kubernetes_svg_bytes() ([]byte, error) {
+ return _www_app_assets_img_kubernetes_svg, nil
+}
+
+func www_app_assets_img_kubernetes_svg() (*asset, error) {
+ bytes, err := www_app_assets_img_kubernetes_svg_bytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindata_file_info{name: "www/app/assets/img/kubernetes.svg", size: 11663, mode: os.FileMode(436), modTime: time.Unix(1429444413, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+var _www_app_assets_js_gitkeep = []byte(``)
+
+func www_app_assets_js_gitkeep_bytes() ([]byte, error) {
+ return _www_app_assets_js_gitkeep, nil
+}
+
+func www_app_assets_js_gitkeep() (*asset, error) {
+ bytes, err := www_app_assets_js_gitkeep_bytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindata_file_info{name: "www/app/assets/js/.gitkeep", size: 0, mode: os.FileMode(436), modTime: time.Unix(1429444413, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+var _www_app_assets_js_app_js = []byte(`var componentNamespaces = ["kubernetesApp.components.dashboard"];
+// APP START
+// ****************************
+// /www/app/assets/app.js is autogenerated. Do not modify.
+// Changes should be made in /master/modules/js or /master/components//js
+// ****************************
+// -----------------------------------
+
+var app = angular.module('kubernetesApp', [
+ 'ngRoute',
+ 'ngMaterial',
+ 'ngLodash',
+ 'door3.css',
+ 'kubernetesApp.config',
+ 'kubernetesApp.services',
+ 'angular.filter'
+].concat(componentNamespaces));
+
+angular.module('kubernetesApp.config', []);
+angular.module('kubernetesApp.services', ['kubernetesApp.config']);
+
+app.config([
+ '$routeProvider',
+ function($routeProvider) {
+ $routeProvider.when("/404", {templateUrl: "views/partials/404.html"})
+ // else 404
+ .otherwise({redirectTo: "/404"});
+ }
+])
+ .config([
+ '$routeProvider',
+ 'manifestRoutes',
+ function($routeProvider, manifestRoutes) {
+ angular.forEach(manifestRoutes, function(r) {
+ var route = {
+ templateUrl: r.templateUrl
+ };
+ if (r.controller) {
+ route.controller = r.controller;
+ }
+ if (r.css) {
+ route.css = r.css;
+ }
+ $routeProvider.when(r.url, route);
+ });
+ }
+ ]);
+
+app.directive('includeReplace',
+ function() {
+ 'use strict';
+ return {
+ require: 'ngInclude',
+ restrict: 'A', /* optional */
+ link: function(scope, el, attrs) { el.replaceWith(el.children()); }
+ };
+ })
+ .directive('compile',
+ ["$compile", function($compile) {
+ 'use strict';
+ return function(scope, element, attrs) {
+ scope.$watch(function(scope) { return scope.$eval(attrs.compile); },
+ function(value) {
+ element.html(value);
+ $compile(element.contents())(scope);
+ });
+ };
+ }])
+ .directive("kubernetesUiMenu",
+ function() {
+ 'use strict';
+ return {
+ templateUrl: "views/partials/kubernetes-ui-menu.tmpl.html"
+ };
+ })
+ .directive('menuToggle', function() {
+ 'use strict';
+ return {
+ scope: {section: '='},
+ templateUrl: 'views/partials/menu-toggle.tmpl.html',
+ link: function($scope, $element) {
+ var controller = $element.parent().controller();
+
+ $scope.isOpen = function() { return controller.isOpen($scope.section); };
+ $scope.toggle = function() { controller.toggleOpen($scope.section); };
+
+ var parentNode = $element[0].parentNode.parentNode.parentNode;
+ if (parentNode.classList.contains('parent-list-item')) {
+ var heading = parentNode.querySelector('h2');
+ $element[0].firstChild.setAttribute('aria-describedby', heading.id);
+ }
+ }
+ };
+ });
+
+app.filter('startFrom',
+ function() {
+ 'use strict';
+ return function(input, start) { return input.slice(start); };
+ })
+ .filter('nospace', function() {
+ 'use strict';
+ return function(value) { return (!value) ? '' : value.replace(/ /g, ''); };
+ });
+
+app.run(['$route', angular.noop])
+ .run(["lodash", function(lodash) {
+ // Alias lodash
+ window['_'] = lodash;
+ }]);
+
+app.service('SidebarService', [
+ '$rootScope',
+ function($rootScope) {
+ var service = this;
+ service.sidebarItems = [];
+
+ service.clearSidebarItems = function() { service.sidebarItems = []; };
+
+ service.renderSidebar = function() {
+ var _entries = '';
+ service.sidebarItems.forEach(function(entry) { _entries += entry.Html; });
+
+ if (_entries) {
+ $rootScope.sidenavLeft = '' + _entries + '
';
+ }
+ };
+
+ service.addSidebarItem = function(item) {
+
+ service.sidebarItems.push(item);
+
+ service.sidebarItems.sort(function(a, b) { return (a.order > b.order) ? 1 : ((b.order > a.order) ? -1 : 0); });
+ };
+ }
+]);
+
+
+app.value("tabs", [{"component":"dashboard","title":"Dashboard"}]);
+app.constant("manifestRoutes", [{"description":"Dashboard visualization.","url":"/dashboard/","templateUrl":"components/dashboard/pages/home.html"},{"description":"Pods","url":"/dashboard/pods","templateUrl":"components/dashboard/views/listPods.html"},{"description":"Pod Visualizer","url":"/dashboard/visualpods","templateUrl":"components/dashboard/views/listPodsVisualizer.html"},{"description":"Services","url":"/dashboard/services","templateUrl":"components/dashboard/views/listServices.html"},{"description":"Replication Controllers","url":"/dashboard/replicationcontrollers","templateUrl":"components/dashboard/views/listReplicationControllers.html"},{"description":"Events","url":"/dashboard/events","templateUrl":"components/dashboard/views/listEvents.html"},{"description":"Minions","url":"/dashboard/minions","templateUrl":"components/dashboard/views/listMinions.html"},{"description":"Replication Controller","url":"/dashboard/replicationcontrollers/:replicationControllerId","templateUrl":"components/dashboard/views/replication.html"},{"description":"Service","url":"/dashboard/services/:serviceId","templateUrl":"components/dashboard/views/service.html"},{"description":"Explore","url":"/dashboard/groups/:grouping*?/selector/:selector*?","templateUrl":"components/dashboard/views/groups.html"},{"description":"Pod","url":"/dashboard/pods/:podId","templateUrl":"components/dashboard/views/pod.html"}]);
+
+angular.module("kubernetesApp.config", [])
+
+.constant("ENV", {
+ "/": {
+ "k8sApiServer": "/api/v1beta2",
+ "k8sDataServer": "/cluster",
+ "k8sDataPollMinIntervalSec": 10,
+ "k8sDataPollMaxIntervalSec": 120,
+ "k8sDataPollErrorThreshold": 5,
+ "cAdvisorProxy": "",
+ "cAdvisorPort": "4194"
+ }
+})
+
+.constant("ngConstant", true)
+
+;
+/**=========================================================
+ * Module: config.js
+ * App routes and resources configuration
+ =========================================================*/
+/**=========================================================
+ * Module: constants.js
+ * Define constants to inject across the application
+ =========================================================*/
+/**=========================================================
+ * Module: main.js
+ * Main Application Controller
+ =========================================================*/
+/**=========================================================
+ * Module: tabs-global.js
+ * Page Controller
+ =========================================================*/
+
+app.controller('TabCtrl', [
+ '$scope',
+ '$location',
+ 'tabs',
+ function($scope, $location, tabs) {
+ $scope.tabs = tabs;
+
+ $scope.switchTab = function(index) {
+ var location_path = $location.path();
+ var tab = tabs[index];
+
+ if (tab) {
+ var path = '/%s'.format(tab.component);
+ if (location_path.indexOf(path) == -1) {
+ $location.path(path);
+ }
+ }
+ };
+ }
+]);
+
+/**=========================================================
+ * Module: sidebar.js
+ * Wraps the sidebar and handles collapsed state
+ =========================================================*/
+(function() {
+ "use strict";
+
+ angular.module('kubernetesApp.services')
+ .service('cAdvisorService', ["$http", "$q", "ENV", function($http, $q, ENV) {
+ var _baseUrl = function(minionIp) {
+ var minionPort = ENV['/']['cAdvisorPort'] || "8081";
+ var proxy = ENV['/']['cAdvisorProxy'] || "/api/v1beta2/proxy/nodes/";
+
+ return proxy + minionIp + ':' + minionPort + '/api/v1.0/';
+ };
+
+ this.getMachineInfo = getMachineInfo;
+
+ function getMachineInfo(minionIp) {
+ var fullUrl = _baseUrl(minionIp) + 'machine';
+ var deferred = $q.defer();
+
+ // hack
+ $http.get(fullUrl).success(function(data) {
+ deferred.resolve(data);
+ }).error(function(data, status) { deferred.reject('There was an error') });
+ return deferred.promise;
+ }
+
+ this.getContainerInfo = getContainerInfo;
+ // containerId optional
+ function getContainerInfo(minionIp, containerId) {
+ containerId = (typeof containerId === "undefined") ? "/" : containerId;
+
+ var fullUrl = _baseUrl(minionIp) + 'containers' + containerId;
+ var deferred = $q.defer();
+
+ var request = {
+ "num_stats": 10,
+ "num_samples": 0
+ };
+
+ $http.post(fullUrl, request)
+ .success(function(data) { deferred.resolve(data); })
+ .error(function() { deferred.reject('There was an error') });
+ return deferred.promise;
+ }
+
+ this.getDataForMinion = function(minionIp) {
+ var machineData, containerData;
+ var deferred = $q.defer();
+
+ var p = $q.all([getMachineInfo(minionIp), getContainerInfo(minionIp)])
+ .then(
+ function(dataArray) {
+ machineData = dataArray[0];
+ containerData = dataArray[1];
+
+ var memoryData = parseMemory(machineData, containerData);
+ var cpuData = parseCpu(machineData, containerData);
+ var fsData = parseFilesystems(machineData, containerData);
+ deferred.resolve({
+ memoryData: memoryData,
+ cpuData: cpuData,
+ filesystemData: fsData,
+ machineData: machineData,
+ containerData: containerData
+ });
+
+ },
+ function(errorData) { deferred.reject(errorData); });
+
+ return deferred.promise;
+ };
+
+ // Utils to process cadvisor data
+ function humanize(num, size, units) {
+ var unit;
+ for (unit = units.pop(); units.length && num >= size; unit = units.pop()) {
+ num /= size;
+ }
+ return [num, unit];
+ }
+
+ // Following the IEC naming convention
+ function humanizeIEC(num) {
+ var ret = humanize(num, 1024, ["TiB", "GiB", "MiB", "KiB", "Bytes"]);
+ return ret[0].toFixed(2) + " " + ret[1];
+ }
+
+ // Following the Metric naming convention
+ function humanizeMetric(num) {
+ var ret = humanize(num, 1000, ["TB", "GB", "MB", "KB", "Bytes"]);
+ return ret[0].toFixed(2) + " " + ret[1];
+ }
+
+ function hasResource(stats, resource) { return stats.stats.length > 0 && stats.stats[0][resource]; }
+
+ // Gets the length of the interval in nanoseconds.
+ function getInterval(current, previous) {
+ var cur = new Date(current);
+ var prev = new Date(previous);
+
+ // ms -> ns.
+ return (cur.getTime() - prev.getTime()) * 1000000;
+ }
+
+ function parseCpu(machineInfo, containerInfo) {
+ var cur = containerInfo.stats[containerInfo.stats.length - 1];
+ var results = [];
+
+ var cpuUsage = 0;
+ if (containerInfo.spec.has_cpu && containerInfo.stats.length >= 2) {
+ var prev = containerInfo.stats[containerInfo.stats.length - 2];
+ var rawUsage = cur.cpu.usage.total - prev.cpu.usage.total;
+ var intervalInNs = getInterval(cur.timestamp, prev.timestamp);
+
+ // Convert to millicores and take the percentage
+ cpuUsage = Math.round(((rawUsage / intervalInNs) / machineInfo.num_cores) * 100);
+ if (cpuUsage > 100) {
+ cpuUsage = 100;
+ }
+ }
+
+ return {
+ cpuPercentUsage: cpuUsage
+ };
+ }
+
+ function parseFilesystems(machineInfo, containerInfo) {
+ var cur = containerInfo.stats[containerInfo.stats.length - 1];
+ if (!cur.filesystem) {
+ return;
+ }
+
+ var filesystemData = [];
+ for (var i = 0; i < cur.filesystem.length; i++) {
+ var data = cur.filesystem[i];
+ var totalUsage = Math.floor((data.usage * 100.0) / data.capacity);
+
+ var f = {
+ device: data.device,
+ filesystemNumber: i + 1,
+ usage: data.usage,
+ usageDescription: humanizeMetric(data.usage),
+ capacity: data.capacity,
+ capacityDescription: humanizeMetric(data.capacity),
+ totalUsage: Math.floor((data.usage * 100.0) / data.capacity)
+ };
+
+ filesystemData.push(f);
+ }
+ return filesystemData;
+ }
+
+ var oneMegabyte = 1024 * 1024;
+ var oneGigabyte = 1024 * oneMegabyte;
+
+ function parseMemory(machineInfo, containerInfo) {
+ if (containerInfo.spec.has_memory && !hasResource(containerInfo, "memory")) {
+ return;
+ }
+
+ // var titles = ["Time", "Total", "Hot"];
+ var data = [];
+ for (var i = 0; i < containerInfo.stats.length; i++) {
+ var cur = containerInfo.stats[i];
+
+ var elements = [];
+ elements.push(cur.timestamp);
+ elements.push(cur.memory.usage / oneMegabyte);
+ elements.push(cur.memory.working_set / oneMegabyte);
+ data.push(elements);
+ }
+
+ // Get the memory limit, saturate to the machine size.
+ var memory_limit = machineInfo.memory_capacity;
+ if (containerInfo.spec.memory.limit && (containerInfo.spec.memory.limit < memory_limit)) {
+ memory_limit = containerInfo.spec.memory.limit;
+ }
+
+ var cur = containerInfo.stats[containerInfo.stats.length - 1];
+
+ var r = {
+ current: {
+ memoryUsage: cur.memory.usage,
+ workingMemoryUsage: cur.memory.working_set,
+ memoryLimit: memory_limit,
+ memoryUsageDescription: humanizeMetric(cur.memory.usage),
+ workingMemoryUsageDescription: humanizeMetric(cur.memory.working_set),
+ memoryLimitDescription: humanizeMetric(memory_limit)
+ },
+ historical: data
+ };
+
+ return r;
+ }
+ }]);
+})();
+
+app.provider('k8sApi',
+ function() {
+
+ var urlBase = '';
+
+ this.setUrlBase = function(value) { urlBase = value; };
+
+ var _get = function($http, baseUrl, query) {
+ var _fullUrl = baseUrl;
+ if (query !== undefined) {
+ _fullUrl += '/' + query;
+ }
+
+ return $http.get(_fullUrl);
+ };
+
+ this.$get = ["$http", "$q", function($http, $q) {
+ var api = {};
+
+ api.getUrlBase = function() { return urlBase; };
+
+ api.getPods = function(query) { return _get($http, urlBase + '/pods', query); };
+
+ api.getMinions = function(query) { return _get($http, urlBase + '/minions', query); };
+
+ api.getServices = function(query) { return _get($http, urlBase + '/services', query); };
+
+ api.getReplicationControllers = function(query) {
+ return _get($http, urlBase + '/replicationControllers', query)
+ };
+
+ api.getEvents = function(query) { return _get($http, urlBase + '/events', query); };
+
+ return api;
+ }];
+ })
+ .config(["k8sApiProvider", "ENV", function(k8sApiProvider, ENV) {
+ if (ENV && ENV['/'] && ENV['/']['k8sApiServer']) {
+ var proxy = ENV['/']['cAdvisorProxy'] || '';
+ k8sApiProvider.setUrlBase(proxy + ENV['/']['k8sApiServer']);
+ }
+ }]);
+
+(function() {
+ "use strict";
+
+ var pollK8sDataServiceProvider = function PollK8sDataServiceProvider(_) {
+ // A set of configuration controlling the polling behavior.
+ // Their values should be configured in the application before
+ // creating the service instance.
+
+ var useSampleData = false;
+ this.setUseSampleData = function(value) { useSampleData = value; };
+
+ var sampleDataFiles = ["shared/assets/sampleData1.json"];
+ this.setSampleDataFiles = function(value) { sampleDataFiles = value; };
+
+ var dataServer = "http://localhost:5555/cluster";
+ this.setDataServer = function(value) { dataServer = value; };
+
+ var pollMinIntervalSec = 10;
+ this.setPollMinIntervalSec = function(value) { pollMinIntervalSec = value; };
+
+ var pollMaxIntervalSec = 120;
+ this.setPollMaxIntervalSec = function(value) { pollMaxIntervalSec = value; };
+
+ var pollErrorThreshold = 5;
+ this.setPollErrorThreshold = function(value) { pollErrorThreshold = value; };
+
+ this.$get = function($http, $timeout) {
+ // Now the sequenceNumber will be used for debugging and verification purposes.
+ var k8sdatamodel = {
+ "data": undefined,
+ "sequenceNumber": 0,
+ "useSampleData": useSampleData
+ };
+ var pollingError = 0;
+ var promise = undefined;
+
+ // Implement fibonacci back off when the service is down.
+ var pollInterval = pollMinIntervalSec;
+ var pollIncrement = pollInterval;
+
+ // Reset polling interval.
+ var resetCounters = function() {
+ pollInterval = pollMinIntervalSec;
+ pollIncrement = pollInterval;
+ };
+
+ // Bump error count and polling interval.
+ var bumpCounters = function() {
+ // Bump the error count.
+ pollingError++;
+
+ // TODO: maybe display an error in the UI to the end user.
+ if (pollingError % pollErrorThreshold === 0) {
+ console.log("Error: " + pollingError + " consecutive polling errors for " + dataServer + ".");
+ }
+
+ // Bump the polling interval.
+ var oldIncrement = pollIncrement;
+ pollIncrement = pollInterval;
+ pollInterval += oldIncrement;
+
+ // Reset when limit reached.
+ if (pollInterval > pollMaxIntervalSec) {
+ resetCounters();
+ }
+ };
+
+ var updateModel = function(newModel) {
+ var dedupe = function(dataModel) {
+ if (dataModel.resources) {
+ dataModel.resources = _.uniq(dataModel.resources, function(resource) { return resource.id; });
+ }
+
+ if (dataModel.relations) {
+ dataModel.relations =
+ _.uniq(dataModel.relations, function(relation) { return relation.source + relation.target; });
+ }
+ };
+
+ dedupe(newModel);
+
+ var newModelString = JSON.stringify(newModel);
+ var oldModelString = "";
+ if (k8sdatamodel.data) {
+ oldModelString = JSON.stringify(k8sdatamodel.data);
+ }
+
+ if (newModelString !== oldModelString) {
+ k8sdatamodel.data = newModel;
+ k8sdatamodel.sequenceNumber++;
+ }
+
+ pollingError = 0;
+ resetCounters();
+ };
+
+ var nextSampleDataFile = 0;
+ var getSampleDataFile = function() {
+ var result = "";
+ if (sampleDataFiles.length > 0) {
+ result = sampleDataFiles[nextSampleDataFile % sampleDataFiles.length];
+ ++nextSampleDataFile;
+ }
+
+ return result;
+ };
+
+ var pollOnce = function(scope, repeat) {
+ var dataSource = (k8sdatamodel.useSampleData) ? getSampleDataFile() : dataServer;
+ $.getJSON(dataSource)
+ .done(function(newModel, jqxhr, textStatus) {
+ if (newModel && newModel.success) {
+ delete newModel.success; // Remove success indicator.
+ delete newModel.timestamp; // Remove changing timestamp.
+ updateModel(newModel);
+ scope.$apply();
+ promise = repeat ? $timeout(function() { pollOnce(scope, true); }, pollInterval * 1000) : undefined;
+ return;
+ }
+
+ bumpCounters();
+ promise = repeat ? $timeout(function() { pollOnce(scope, true); }, pollInterval * 1000) : undefined;
+ })
+ .fail(function(jqxhr, textStatus, error) {
+ bumpCounters();
+ promise = repeat ? $timeout(function() { pollOnce(scope, true); }, pollInterval * 1000) : undefined;
+ });
+ };
+
+ var isPolling = function() { return promise ? true : false; };
+
+ var start = function(scope) {
+ // If polling has already started, then calling start() again would
+ // just reset the counters and polling interval, but it will not
+ // start a new thread polling in parallel to the existing polling
+ // thread.
+ resetCounters();
+ if (!promise) {
+ k8sdatamodel.data = undefined;
+ pollOnce(scope, true);
+ }
+ };
+
+ var stop = function() {
+ if (promise) {
+ $timeout.cancel(promise);
+ promise = undefined;
+ }
+ };
+
+ var refresh = function(scope) {
+ stop(scope);
+ resetCounters();
+ k8sdatamodel.data = undefined;
+ pollOnce(scope, false);
+ };
+
+ return {
+ "k8sdatamodel": k8sdatamodel,
+ "isPolling": isPolling,
+ "refresh": refresh,
+ "start": start,
+ "stop": stop
+ };
+ };
+ };
+
+ angular.module("kubernetesApp.services")
+ .provider("pollK8sDataService", ["lodash", pollK8sDataServiceProvider])
+ .config(["pollK8sDataServiceProvider", "ENV", function(pollK8sDataServiceProvider, ENV) {
+ if (ENV && ENV['/']) {
+ if (ENV['/']['k8sDataServer']) {
+ pollK8sDataServiceProvider.setDataServer(ENV['/']['k8sDataServer']);
+ }
+ if (ENV['/']['k8sDataPollIntervalMinSec']) {
+ pollK8sDataServiceProvider.setPollIntervalSec(ENV['/']['k8sDataPollIntervalMinSec']);
+ }
+ if (ENV['/']['k8sDataPollIntervalMaxSec']) {
+ pollK8sDataServiceProvider.setPollIntervalSec(ENV['/']['k8sDataPollIntervalMaxSec']);
+ }
+ if (ENV['/']['k8sDataPollErrorThreshold']) {
+ pollK8sDataServiceProvider.setPollErrorThreshold(ENV['/']['k8sDataPollErrorThreshold']);
+ }
+ }
+ }]);
+
+}());
+
+/**=========================================================
+ * Module: toggle-state.js
+ * Services to share toggle state functionality
+ =========================================================*/
+
+
+app.controller('cAdvisorController', [
+ '$scope',
+ '$routeParams',
+ 'k8sApi',
+ 'lodash',
+ 'cAdvisorService',
+ '$q',
+ '$interval',
+ function($scope, $routeParams, k8sApi, lodash, cAdvisorService, $q, $interval) {
+ $scope.k8sApi = k8sApi;
+
+ $scope.activeMinionDataById = {};
+ $scope.maxDataByById = {};
+
+ $scope.getData = function() {
+ $scope.loading = true;
+
+ k8sApi.getMinions().success(angular.bind(this, function(res) {
+ $scope.minions = res;
+ // console.log(res);
+ var promises = lodash.map(res.items, function(m) { return cAdvisorService.getDataForMinion(m.id); });
+
+ $q.all(promises).then(
+ function(dataArray) {
+ lodash.each(dataArray, function(data, i) {
+ var m = res.items[i];
+
+ var maxData = maxMemCpuInfo(m.id, data.memoryData, data.cpuData, data.filesystemData);
+
+ // console.log("maxData", maxData);
+
+ $scope.activeMinionDataById[m.id] =
+ transformMemCpuInfo(data.memoryData, data.cpuData, data.filesystemData, maxData, m.hostIP)
+ });
+
+ },
+ function(errorData) {
+ // console.log("Error: " + errorData);
+ $scope.loading = false;
+ });
+
+ $scope.loading = false;
+ })).error(angular.bind(this, this.handleError));
+ };
+
+ function getcAdvisorDataForMinion(m) {
+ var p = cAdvisorService.getDataForMinion(m.hostIP);
+ return p;
+ }
+
+ function handleError(data, status, headers, config) {
+ // console.log("Error (" + status + "): " + data);
+ $scope.loading = false;
+ };
+
+ // d3
+ function getColorForIndex(i, percentage) {
+ // var colors = ['red', 'blue', 'yellow', 'pink', 'purple', 'green', 'orange'];
+ // return colors[i];
+ var c = "color-" + (i + 1);
+ if (percentage && percentage >= 90)
+ c = c + ' color-critical';
+ else if (percentage && percentage >= 80)
+ c = c + ' color-warning';
+
+ return c;
+ }
+
+ function getMaxColorForIndex(i, percentage) {
+ // var colors = ['red', 'blue', 'yellow', 'pink', 'purple', 'green', 'orange'];
+ // return colors[i];
+ var c = "color-max-" + (i + 1);
+ if (percentage && percentage >= 90)
+ c = c + ' color-max-critical';
+ else if (percentage && percentage >= 80)
+ c = c + ' color-max-warning';
+
+ return c;
+ }
+
+ function maxMemCpuInfo(mId, mem, cpu, fsDataArray) {
+ if ($scope.maxDataByById[mId] === undefined) $scope.maxDataByById[mId] = {};
+
+ var currentMem = mem.current;
+ var currentCpu = cpu;
+
+ var items = [];
+
+ if ($scope.maxDataByById[mId]['cpu'] === undefined ||
+ $scope.maxDataByById[mId]['cpu'] < currentCpu.cpuPercentUsage) {
+ // console.log("New max cpu " + mId, $scope.maxDataByById[mId].cpu, currentCpu.cpuPercentUsage);
+ $scope.maxDataByById[mId]['cpu'] = currentCpu.cpuPercentUsage;
+ }
+ items.push({
+ maxValue: $scope.maxDataByById[mId]['cpu'],
+ maxTickClassNames: getColorForIndex(0, $scope.maxDataByById[mId]['cpu']),
+ maxClassNames: getMaxColorForIndex(0, $scope.maxDataByById[mId]['cpu'])
+ });
+
+ var memPercentage = Math.floor((currentMem.memoryUsage * 100.0) / currentMem.memoryLimit);
+ if ($scope.maxDataByById[mId]['mem'] === undefined || $scope.maxDataByById[mId]['mem'] < memPercentage)
+ $scope.maxDataByById[mId]['mem'] = memPercentage;
+ items.push({
+ maxValue: $scope.maxDataByById[mId]['mem'],
+ maxTickClassNames: getColorForIndex(1, $scope.maxDataByById[mId]['mem']),
+ maxClassNames: getMaxColorForIndex(1, $scope.maxDataByById[mId]['mem'])
+ });
+
+ for (var i = 0; i < fsDataArray.length; i++) {
+ var f = fsDataArray[i];
+ var fid = 'FS #' + f.filesystemNumber;
+ if ($scope.maxDataByById[mId][fid] === undefined || $scope.maxDataByById[mId][fid] < f.totalUsage)
+ $scope.maxDataByById[mId][fid] = f.totalUsage;
+ items.push({
+ maxValue: $scope.maxDataByById[mId][fid],
+ maxTickClassNames: getColorForIndex(2 + i, $scope.maxDataByById[mId][fid]),
+ maxClassNames: getMaxColorForIndex(2 + i, $scope.maxDataByById[mId][fid])
+ });
+ }
+
+ // console.log("Max Data is now " + mId, $scope.maxDataByById[mId]);
+ return items;
+ }
+
+ function transformMemCpuInfo(mem, cpu, fsDataArray, maxData, hostName) {
+ var currentMem = mem.current;
+ var currentCpu = cpu;
+
+ var items = [];
+
+ items.push({
+ label: 'CPU',
+ stats: currentCpu.cpuPercentUsage + '%',
+ value: currentCpu.cpuPercentUsage,
+ classNames: getColorForIndex(0, currentCpu.cpuPercentUsage),
+ maxData: maxData[0],
+ hostName: hostName
+ });
+
+ var memPercentage = Math.floor((currentMem.memoryUsage * 100.0) / currentMem.memoryLimit);
+ items.push({
+ label: 'Memory',
+ stats: currentMem.memoryUsageDescription + ' / ' + currentMem.memoryLimitDescription,
+ value: memPercentage,
+ classNames: getColorForIndex(1, memPercentage),
+ maxData: maxData[1],
+ hostName: hostName
+ });
+
+ for (var i = 0; i < fsDataArray.length; i++) {
+ var f = fsDataArray[i];
+
+ items.push({
+ label: 'FS #' + f.filesystemNumber,
+ stats: f.usageDescription + ' / ' + f.capacityDescription,
+ value: f.totalUsage,
+ classNames: getColorForIndex(2 + i, f.totalUsage),
+ maxData: maxData[2 + i],
+ hostName: hostName
+
+ });
+ }
+
+ var a = [];
+ var segments = {
+ segments: items
+ };
+ a.push(segments);
+ return a;
+ };
+
+ // end d3
+ var promise = $interval($scope.getData, 3000);
+
+ // Cancel interval on page changes
+ $scope.$on('$destroy', function() {
+ if (angular.isDefined(promise)) {
+ $interval.cancel(promise);
+ promise = undefined;
+ }
+ });
+
+ $scope.getData();
+
+ }
+]);
+
+/**=========================================================
+ * Module: Dashboard
+ * Visualizer for clusters
+ =========================================================*/
+
+app.controller('DashboardCtrl', ['$scope', function($scope) {}]);
+
+/**=========================================================
+ * Module: Group
+ * Visualizer for groups
+ =========================================================*/
+
+app.controller('GroupCtrl', [
+ '$scope',
+ '$route',
+ '$interval',
+ '$routeParams',
+ 'k8sApi',
+ '$rootScope',
+ '$location',
+ 'lodash',
+ function($scope, $route, $interval, $routeParams, k8sApi, $rootScope, $location, _) {
+ 'use strict';
+ $scope.doTheBack = function() { window.history.back(); };
+
+ $scope.capitalize = function(s) { return _.capitalize(s); };
+
+ $rootScope.doTheBack = $scope.doTheBack;
+
+ $scope.resetGroupLayout = function(group) { delete group.settings; };
+
+ $scope.handlePath = function(path) {
+ var parts = path.split("/");
+ // split leaves an empty string at the beginning.
+ parts = parts.slice(1);
+
+ if (parts.length === 0) {
+ return;
+ }
+ this.handleGroups(parts.slice(1));
+ };
+
+ $scope.getState = function(obj) { return Object.keys(obj)[0]; };
+
+ $scope.clearSelector = function(grouping) { $location.path("/dashboard/groups/" + grouping + "/selector/"); };
+
+ $scope.changeGroupBy = function() {
+ var grouping = $scope.selectedGroupBy;
+
+ var s = _.clone($location.search());
+ if ($scope.routeParams.grouping != grouping)
+ $location.path("/dashboard/groups/" + grouping + "/selector/").search(s);
+ };
+
+ $scope.createBarrier = function(count, callback) {
+ var barrier = count;
+ var barrierFunction = angular.bind(this, function(data) {
+ // JavaScript is single threaded so this is safe.
+ barrier--;
+ if (barrier === 0) {
+ if (callback) {
+ callback();
+ }
+ }
+ });
+ return barrierFunction;
+ };
+
+ $scope.handleGroups = function(parts, selector) {
+ $scope.groupBy = parts;
+ $scope.loading = true;
+ $scope.selector = selector;
+ var args = [];
+ var type = "";
+ if (selector && selector.length > 0) {
+ $scope.selectorPieces = selector.split(",");
+ var labels = [];
+ var fields = [];
+ for (var i = 0; i < $scope.selectorPieces.length; i++) {
+ var piece = $scope.selectorPieces[i];
+ if (piece[0] == '$') {
+ fields.push(piece.slice(2));
+ } else {
+ if (piece.indexOf("type=") === 0) {
+ var labelParts = piece.split("=");
+ if (labelParts.length > 1) {
+ type = labelParts[1];
+ }
+ } else {
+ labels.push(piece);
+ }
+ }
+ }
+ if (labels.length > 0) {
+ args.push("labels=" + encodeURI(labels.join(",")));
+ }
+ if (fields.length > 0) {
+ args.push("fields=" + encodeURI(fields.join(",")));
+ }
+ }
+ var query = "?" + args.join("&");
+ var list = [];
+ var count = type.length > 0 ? 1 : 3;
+ var barrier = $scope.createBarrier(count, function() {
+ $scope.groups = $scope.groupData(list, 0);
+ $scope.loading = false;
+ $scope.groupByOptions = buildGroupByOptions();
+ $scope.selectedGroupBy = $routeParams.grouping;
+ });
+
+ if (type === "" || type == "pod") {
+ k8sApi.getPods(query).success(function(data) {
+ $scope.addLabel("type", "pod", data.items);
+ for (var i = 0; data.items && i < data.items.length; ++i) {
+ data.items[i].labels.host = data.items[i].currentState.host;
+ list.push(data.items[i]);
+ }
+ barrier();
+ }).error($scope.handleError);
+ }
+ if (type === "" || type == "service") {
+ k8sApi.getServices(query).success(function(data) {
+ $scope.addLabel("type", "service", data.items);
+ for (var i = 0; data.items && i < data.items.length; ++i) {
+ list.push(data.items[i]);
+ }
+ barrier();
+ }).error($scope.handleError);
+ }
+ if (type === "" || type == "replicationController") {
+ k8sApi.getReplicationControllers(query).success(angular.bind(this, function(data) {
+ $scope.addLabel("type", "replicationController", data.items);
+ for (var i = 0; data.items && i < data.items.length; ++i) {
+ list.push(data.items[i]);
+ }
+ barrier();
+ })).error($scope.handleError);
+ }
+ };
+
+ $scope.addLabel = function(key, value, items) {
+ if (!items) {
+ return;
+ }
+ for (var i = 0; i < items.length; i++) {
+ if (!items[i].labels) {
+ items[i].labels = [];
+ }
+ items[i].labels[key] = value;
+ }
+ };
+
+ $scope.groupData = function(items, index) {
+ var result = {
+ "items": {},
+ "kind": "grouping"
+ };
+ for (var i = 0; i < items.length; i++) {
+ key = items[i].labels[$scope.groupBy[index]];
+ if (!key) {
+ key = "";
+ }
+ var list = result.items[key];
+ if (!list) {
+ list = [];
+ result.items[key] = list;
+ }
+ list.push(items[i]);
+ }
+
+ if (index + 1 < $scope.groupBy.length) {
+ for (var key in result.items) {
+ result.items[key] = $scope.groupData(result.items[key], index + 1);
+ }
+ }
+ return result;
+ };
+ $scope.getGroupColor = function(type) {
+ if (type === 'pod') {
+ return '#6193F0';
+ } else if (type === 'replicationController') {
+ return '#E008FE';
+ } else if (type === 'service') {
+ return '#7C43FF';
+ }
+ };
+
+ var groups = $routeParams.grouping;
+ if (!groups) {
+ groups = '';
+ }
+
+ $scope.routeParams = $routeParams;
+ $scope.route = $route;
+
+ $scope.handleGroups(groups.split('/'), $routeParams.selector);
+
+ $scope.handleError = function(data, status, headers, config) {
+ console.log("Error (" + status + "): " + data);
+ $scope_.loading = false;
+ };
+
+ function getDefaultGroupByOptions() { return [{name: 'Type', value: 'type'}, {name: 'Name', value: 'name'}]; }
+
+ function buildGroupByOptions() {
+ var g = $scope.groups;
+ var options = getDefaultGroupByOptions();
+ var newOptions = _.map(g.items, function(vals) { return _.map(vals, function(v) { return _.keys(v.labels); }); });
+ newOptions =
+ _.reject(_.uniq(_.flattenDeep(newOptions)), function(o) { return o == 'name' || o == 'type' || o == ""; });
+ newOptions = _.map(newOptions, function(o) {
+ return {
+ name: o,
+ value: o
+ };
+ });
+
+ options = options.concat(newOptions);
+ return options;
+ }
+
+ $scope.changeFilterBy = function(selector) {
+ var grouping = $scope.selectedGroupBy;
+
+ var s = _.clone($location.search());
+ if ($scope.routeParams.selector != selector)
+ $location.path("/dashboard/groups/" + $scope.routeParams.grouping + "/selector/" + selector).search(s);
+ };
+ }
+]);
+
+/**=========================================================
+ * Module: Header
+ * Visualizer for clusters
+ =========================================================*/
+
+angular.module('kubernetesApp.components.dashboard', [])
+ .controller('HeaderCtrl', [
+ '$scope',
+ '$location',
+ function($scope, $location) {
+ 'use strict';
+ $scope.$watch('Pages', function(newValue, oldValue) {
+ if (typeof newValue !== 'undefined') {
+ $location.path(newValue);
+ }
+ });
+
+ $scope.subPages = [
+ {category: 'dashboard', name: 'Explore', value: '/dashboard/groups/type/selector/'},
+ {category: 'dashboard', name: 'Pods', value: '/dashboard/pods'},
+ {category: 'dashboard', name: 'Minions', value: '/dashboard/minions'},
+ {category: 'dashboard', name: 'Replication Controllers', value: '/dashboard/replicationcontrollers'},
+ {category: 'dashboard', name: 'Services', value: '/dashboard/services'},
+ {category: 'dashboard', name: 'Events', value: '/dashboard/events'}
+ ];
+ }
+ ]);
+
+/**=========================================================
+ * Module: List Events
+ * Visualizer list events
+ =========================================================*/
+
+app.controller('ListEventsCtrl', [
+ '$scope',
+ '$routeParams',
+ 'k8sApi',
+ '$location',
+ '$filter',
+ function($scope, $routeParams, k8sApi, $location, $filter) {
+ 'use strict';
+ $scope.getData = getData;
+ $scope.loading = true;
+ $scope.k8sApi = k8sApi;
+ $scope.pods = null;
+ $scope.groupedPods = null;
+ $scope.serverView = false;
+
+ $scope.headers = [
+ {name: 'Time', field: 'time'},
+ {name: 'From', field: 'from'},
+ {name: 'Sub Object Path', field: 'subobject'},
+ {name: 'Reason', field: 'reason'},
+ {name: 'Message', field: 'message'}
+ ];
+
+ $scope.custom = {
+ time: '',
+ from: 'grey',
+ subobject: 'grey',
+ reason: 'grey',
+ message: 'grey'
+ };
+ $scope.sortable = ['time', 'from', 'subobject'];
+ $scope.thumbs = 'thumb';
+ $scope.count = 10;
+
+ $scope.go = function(d) { $location.path('/dashboard/pods/' + d.id); };
+
+ $scope.moreClick = function(d, e) {
+ $location.path('/dashboard/pods/' + d.id);
+ e.stopPropagation();
+ };
+
+ function handleError(data, status, headers, config) {
+ console.log("Error (" + status + "): " + data);
+ $scope.loading = false;
+ }
+
+ $scope.content = [];
+
+ function getData(dataId) {
+ $scope.loading = true;
+ k8sApi.getEvents().success(function(data) {
+ $scope.loading = false;
+
+ var _fixComma = function(str) {
+ if (str.substring(0, 1) == ',') {
+ return str.substring(1);
+ } else {
+ return str;
+ }
+ };
+
+ data.items.forEach(function(event) {
+
+ $scope.content.push({
+ time: $filter('date')(event.timestamp, 'medium'),
+ from: event.source,
+ subobject: event.involvedObject.fieldPath,
+ reason: event.reason,
+ message: event.message
+ });
+
+ });
+
+ }).error($scope.handleError);
+ }
+
+ getData($routeParams.serviceId);
+
+ }
+]);
+
+/**=========================================================
+ * Module: Minions
+ * Visualizer for minions
+ =========================================================*/
+
+app.controller('ListMinionsCtrl', [
+ '$scope',
+ '$routeParams',
+ 'k8sApi',
+ '$location',
+ function($scope, $routeParams, k8sApi, $location) {
+ 'use strict';
+ $scope.getData = getData;
+ $scope.loading = true;
+ $scope.k8sApi = k8sApi;
+ $scope.pods = null;
+ $scope.groupedPods = null;
+ $scope.serverView = false;
+
+ $scope.headers = [{name: 'Name', field: 'name'}, {name: 'IP', field: 'ip'}, {name: 'Status', field: 'status'}];
+
+ $scope.custom = {
+ name: '',
+ status: 'grey',
+ ip: 'grey'
+ };
+ $scope.sortable = ['name', 'status', 'ip'];
+ $scope.thumbs = 'thumb';
+ $scope.count = 10;
+
+ $scope.go = function(d) { $location.path('/dashboard/pods/' + d.id); };
+
+ $scope.moreClick = function(d, e) {
+ $location.path('/dashboard/pods/' + d.id);
+ e.stopPropagation();
+ };
+
+ function handleError(data, status, headers, config) {
+ console.log("Error (" + status + "): " + data);
+ $scope.loading = false;
+ }
+
+ $scope.content = [];
+
+ function getData(dataId) {
+ $scope.loading = true;
+ k8sApi.getMinions().success(function(data) {
+ $scope.loading = false;
+
+ var _fixComma = function(str) {
+ if (str.substring(0, 1) == ',') {
+ return str.substring(1);
+ } else {
+ return str;
+ }
+ };
+
+ data.items.forEach(function(minion) {
+ var _kind = '';
+
+ if (minion.status.conditions) {
+ Object.keys(minion.status.conditions)
+ .forEach(function(key) { _kind += minion.status.conditions[key].kind; });
+ }
+
+ $scope.content.push({name: minion.id, ip: minion.hostIP, status: _kind});
+
+ });
+
+ }).error($scope.handleError);
+ }
+
+ getData($routeParams.serviceId);
+
+ }
+]);
+
+
+
+app.controller('ListPodsCtrl', [
+ '$scope',
+ '$routeParams',
+ 'k8sApi',
+ 'lodash',
+ '$location',
+ function($scope, $routeParams, k8sApi, lodash, $location) {
+ var _ = lodash;
+ $scope.getData = getData;
+ $scope.loading = true;
+ $scope.k8sApi = k8sApi;
+ $scope.pods = null;
+ $scope.groupedPods = null;
+ $scope.serverView = false;
+
+ $scope.headers = [
+ {name: '', field: 'thumb'},
+ {name: 'Pod', field: 'pod'},
+ {name: 'IP', field: 'ip'},
+ {name: 'Status', field: 'status'},
+ {name: 'Containers', field: 'containers'},
+ {name: 'Images', field: 'images'},
+ {name: 'Host', field: 'host'},
+ {name: 'Labels', field: 'labels'}
+ ];
+
+ $scope.custom = {
+ pod: '',
+ ip: 'grey',
+ containers: 'grey',
+ images: 'grey',
+ host: 'grey',
+ labels: 'grey',
+ status: 'grey'
+ };
+ $scope.sortable = ['pod', 'ip', 'status'];
+ $scope.thumbs = 'thumb';
+ $scope.count = 10;
+
+ $scope.go = function(d) { $location.path('/dashboard/pods/' + d.id); };
+
+ $scope.moreClick = function(d, e) {
+ $location.path('/dashboard/pods/' + d.id);
+ e.stopPropagation();
+ };
+
+ var orderedPodNames = [];
+
+ function handleError(data, status, headers, config) {
+ console.log("Error (" + status + "): " + data);
+ $scope.loading = false;
+ };
+
+ function getPodName(pod) { return _.has(pod.labels, 'name') ? pod.labels.name : pod.id; }
+
+ $scope.content = [];
+
+ function getData(dataId) {
+ $scope.loading = true;
+ k8sApi.getPods().success(angular.bind(this, function(data) {
+ $scope.loading = false;
+
+ var _fixComma = function(str) {
+ if (str.substring(0, 1) == ',') {
+ return str.substring(1);
+ } else {
+ return str;
+ }
+ };
+
+ data.items.forEach(function(pod) {
+ var _containers = '', _images = '', _labels = '', _uses = '';
+
+ if (pod.desiredState.manifest) {
+ Object.keys(pod.desiredState.manifest.containers)
+ .forEach(function(key) {
+ _containers += ', ' + pod.desiredState.manifest.containers[key].name;
+ _images += ', ' + pod.desiredState.manifest.containers[key].image;
+ });
+ }
+
+ Object.keys(pod.labels)
+ .forEach(function(key) {
+ if (key == 'name') {
+ _labels += ', ' + pod.labels[key];
+ }
+ if (key == 'uses') {
+ _uses += ', ' + pod.labels[key];
+ }
+ });
+
+ $scope.content.push({
+ thumb: '"assets/img/kubernetes.svg"',
+ pod: pod.id,
+ ip: pod.currentState.podIP,
+ containers: _fixComma(_containers),
+ images: _fixComma(_images),
+ host: pod.currentState.host,
+ labels: _fixComma(_labels) + ':' + _fixComma(_uses),
+ status: pod.currentState.status
+ });
+
+ });
+
+ })).error(angular.bind(this, handleError));
+ };
+
+ $scope.getPodRestarts = function(pod) {
+ var r = null;
+ var container = _.first(pod.desiredState.manifest.containers);
+ if (container) r = pod.currentState.info[container.name].restartCount;
+ return r;
+ };
+
+ $scope.otherLabels = function(labels) { return _.omit(labels, 'name') };
+
+ $scope.podStatusClass = function(pod) {
+
+ var s = pod.currentState.status.toLowerCase();
+
+ if (s == 'running' || s == 'succeeded')
+ return null;
+ else
+ return "status-" + s;
+ };
+
+ $scope.podIndexFromName = function(pod) {
+ var name = getPodName(pod);
+ return _.indexOf(orderedPodNames, name) + 1;
+ };
+
+ getData($routeParams.serviceId);
+
+ }
+]);
+
+/**=========================================================
+ * Module: Replication Controllers
+ * Visualizer for replication controllers
+ =========================================================*/
+
+app.controller('ListReplicationControllersCtrl', [
+ '$scope',
+ '$routeParams',
+ 'k8sApi',
+ '$location',
+ function($scope, $routeParams, k8sApi, $location) {
+ 'use strict';
+ $scope.getData = getData;
+ $scope.loading = true;
+ $scope.k8sApi = k8sApi;
+ $scope.pods = null;
+ $scope.groupedPods = null;
+ $scope.serverView = false;
+
+ $scope.headers = [
+ {name: 'Controller', field: 'controller'},
+ {name: 'Containers', field: 'containers'},
+ {name: 'Images', field: 'images'},
+ {name: 'Selector', field: 'selector'},
+ {name: 'Replicas', field: 'replicas'}
+ ];
+
+ $scope.custom = {
+ controller: '',
+ containers: 'grey',
+ images: 'grey',
+ selector: 'grey',
+ replicas: 'grey'
+ };
+ $scope.sortable = ['controller', 'containers', 'images'];
+ $scope.thumbs = 'thumb';
+ $scope.count = 10;
+
+ $scope.go = function(d) { $location.path('/dashboard/pods/' + d.id); };
+
+ $scope.moreClick = function(d, e) {
+ $location.path('/dashboard/pods/' + d.id);
+ e.stopPropagation();
+ };
+
+ function handleError(data, status, headers, config) {
+ console.log("Error (" + status + "): " + data);
+ $scope.loading = false;
+ }
+
+ $scope.content = [];
+
+ function getData(dataId) {
+ $scope.loading = true;
+ k8sApi.getReplicationControllers().success(function(data) {
+ $scope.loading = false;
+
+ var _fixComma = function(str) {
+ if (str.substring(0, 1) == ',') {
+ return str.substring(1);
+ } else {
+ return str;
+ }
+ };
+
+ data.items.forEach(function(replicationController) {
+
+ var _name = '', _image = '';
+
+ if (replicationController.desiredState.podTemplate.desiredState.manifest.containers) {
+ Object.keys(replicationController.desiredState.podTemplate.desiredState.manifest.containers)
+ .forEach(function(key) {
+ _name += replicationController.desiredState.podTemplate.desiredState.manifest.containers[key].name;
+ _image += replicationController.desiredState.podTemplate.desiredState.manifest.containers[key].image;
+ });
+ }
+
+ var _name_selector = '';
+
+ if (replicationController.desiredState.replicaSelector) {
+ Object.keys(replicationController.desiredState.replicaSelector)
+ .forEach(function(key) { _name_selector += replicationController.desiredState.replicaSelector[key]; });
+ }
+
+ $scope.content.push({
+ controller: replicationController.id,
+ containers: _name,
+ images: _image,
+ selector: _name_selector,
+ replicas: replicationController.currentState.replicas
+ });
+
+ });
+
+ }).error($scope.handleError);
+ }
+
+ getData($routeParams.serviceId);
+
+ }
+]);
+
+/**=========================================================
+ * Module: Services
+ * Visualizer for services
+ =========================================================*/
+
+app.controller('ListServicesCtrl', [
+ '$scope',
+ '$interval',
+ '$routeParams',
+ 'k8sApi',
+ '$rootScope',
+ function($scope, $interval, $routeParams, k8sApi, $rootScope) {
+ 'use strict';
+ $scope.doTheBack = function() { window.history.back(); };
+
+ $scope.headers = [
+ {name: 'Name', field: 'name'},
+ {name: 'Labels', field: 'labels'},
+ {name: 'Selector', field: 'selector'},
+ {name: 'IP', field: 'ip'},
+ {name: 'Port', field: 'port'}
+ ];
+
+ $scope.custom = {
+ name: '',
+ ip: 'grey',
+ selector: 'grey',
+ port: 'grey',
+ labels: 'grey'
+ };
+ $scope.sortable = ['name', 'ip', 'port'];
+ $scope.count = 10;
+
+ $scope.content = [];
+
+ $rootScope.doTheBack = $scope.doTheBack;
+
+ $scope.handleError = function(data, status, headers, config) {
+ console.log("Error (" + status + "): " + data);
+ $scope_.loading = false;
+ };
+
+ $scope.getData = function(dataId) {
+ $scope.loading = true;
+ k8sApi.getServices(dataId).success(angular.bind(this, function(data) {
+ $scope.services = data;
+ $scope.loading = false;
+
+ var _fixComma = function(str) {
+ if (str.substring(0, 1) == ',') {
+ return str.substring(1);
+ } else {
+ return str;
+ }
+ };
+
+ var addLabel = function(str, label) {
+ if (str) {
+ str = label + str;
+ }
+ return str;
+ };
+
+ if (data.items.constructor === Array) {
+ data.items.forEach(function(service) {
+
+ var _name = '', _uses = '', _component = '', _provider = '';
+
+ if (service.labels !== null && typeof service.labels === 'object') {
+ Object.keys(service.labels)
+ .forEach(function(key) {
+ if (key == 'name') {
+ _name += ',' + service.labels[key];
+ }
+ if (key == 'component') {
+ _component += ',' + service.labels[key];
+ }
+ if (key == 'provider') {
+ _provider += ',' + service.labels[key];
+ }
+ });
+ }
+
+ var _selectors = '';
+
+ if (service.selector !== null && typeof service.selector === 'object') {
+ Object.keys(service.selector)
+ .forEach(function(key) {
+ if (key == 'name') {
+ _selectors += ',' + service.selector[key];
+ }
+ });
+ }
+
+ $scope.content.push({
+ name: service.id,
+ ip: service.portalIP,
+ port: service.port,
+ selector: addLabel(_fixComma(_selectors), 'name='),
+ labels: addLabel(_fixComma(_name), 'name=') + ' ' + addLabel(_fixComma(_component), 'component=') + ' ' +
+ addLabel(_fixComma(_provider), 'provider=')
+ });
+ });
+ }
+ })).error($scope.handleError);
+ };
+
+ $scope.getData($routeParams.serviceId);
+ }
+]);
+
+/**=========================================================
+ * Module: Pods
+ * Visualizer for pods
+ =========================================================*/
+
+app.controller('PodCtrl', [
+ '$scope',
+ '$interval',
+ '$routeParams',
+ 'k8sApi',
+ '$rootScope',
+ function($scope, $interval, $routeParams, k8sApi, $rootScope) {
+ 'use strict';
+ $scope.doTheBack = function() { window.history.back(); };
+
+ $rootScope.doTheBack = $scope.doTheBack;
+
+ $scope.handleError = function(data, status, headers, config) {
+ console.log("Error (" + status + "): " + data);
+ $scope_.loading = false;
+ };
+
+ $scope.handlePod = function(podId) {
+ $scope.loading = true;
+ k8sApi.getPods(podId).success(angular.bind(this, function(data) {
+ $scope.pod = data;
+ $scope.loading = false;
+ })).error($scope.handleError);
+ };
+
+ $scope.handlePod($routeParams.podId);
+ }
+]);
+
+/**=========================================================
+ * Module: Replication
+ * Visualizer for replication controllers
+ =========================================================*/
+
+function ReplicationController() {
+}
+
+ReplicationController.prototype.getData = function(dataId) {
+ this.scope.loading = true;
+ this.k8sApi.getReplicationControllers(dataId).success(angular.bind(this, function(data) {
+ this.scope.replicationController = data;
+ this.scope.loading = false;
+ })).error(angular.bind(this, this.handleError));
+};
+
+ReplicationController.prototype.handleError = function(data, status, headers, config) {
+ console.log("Error (" + status + "): " + data);
+ this.scope.loading = false;
+};
+
+app.controller('ReplicationControllerCtrl', [
+ '$scope',
+ '$routeParams',
+ 'k8sApi',
+ function($scope, $routeParams, k8sApi) {
+ $scope.controller = new ReplicationController();
+ $scope.controller.k8sApi = k8sApi;
+ $scope.controller.scope = $scope;
+ $scope.controller.getData($routeParams.replicationControllerId);
+ }
+]);
+
+/**=========================================================
+ * Module: Services
+ * Visualizer for services
+ =========================================================*/
+
+function ServiceController() {
+}
+
+ServiceController.prototype.getData = function(dataId) {
+ this.scope.loading = true;
+ this.k8sApi.getServices(dataId).success(angular.bind(this, function(data) {
+ this.scope.service = data;
+ this.scope.loading = false;
+ })).error(angular.bind(this, this.handleError));
+};
+
+ServiceController.prototype.handleError = function(data, status, headers, config) {
+ console.log("Error (" + status + "): " + data);
+ this.scope.loading = false;
+};
+
+app.controller('ServiceCtrl', [
+ '$scope',
+ '$routeParams',
+ 'k8sApi',
+ '$location',
+ function($scope, $routeParams, k8sApi, $location) {
+ $scope.controller = new ServiceController();
+ $scope.controller.k8sApi = k8sApi;
+ $scope.controller.scope = $scope;
+ $scope.controller.getData($routeParams.serviceId);
+
+ $scope.go = function(d) { $location.path('/dashboard/services/' + d.id); }
+
+ $scope.moreClick = function(d, e) {
+ $location.path('/dashboard/services/' + d.id);
+ e.stopPropagation();
+ }
+ }
+]);
+
+(function() {
+ 'use strict';
+
+ angular.module('kubernetesApp.components.dashboard')
+ .directive('d3MinionBarGauge', [
+ 'd3DashboardService',
+ function(d3DashboardService) {
+
+ return {
+ restrict: 'E',
+ scope: {
+ data: '=',
+ thickness: '@',
+ graphWidth: '@',
+ graphHeight: '@'
+
+ },
+ link: function(scope, element, attrs) {
+
+ var draw = function(d3) {
+ var svg = d3.select("svg.chart");
+ var legendSvg = d3.select("svg.legend");
+ window.onresize = function() { return scope.$apply(); };
+
+ scope.$watch(function() { return angular.element(window)[0].innerWidth; },
+ function() { return scope.render(scope.data); });
+
+ scope.$watch('data', function(newVals, oldVals) {
+ return initOrUpdate(newVals, oldVals);
+
+ }, true);
+
+ function initOrUpdate(newVals, oldVals) {
+ if (oldVals === null || oldVals === undefined) {
+ return scope.render(newVals);
+ } else {
+ return update(oldVals, newVals);
+ }
+ }
+
+ var textOffset = 10;
+ var el = null;
+ var radius = 100;
+ var oldData = [];
+
+ function init(options) {
+ var clone = options.data;
+ var preparedData = setData(clone);
+ setup(preparedData, options.width, options.height);
+ }
+
+ function setup(data, w, h) {
+ svg = d3.select(element[0]).append("svg").attr("width", "100%");
+
+ legendSvg = d3.select(element[0]).append("svg").attr("width", "100%");
+
+ var chart = svg.attr("class", "chart")
+ .attr("width", w)
+ .attr("height", h - 25)
+ .append("svg:g")
+ .attr("class", "concentricchart")
+ .attr("transform", "translate(" + ((w / 2)) + "," + h / 4 + ")");
+
+ var legend = legendSvg.attr("class", "legend").attr("width", w);
+
+ radius = Math.min(w, h) / 2;
+
+ var hostName = legendSvg.append("text")
+ .attr("class", "hostName")
+ .attr("transform", "translate(" + ((w - 120) / 2) + "," + 15 + ")");
+
+ var label_legend_area = legendSvg.append("svg:g")
+ .attr("class", "label_legend_area")
+ .attr("transform", "translate(" + ((w - 185) / 2) + "," + 35 + ")");
+
+ var legend_group = label_legend_area.append("svg:g").attr("class", "legend_group");
+
+ var label_group = label_legend_area.append("svg:g")
+ .attr("class", "label_group")
+ .attr("transform", "translate(" + 25 + "," + 11 + ")");
+
+ var stats_group = label_legend_area.append("svg:g")
+ .attr("class", "stats_group")
+ .attr("transform", "translate(" + 85 + "," + 11 + ")");
+
+ var path_group = chart.append("svg:g")
+ .attr("class", "path_group")
+ .attr("transform", "translate(0," + (h / 4) + ")");
+ var value_group = chart.append("svg:g")
+ .attr("class", "value_group")
+ .attr("transform", "translate(" + -(w * 0.205) + "," + -(h * 0.10) + ")");
+ generateArcs(chart, data);
+ }
+
+ function update(_oldData, _newData) {
+ if (_newData === undefined || _newData === null) {
+ return;
+ }
+
+ var clone = jQuery.extend(true, {}, _newData);
+ var cloneOld = jQuery.extend(true, {}, _oldData);
+ var preparedData = setData(clone);
+ oldData = setData(cloneOld);
+ animate(preparedData);
+ }
+
+ function animate(data) { generateArcs(null, data); }
+
+ function setData(data) {
+ var diameter = 2 * Math.PI * radius;
+ var localData = [];
+
+ $.each(data[0].segments, function(ri, value) {
+
+ function calcAngles(v) {
+ var segmentValueSum = 200;
+ if (v > segmentValueSum) {
+ v = segmentValueSum;
+ }
+
+ var segmentValue = v;
+ var fraction = segmentValue / segmentValueSum;
+ var arcBatchLength = fraction * 4 * Math.PI;
+ var arcPartition = arcBatchLength;
+ var startAngle = Math.PI * 2;
+ var endAngle = startAngle + arcPartition;
+
+ return {
+ startAngle: startAngle,
+ endAngle: endAngle
+ };
+ }
+
+ var valueData = calcAngles(value.value);
+ data[0].segments[ri].startAngle = valueData.startAngle;
+ data[0].segments[ri].endAngle = valueData.endAngle;
+
+ var maxData = value.maxData;
+ var maxTickData = calcAngles(maxData.maxValue + 0.2);
+ data[0].segments[ri].maxTickStartAngle = maxTickData.startAngle;
+ data[0].segments[ri].maxTickEndAngle = maxTickData.endAngle;
+
+ var maxArcData = calcAngles(maxData.maxValue);
+ data[0].segments[ri].maxArcStartAngle = maxArcData.startAngle;
+ data[0].segments[ri].maxArcEndAngle = maxArcData.endAngle;
+
+ data[0].segments[ri].index = ri;
+ });
+ localData.push(data[0].segments);
+ return localData[0];
+ }
+
+ function generateArcs(_svg, data) {
+ var chart = svg;
+ var transitionTime = 750;
+ $.each(data, function(index, value) {
+ if (oldData[index] !== undefined) {
+ data[index].previousEndAngle = oldData[index].endAngle;
+ } else {
+ data[index].previousEndAngle = 0;
+ }
+ });
+ var thickness = parseInt(scope.thickness, 10);
+ var ir = (parseInt(scope.graphWidth, 10) / 3);
+ var path_group = svg.select('.path_group');
+ var arc_group = path_group.selectAll(".arc_group").data(data);
+ var arcEnter = arc_group.enter().append("g").attr("class", "arc_group");
+
+ arcEnter.append("path").attr("class", "bg-circle").attr("d", getBackgroundArc(thickness, ir));
+
+ arcEnter.append("path")
+ .attr("class", function(d, i) { return 'max_tick_arc ' + d.maxData.maxTickClassNames; });
+
+ arcEnter.append("path")
+ .attr("class", function(d, i) { return 'max_bg_arc ' + d.maxData.maxClassNames; });
+
+ arcEnter.append("path").attr("class", function(d, i) { return 'value_arc ' + d.classNames; });
+
+ var max_tick_arc = arc_group.select(".max_tick_arc");
+
+ max_tick_arc.transition()
+ .attr("class", function(d, i) { return 'max_tick_arc ' + d.maxData.maxTickClassNames; })
+ .attr("d", function(d) {
+ var arc = maxArc(thickness, ir);
+ arc.startAngle(d.maxTickStartAngle);
+ arc.endAngle(d.maxTickEndAngle);
+ return arc(d);
+ });
+
+ var max_bg_arc = arc_group.select(".max_bg_arc");
+
+ max_bg_arc.transition()
+ .attr("class", function(d, i) { return 'max_bg_arc ' + d.maxData.maxClassNames; })
+ .attr("d", function(d) {
+ var arc = maxArc(thickness, ir);
+ arc.startAngle(d.maxArcStartAngle);
+ arc.endAngle(d.maxArcEndAngle);
+ return arc(d);
+ });
+
+ var value_arc = arc_group.select(".value_arc");
+
+ value_arc.transition().ease("exp").attr("class", function(d, i) {
+ return 'value_arc ' + d.classNames;
+ }).duration(transitionTime).attrTween("d", function(d) { return arcTween(d, thickness, ir); });
+
+ arc_group.exit()
+ .select(".value_arc")
+ .transition()
+ .ease("exp")
+ .duration(transitionTime)
+ .attrTween("d", function(d) { return arcTween(d, thickness, ir); })
+ .remove();
+
+ drawLabels(chart, data, ir, thickness);
+ buildLegend(chart, data);
+ }
+
+ function arcTween(b, thickness, ir) {
+ var prev = JSON.parse(JSON.stringify(b));
+ prev.endAngle = b.previousEndAngle;
+ var i = d3.interpolate(prev, b);
+ return function(t) { return getArc(thickness, ir)(i(t)); };
+ }
+
+ function maxArc(thickness, ir) {
+ var arc = d3.svg.arc().innerRadius(function(d) {
+ return getRadiusRing(ir, d.index);
+ }).outerRadius(function(d) { return getRadiusRing(ir + thickness, d.index); });
+ return arc;
+ }
+
+ function drawLabels(chart, data, ir, thickness) {
+ svg.select('.value_group').selectAll("*").remove();
+ var counts = data.length;
+ var value_group = chart.select('.value_group');
+ var valueLabels = value_group.selectAll("text.value").data(data);
+ valueLabels.enter()
+ .append("svg:text")
+ .attr("class", "value")
+ .attr(
+ "transform", function(d) { return "translate(" + (getRadiusRing(ir, counts - 1)) + ", 0)"; })
+ .attr("dx", function(d, i) { return 0; })
+ .attr("dy", function(d, i) { return (thickness + 3) * i; })
+ .attr("text-anchor", function(d) { return "start"; })
+ .text(function(d) { return d.value; });
+ valueLabels.transition().duration(300).attrTween(
+ "d", function(d) { return arcTween(d, thickness, ir); });
+ valueLabels.exit().remove();
+ }
+
+ function buildLegend(chart, data) {
+ var svg = legendSvg;
+ svg.select('.label_group').selectAll("*").remove();
+ svg.select('.legend_group').selectAll("*").remove();
+ svg.select('.stats_group').selectAll("*").remove();
+
+ var host_name = svg.select('.hostName');
+ var label_group = svg.select('.label_group');
+ var stats_group = svg.select('.stats_group');
+
+ host_name.text(data[0].hostName);
+
+ host_name = svg.selectAll("text.hostName").data(data);
+
+ host_name.attr("text-anchor", function(d) { return "start"; })
+ .text(function(d) { return d.hostName; });
+ host_name.exit().remove();
+
+ var labels = label_group.selectAll("text.labels").data(data);
+ labels.enter()
+ .append("svg:text")
+ .attr("class", "labels")
+ .attr("dy", function(d, i) { return 19 * i; })
+ .attr("text-anchor", function(d) { return "start"; })
+ .text(function(d) { return d.label; });
+ labels.exit().remove();
+
+ var stats = stats_group.selectAll("text.stats").data(data);
+ stats.enter()
+ .append("svg:text")
+ .attr("class", "stats")
+ .attr("dy", function(d, i) { return 19 * i; })
+ .attr("text-anchor", function(d) { return "start"; })
+ .text(function(d) { return d.stats; });
+ stats.exit().remove();
+
+ var legend_group = svg.select('.legend_group');
+ var legend = legend_group.selectAll("rect").data(data);
+ legend.enter()
+ .append("svg:rect")
+ .attr("x", 2)
+ .attr("y", function(d, i) { return 19 * i; })
+ .attr("width", 13)
+ .attr("height", 13)
+ .attr("class", function(d, i) { return "rect " + d.classNames; });
+
+ legend.exit().remove();
+ }
+
+ function getRadiusRing(ir, i) { return ir - (i * 20); }
+
+ function getArc(thickness, ir) {
+ var arc = d3.svg.arc()
+ .innerRadius(function(d) { return getRadiusRing(ir, d.index); })
+ .outerRadius(function(d) { return getRadiusRing(ir + thickness, d.index); })
+ .startAngle(function(d, i) { return d.startAngle; })
+ .endAngle(function(d, i) { return d.endAngle; });
+ return arc;
+ }
+
+ function getBackgroundArc(thickness, ir) {
+ var arc = d3.svg.arc()
+ .innerRadius(function(d) { return getRadiusRing(ir, d.index); })
+ .outerRadius(function(d) { return getRadiusRing(ir + thickness, d.index); })
+ .startAngle(0)
+ .endAngle(function() { return 2 * Math.PI; });
+ return arc;
+ }
+
+ scope.render = function(data) {
+ if (data === undefined || data === null) {
+ return;
+ }
+
+ svg.selectAll("*").remove();
+
+ var graph = $(element[0]);
+ var w = scope.graphWidth;
+ var h = scope.graphHeight;
+
+ var options = {
+ data: data,
+ width: w,
+ height: h
+ };
+
+ init(options);
+ };
+ };
+ d3DashboardService.d3().then(draw);
+ }
+ };
+ }
+ ]);
+}());
+
+(function() {
+ 'use strict';
+
+ angular.module('kubernetesApp.components.dashboard')
+ .directive(
+ 'dashboardHeader',
+ function() {
+ 'use strict';
+ return {
+ restrict: 'A',
+ replace: true,
+ scope: {user: '='},
+ templateUrl: "components/dashboard/pages/header.html",
+ controller: [
+ '$scope',
+ '$filter',
+ '$location',
+ '$rootScope',
+ function($scope, $filter, $location, $rootScope) {
+ $scope.$watch('page', function(newValue, oldValue) {
+ if (typeof newValue !== 'undefined') {
+ $location.path(newValue);
+ }
+ });
+
+ $scope.subpages = [
+ {
+ category: 'dashboard',
+ name: 'Groups',
+ value: '/dashboard/groups/type/selector/',
+ id: 'groupsView'
+ },
+ {category: 'dashboard', name: 'Pods', value: '/dashboard/pods', id: 'podsView'},
+ {category: 'dashboard', name: 'Minions', value: '/dashboard/minions', id: 'minionsView'},
+ {
+ category: 'dashboard',
+ name: 'Replication Controllers',
+ value: '/dashboard/replicationcontrollers',
+ id: 'rcView'
+ },
+ {category: 'dashboard', name: 'Services', value: '/dashboard/services', id: 'servicesView'},
+ {category: 'dashboard', name: 'Events', value: '/dashboard/events', id: 'eventsView'},
+ ];
+ }
+ ]
+ };
+ })
+ .directive('dashboardFooter',
+ function() {
+ 'use strict';
+ return {
+ restrict: 'A',
+ replace: true,
+ templateUrl: "components/dashboard/pages/footer.html",
+ controller: ['$scope', '$filter', function($scope, $filter) {}]
+ };
+ })
+ .directive('mdTable', function() {
+ 'use strict';
+ return {
+ restrict: 'E',
+ scope: {
+ headers: '=',
+ content: '=',
+ sortable: '=',
+ filters: '=',
+ customClass: '=customClass',
+ thumbs: '=',
+ count: '='
+ },
+ controller: ["$scope", "$filter", "$window", "$location", function($scope, $filter, $window, $location) {
+ var orderBy = $filter('orderBy');
+ $scope.currentPage = 0;
+ $scope.nbOfPages = function() { return Math.ceil($scope.content.length / $scope.count); };
+ $scope.handleSort = function(field) {
+ if ($scope.sortable.indexOf(field) > -1) {
+ return true;
+ } else {
+ return false;
+ }
+ };
+ $scope.go = function(d) {
+ if (d.pod) {
+ $location.path('/dashboard/pods/' + d.pod);
+ } else if (d.name) {
+ $location.path('/dashboard/services/' + d.name);
+ }
+ };
+ $scope.order = function(predicate, reverse) {
+ $scope.content = orderBy($scope.content, predicate, reverse);
+ $scope.predicate = predicate;
+ };
+ $scope.order($scope.sortable[0], false);
+ $scope.getNumber = function(num) { return new Array(num); };
+ $scope.goToPage = function(page) { $scope.currentPage = page; };
+ }],
+ templateUrl: 'views/partials/md-table.tmpl.html'
+ };
+ });
+
+}());
+
+angular.module('kubernetesApp.components.dashboard')
+ .factory('d3DashboardService', [
+ '$document',
+ '$q',
+ '$rootScope',
+ function($document, $q, $rootScope) {
+ var d = $q.defer();
+ function onScriptLoad() {
+ // Load client in the browser
+ $rootScope.$apply(function() { d.resolve(window.d3); });
+ }
+ // Create a script tag with d3 as the source
+ // and call our onScriptLoad callback when it
+ // has been loaded
+ var scriptTag = $document[0].createElement('script');
+ scriptTag.type = 'text/javascript';
+ scriptTag.async = true;
+ scriptTag.src = 'vendor/d3/d3.min.js';
+ scriptTag.onreadystatechange = function() {
+ if (this.readyState == 'complete') onScriptLoad();
+ };
+ scriptTag.onload = onScriptLoad;
+
+ var s = $document[0].getElementsByTagName('body')[0];
+ s.appendChild(scriptTag);
+
+ return {
+ d3: function() { return d.promise; }
+ };
+ }
+ ]);
+
+(function() {
+ 'use strict';
+
+ angular.module('pods', []).service('podService', PodDataService);
+
+ /**
+ * Pod DataService
+ * Mock async data service.
+ *
+ * @returns {{loadAll: Function}}
+ * @constructor
+ */
+ function PodDataService($q) {
+ var pods = {
+ "kind": "PodList",
+ "creationTimestamp": null,
+ "selfLink": "/api/v1beta1/pods",
+ "resourceVersion": 166552,
+ "apiVersion": "v1beta1",
+ "items": [{
+ "id": "hello",
+ "uid": "0fe3644e-ab53-11e4-8ae8-061695c59fcf",
+ "creationTimestamp": "2015-02-03T03:16:36Z",
+ "selfLink": "/api/v1beta1/pods/hello?namespace=default",
+ "resourceVersion": 466,
+ "namespace": "default",
+ "labels": {"environment": "testing", "name": "hello"},
+ "desiredState": {
+ "manifest": {
+ "version": "v1beta2",
+ "id": "",
+ "volumes": null,
+ "containers": [{
+ "name": "hello",
+ "image": "quay.io/kelseyhightower/hello",
+ "ports": [{"hostPort": 80, "containerPort": 80, "protocol": "TCP"}],
+ "imagePullPolicy": "PullIfNotPresent"
+ }],
+ "restartPolicy": {"always": {}},
+ "dnsPolicy": "ClusterFirst"
+ }
+ },
+ "currentState": {
+ "manifest": {"version": "", "id": "", "volumes": null, "containers": null, "restartPolicy": {}},
+ "status": "Running",
+ "host": "172.31.12.204",
+ "podIP": "10.244.73.2",
+ "info": {
+ "hello": {
+ "state": {"running": {"startedAt": "2015-02-03T03:16:51Z"}},
+ "restartCount": 0,
+ "image": "quay.io/kelseyhightower/hello",
+ "containerID": "docker://96ade8ff30a44c4489969eaf343a7899317671b07a9766ecd0963e9b41501256"
+ },
+ "net": {
+ "state": {"running": {"startedAt": "2015-02-03T03:16:41Z"}},
+ "restartCount": 0,
+ "podIP": "10.244.73.2",
+ "image": "kubernetes/pause:latest",
+ "containerID": "docker://93d32603cafbff7165dadb1d4527899c24246bca2f5e6770b8297fd3721b272c"
+ }
+ }
+ }
+ }]
+ };
+
+ // Uses promises
+ return {
+ loadAll: function() {
+ // Simulate async call
+ return $q.when(pods);
+ }
+ };
+ }
+ PodDataService.$inject = ["$q"];
+
+})();
+
+(function() {
+ 'use strict';
+
+ angular.module('replicationControllers', [])
+ .service('replicationControllerService', ReplicationControllerDataService);
+
+ /**
+ * Replication Controller DataService
+ * Mock async data service.
+ *
+ * @returns {{loadAll: Function}}
+ * @constructor
+ */
+ function ReplicationControllerDataService($q) {
+ var replicationControllers = {
+ "kind": "ReplicationControllerList",
+ "creationTimestamp": null,
+ "selfLink": "/api/v1beta1/replicationControllers",
+ "resourceVersion": 166552,
+ "apiVersion": "v1beta1",
+ "items": []
+ };
+
+ // Uses promises
+ return {
+ loadAll: function() {
+ // Simulate async call
+ return $q.when(replicationControllers);
+ }
+ };
+ }
+ ReplicationControllerDataService.$inject = ["$q"];
+
+})();
+
+(function() {
+ 'use strict';
+
+ angular.module('services', []).service('serviceService', ServiceDataService);
+
+ /**
+ * Service DataService
+ * Mock async data service.
+ *
+ * @returns {{loadAll: Function}}
+ * @constructor
+ */
+ function ServiceDataService($q) {
+ var services = {
+ "kind": "ServiceList",
+ "creationTimestamp": null,
+ "selfLink": "/api/v1beta1/services",
+ "resourceVersion": 166552,
+ "apiVersion": "v1beta1",
+ "items": [
+ {
+ "id": "kubernetes",
+ "uid": "626dd08d-ab51-11e4-8ae8-061695c59fcf",
+ "creationTimestamp": "2015-02-03T03:04:36Z",
+ "selfLink": "/api/v1beta1/services/kubernetes?namespace=default",
+ "resourceVersion": 11,
+ "namespace": "default",
+ "port": 443,
+ "protocol": "TCP",
+ "labels": {"component": "apiserver", "provider": "kubernetes"},
+ "selector": null,
+ "containerPort": 0,
+ "portalIP": "10.244.66.215",
+ "sessionAffinity": "None"
+ },
+ {
+ "id": "kubernetes-ro",
+ "uid": "626f9584-ab51-11e4-8ae8-061695c59fcf",
+ "creationTimestamp": "2015-02-03T03:04:36Z",
+ "selfLink": "/api/v1beta1/services/kubernetes-ro?namespace=default",
+ "resourceVersion": 12,
+ "namespace": "default",
+ "port": 80,
+ "protocol": "TCP",
+ "labels": {"component": "apiserver", "provider": "kubernetes"},
+ "selector": null,
+ "containerPort": 0,
+ "portalIP": "10.244.182.142",
+ "sessionAffinity": "None"
+ }
+ ]
+ };
+
+ // Uses promises
+ return {
+ loadAll: function() {
+ // Simulate async call
+ return $q.when(services);
+ }
+ };
+ }
+ ServiceDataService.$inject = ["$q"];
+
+})();
+`)
+
+func www_app_assets_js_app_js_bytes() ([]byte, error) {
+ return _www_app_assets_js_app_js, nil
+}
+
+func www_app_assets_js_app_js() (*asset, error) {
+ bytes, err := www_app_assets_js_app_js_bytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindata_file_info{name: "www/app/assets/js/app.js", size: 79552, mode: os.FileMode(436), modTime: time.Unix(1429574518, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+var _www_app_assets_js_base_js = []byte(`!function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){function n(e){var t=e.length,n=Z.type(e);return"function"===n||Z.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e}function r(e,t,n){if(Z.isFunction(t))return Z.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return Z.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(ae.test(t))return Z.filter(t,e,n);t=Z.filter(t,e)}return Z.grep(e,function(e){return U.call(t,e)>=0!==n})}function i(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function o(e){var t=he[e]={};return Z.each(e.match(de)||[],function(e,n){t[n]=!0}),t}function s(){J.removeEventListener("DOMContentLoaded",s,!1),e.removeEventListener("load",s,!1),Z.ready()}function a(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=Z.expando+a.uid++}function u(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(be,"-$1").toLowerCase(),n=e.getAttribute(r),"string"==typeof n){try{n="true"===n?!0:"false"===n?!1:"null"===n?null:+n+""===n?+n:xe.test(n)?Z.parseJSON(n):n}catch(i){}ye.set(e,t,n)}else n=void 0;return n}function l(){return!0}function c(){return!1}function f(){try{return J.activeElement}catch(e){}}function p(e,t){return Z.nodeName(e,"table")&&Z.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function d(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function h(e){var t=Pe.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function g(e,t){for(var n=0,r=e.length;r>n;n++)ve.set(e[n],"globalEval",!t||ve.get(t[n],"globalEval"))}function m(e,t){var n,r,i,o,s,a,u,l;if(1===t.nodeType){if(ve.hasData(e)&&(o=ve.access(e),s=ve.set(t,o),l=o.events)){delete s.handle,s.events={};for(i in l)for(n=0,r=l[i].length;r>n;n++)Z.event.add(t,i,l[i][n])}ye.hasData(e)&&(a=ye.access(e),u=Z.extend({},a),ye.set(t,u))}}function v(e,t){var n=e.getElementsByTagName?e.getElementsByTagName(t||"*"):e.querySelectorAll?e.querySelectorAll(t||"*"):[];return void 0===t||t&&Z.nodeName(e,t)?Z.merge([e],n):n}function y(e,t){var n=t.nodeName.toLowerCase();"input"===n&&Ne.test(e.type)?t.checked=e.checked:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}function x(t,n){var r,i=Z(n.createElement(t)).appendTo(n.body),o=e.getDefaultComputedStyle&&(r=e.getDefaultComputedStyle(i[0]))?r.display:Z.css(i[0],"display");return i.detach(),o}function b(e){var t=J,n=$e[e];return n||(n=x(e,t),"none"!==n&&n||(We=(We||Z("")).appendTo(t.documentElement),t=We[0].contentDocument,t.write(),t.close(),n=x(e,t),We.detach()),$e[e]=n),n}function w(e,t,n){var r,i,o,s,a=e.style;return n=n||_e(e),n&&(s=n.getPropertyValue(t)||n[t]),n&&(""!==s||Z.contains(e.ownerDocument,e)||(s=Z.style(e,t)),Be.test(s)&&Ie.test(t)&&(r=a.width,i=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=s,s=n.width,a.width=r,a.minWidth=i,a.maxWidth=o)),void 0!==s?s+"":s}function T(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function C(e,t){if(t in e)return t;for(var n=t[0].toUpperCase()+t.slice(1),r=t,i=Ge.length;i--;)if(t=Ge[i]+n,t in e)return t;return r}function N(e,t,n){var r=Xe.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function k(e,t,n,r,i){for(var o=n===(r?"border":"content")?4:"width"===t?1:0,s=0;4>o;o+=2)"margin"===n&&(s+=Z.css(e,n+Te[o],!0,i)),r?("content"===n&&(s-=Z.css(e,"padding"+Te[o],!0,i)),"margin"!==n&&(s-=Z.css(e,"border"+Te[o]+"Width",!0,i))):(s+=Z.css(e,"padding"+Te[o],!0,i),"padding"!==n&&(s+=Z.css(e,"border"+Te[o]+"Width",!0,i)));return s}function E(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=_e(e),s="border-box"===Z.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=w(e,t,o),(0>i||null==i)&&(i=e.style[t]),Be.test(i))return i;r=s&&(Q.boxSizingReliable()||i===e.style[t]),i=parseFloat(i)||0}return i+k(e,t,n||(s?"border":"content"),r,o)+"px"}function S(e,t){for(var n,r,i,o=[],s=0,a=e.length;a>s;s++)r=e[s],r.style&&(o[s]=ve.get(r,"olddisplay"),n=r.style.display,t?(o[s]||"none"!==n||(r.style.display=""),""===r.style.display&&Ce(r)&&(o[s]=ve.access(r,"olddisplay",b(r.nodeName)))):(i=Ce(r),"none"===n&&i||ve.set(r,"olddisplay",i?n:Z.css(r,"display"))));for(s=0;a>s;s++)r=e[s],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[s]||"":"none"));return e}function D(e,t,n,r,i){return new D.prototype.init(e,t,n,r,i)}function j(){return setTimeout(function(){Qe=void 0}),Qe=Z.now()}function A(e,t){var n,r=0,i={height:e};for(t=t?1:0;4>r;r+=2-t)n=Te[r],i["margin"+n]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function L(e,t,n){for(var r,i=(nt[t]||[]).concat(nt["*"]),o=0,s=i.length;s>o;o++)if(r=i[o].call(n,t,e))return r}function q(e,t,n){var r,i,o,s,a,u,l,c,f=this,p={},d=e.style,h=e.nodeType&&Ce(e),g=ve.get(e,"fxshow");n.queue||(a=Z._queueHooks(e,"fx"),null==a.unqueued&&(a.unqueued=0,u=a.empty.fire,a.empty.fire=function(){a.unqueued||u()}),a.unqueued++,f.always(function(){f.always(function(){a.unqueued--,Z.queue(e,"fx").length||a.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[d.overflow,d.overflowX,d.overflowY],l=Z.css(e,"display"),c="none"===l?ve.get(e,"olddisplay")||b(e.nodeName):l,"inline"===c&&"none"===Z.css(e,"float")&&(d.display="inline-block")),n.overflow&&(d.overflow="hidden",f.always(function(){d.overflow=n.overflow[0],d.overflowX=n.overflow[1],d.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],Ke.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(h?"hide":"show")){if("show"!==i||!g||void 0===g[r])continue;h=!0}p[r]=g&&g[r]||Z.style(e,r)}else l=void 0;if(Z.isEmptyObject(p))"inline"===("none"===l?b(e.nodeName):l)&&(d.display=l);else{g?"hidden"in g&&(h=g.hidden):g=ve.access(e,"fxshow",{}),o&&(g.hidden=!h),h?Z(e).show():f.done(function(){Z(e).hide()}),f.done(function(){var t;ve.remove(e,"fxshow");for(t in p)Z.style(e,t,p[t])});for(r in p)s=L(h?g[r]:0,r,f),r in g||(g[r]=s.start,h&&(s.end=s.start,s.start="width"===r||"height"===r?1:0))}}function H(e,t){var n,r,i,o,s;for(n in e)if(r=Z.camelCase(n),i=t[r],o=e[n],Z.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),s=Z.cssHooks[r],s&&"expand"in s){o=s.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}function O(e,t,n){var r,i,o=0,s=tt.length,a=Z.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;for(var t=Qe||j(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,s=0,u=l.tweens.length;u>s;s++)l.tweens[s].run(o);return a.notifyWith(e,[l,o,n]),1>o&&u?n:(a.resolveWith(e,[l]),!1)},l=a.promise({elem:e,props:Z.extend({},t),opts:Z.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Qe||j(),duration:n.duration,tweens:[],createTween:function(t,n){var r=Z.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)l.tweens[n].run(1);return t?a.resolveWith(e,[l,t]):a.rejectWith(e,[l,t]),this}}),c=l.props;for(H(c,l.opts.specialEasing);s>o;o++)if(r=tt[o].call(l,e,c,l.opts))return r;return Z.map(c,L,l),Z.isFunction(l.opts.start)&&l.opts.start.call(e,l),Z.fx.timer(Z.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function F(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(de)||[];if(Z.isFunction(n))for(;r=o[i++];)"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function P(e,t,n,r){function i(a){var u;return o[a]=!0,Z.each(e[a]||[],function(e,a){var l=a(t,n,r);return"string"!=typeof l||s||o[l]?s?!(u=l):void 0:(t.dataTypes.unshift(l),i(l),!1)}),u}var o={},s=e===xt;return i(t.dataTypes[0])||!o["*"]&&i("*")}function R(e,t){var n,r,i=Z.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&Z.extend(!0,e,r),e}function M(e,t,n){for(var r,i,o,s,a=e.contents,u=e.dataTypes;"*"===u[0];)u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in a)if(a[i]&&a[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}s||(s=i)}o=o||s}return o?(o!==u[0]&&u.unshift(o),n[o]):void 0}function W(e,t,n,r){var i,o,s,a,u,l={},c=e.dataTypes.slice();if(c[1])for(s in e.converters)l[s.toLowerCase()]=e.converters[s];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(s=l[u+" "+o]||l["* "+o],!s)for(i in l)if(a=i.split(" "),a[1]===o&&(s=l[u+" "+a[0]]||l["* "+a[0]])){s===!0?s=l[i]:l[i]!==!0&&(o=a[0],c.unshift(a[1]));break}if(s!==!0)if(s&&e["throws"])t=s(t);else try{t=s(t)}catch(f){return{state:"parsererror",error:s?f:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}function $(e,t,n,r){var i;if(Z.isArray(t))Z.each(t,function(t,i){n||Nt.test(e)?r(e,i):$(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==Z.type(t))r(e,t);else for(i in t)$(e+"["+i+"]",t[i],n,r)}function I(e){return Z.isWindow(e)?e:9===e.nodeType&&e.defaultView}var B=[],_=B.slice,z=B.concat,X=B.push,U=B.indexOf,V={},Y=V.toString,G=V.hasOwnProperty,Q={},J=e.document,K="2.1.3",Z=function(e,t){return new Z.fn.init(e,t)},ee=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,te=/^-ms-/,ne=/-([\da-z])/gi,re=function(e,t){return t.toUpperCase()};Z.fn=Z.prototype={jquery:K,constructor:Z,selector:"",length:0,toArray:function(){return _.call(this)},get:function(e){return null!=e?0>e?this[e+this.length]:this[e]:_.call(this)},pushStack:function(e){var t=Z.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return Z.each(this,e,t)},map:function(e){return this.pushStack(Z.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(_.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:X,sort:B.sort,splice:B.splice},Z.extend=Z.fn.extend=function(){var e,t,n,r,i,o,s=arguments[0]||{},a=1,u=arguments.length,l=!1;for("boolean"==typeof s&&(l=s,s=arguments[a]||{},a++),"object"==typeof s||Z.isFunction(s)||(s={}),a===u&&(s=this,a--);u>a;a++)if(null!=(e=arguments[a]))for(t in e)n=s[t],r=e[t],s!==r&&(l&&r&&(Z.isPlainObject(r)||(i=Z.isArray(r)))?(i?(i=!1,o=n&&Z.isArray(n)?n:[]):o=n&&Z.isPlainObject(n)?n:{},s[t]=Z.extend(l,o,r)):void 0!==r&&(s[t]=r));return s},Z.extend({expando:"jQuery"+(K+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isFunction:function(e){return"function"===Z.type(e)},isArray:Array.isArray,isWindow:function(e){return null!=e&&e===e.window},isNumeric:function(e){return!Z.isArray(e)&&e-parseFloat(e)+1>=0},isPlainObject:function(e){return"object"!==Z.type(e)||e.nodeType||Z.isWindow(e)?!1:e.constructor&&!G.call(e.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?V[Y.call(e)]||"object":typeof e},globalEval:function(e){var t,n=eval;e=Z.trim(e),e&&(1===e.indexOf("use strict")?(t=J.createElement("script"),t.text=e,J.head.appendChild(t).parentNode.removeChild(t)):n(e))},camelCase:function(e){return e.replace(te,"ms-").replace(ne,re)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,r){var i,o=0,s=e.length,a=n(e);if(r){if(a)for(;s>o&&(i=t.apply(e[o],r),i!==!1);o++);else for(o in e)if(i=t.apply(e[o],r),i===!1)break}else if(a)for(;s>o&&(i=t.call(e[o],o,e[o]),i!==!1);o++);else for(o in e)if(i=t.call(e[o],o,e[o]),i===!1)break;return e},trim:function(e){return null==e?"":(e+"").replace(ee,"")},makeArray:function(e,t){var r=t||[];return null!=e&&(n(Object(e))?Z.merge(r,"string"==typeof e?[e]:e):X.call(r,e)),r},inArray:function(e,t,n){return null==t?-1:U.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;n>r;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,s=e.length,a=!n;s>o;o++)r=!t(e[o],o),r!==a&&i.push(e[o]);return i},map:function(e,t,r){var i,o=0,s=e.length,a=n(e),u=[];if(a)for(;s>o;o++)i=t(e[o],o,r),null!=i&&u.push(i);else for(o in e)i=t(e[o],o,r),null!=i&&u.push(i);return z.apply([],u)},guid:1,proxy:function(e,t){var n,r,i;return"string"==typeof t&&(n=e[t],t=e,e=n),Z.isFunction(e)?(r=_.call(arguments,2),i=function(){return e.apply(t||this,r.concat(_.call(arguments)))},i.guid=e.guid=e.guid||Z.guid++,i):void 0},now:Date.now,support:Q}),Z.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){V["[object "+t+"]"]=t.toLowerCase()});var ie=function(e){function t(e,t,n,r){var i,o,s,a,u,l,f,d,h,g;if((t?t.ownerDocument||t:$)!==q&&L(t),t=t||q,n=n||[],a=t.nodeType,"string"!=typeof e||!e||1!==a&&9!==a&&11!==a)return n;if(!r&&O){if(11!==a&&(i=ye.exec(e)))if(s=i[1]){if(9===a){if(o=t.getElementById(s),!o||!o.parentNode)return n;if(o.id===s)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(s))&&M(t,o)&&o.id===s)return n.push(o),n}else{if(i[2])return K.apply(n,t.getElementsByTagName(e)),n;if((s=i[3])&&w.getElementsByClassName)return K.apply(n,t.getElementsByClassName(s)),n}if(w.qsa&&(!F||!F.test(e))){if(d=f=W,h=t,g=1!==a&&e,1===a&&"object"!==t.nodeName.toLowerCase()){for(l=k(e),(f=t.getAttribute("id"))?d=f.replace(be,"\\$&"):t.setAttribute("id",d),d="[id='"+d+"'] ",u=l.length;u--;)l[u]=d+p(l[u]);h=xe.test(e)&&c(t.parentNode)||t,g=l.join(",")}if(g)try{return K.apply(n,h.querySelectorAll(g)),n}catch(m){}finally{f||t.removeAttribute("id")}}}return S(e.replace(ue,"$1"),t,n,r)}function n(){function e(n,r){return t.push(n+" ")>T.cacheLength&&delete e[t.shift()],e[n+" "]=r}var t=[];return e}function r(e){return e[W]=!0,e}function i(e){var t=q.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split("|"),r=e.length;r--;)T.attrHandle[n[r]]=t}function s(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||V)-(~e.sourceIndex||V);if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function a(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function l(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),s=o.length;s--;)n[i=o[s]]&&(n[i]=!(r[i]=n[i]))})})}function c(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function f(){}function p(e){for(var t=0,n=e.length,r="";n>t;t++)r+=e[t].value;return r}function d(e,t,n){var r=t.dir,i=n&&"parentNode"===r,o=B++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||i)return e(t,n,o)}:function(t,n,s){var a,u,l=[I,o];if(s){for(;t=t[r];)if((1===t.nodeType||i)&&e(t,n,s))return!0}else for(;t=t[r];)if(1===t.nodeType||i){if(u=t[W]||(t[W]={}),(a=u[r])&&a[0]===I&&a[1]===o)return l[2]=a[2];if(u[r]=l,l[2]=e(t,n,s))return!0}}}function h(e){return e.length>1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function g(e,n,r){for(var i=0,o=n.length;o>i;i++)t(e,n[i],r);return r}function m(e,t,n,r,i){for(var o,s=[],a=0,u=e.length,l=null!=t;u>a;a++)(o=e[a])&&(!n||n(o,r,i))&&(s.push(o),l&&t.push(a));return s}function v(e,t,n,i,o,s){return i&&!i[W]&&(i=v(i)),o&&!o[W]&&(o=v(o,s)),r(function(r,s,a,u){var l,c,f,p=[],d=[],h=s.length,v=r||g(t||"*",a.nodeType?[a]:a,[]),y=!e||!r&&t?v:m(v,p,e,a,u),x=n?o||(r?e:h||i)?[]:s:y;if(n&&n(y,x,a,u),i)for(l=m(x,d),i(l,[],a,u),c=l.length;c--;)(f=l[c])&&(x[d[c]]=!(y[d[c]]=f));if(r){if(o||e){if(o){for(l=[],c=x.length;c--;)(f=x[c])&&l.push(y[c]=f);o(null,x=[],l,u)}for(c=x.length;c--;)(f=x[c])&&(l=o?ee(r,f):p[c])>-1&&(r[l]=!(s[l]=f))}}else x=m(x===s?x.splice(h,x.length):x),o?o(null,s,x,u):K.apply(s,x)})}function y(e){for(var t,n,r,i=e.length,o=T.relative[e[0].type],s=o||T.relative[" "],a=o?1:0,u=d(function(e){return e===t},s,!0),l=d(function(e){return ee(t,e)>-1},s,!0),c=[function(e,n,r){var i=!o&&(r||n!==D)||((t=n).nodeType?u(e,n,r):l(e,n,r));return t=null,i}];i>a;a++)if(n=T.relative[e[a].type])c=[d(h(c),n)];else{if(n=T.filter[e[a].type].apply(null,e[a].matches),n[W]){for(r=++a;i>r&&!T.relative[e[r].type];r++);return v(a>1&&h(c),a>1&&p(e.slice(0,a-1).concat({value:" "===e[a-2].type?"*":""})).replace(ue,"$1"),n,r>a&&y(e.slice(a,r)),i>r&&y(e=e.slice(r)),i>r&&p(e))}c.push(n)}return h(c)}function x(e,n){var i=n.length>0,o=e.length>0,s=function(r,s,a,u,l){var c,f,p,d=0,h="0",g=r&&[],v=[],y=D,x=r||o&&T.find.TAG("*",l),b=I+=null==y?1:Math.random()||.1,w=x.length;for(l&&(D=s!==q&&s);h!==w&&null!=(c=x[h]);h++){if(o&&c){for(f=0;p=e[f++];)if(p(c,s,a)){u.push(c);break}l&&(I=b)}i&&((c=!p&&c)&&d--,r&&g.push(c))}if(d+=h,i&&h!==d){for(f=0;p=n[f++];)p(g,v,s,a);if(r){if(d>0)for(;h--;)g[h]||v[h]||(v[h]=Q.call(u));v=m(v)}K.apply(u,v),l&&!r&&v.length>0&&d+n.length>1&&t.uniqueSort(u)}return l&&(I=b,D=y),g};return i?r(s):s}var b,w,T,C,N,k,E,S,D,j,A,L,q,H,O,F,P,R,M,W="sizzle"+1*new Date,$=e.document,I=0,B=0,_=n(),z=n(),X=n(),U=function(e,t){return e===t&&(A=!0),0},V=1<<31,Y={}.hasOwnProperty,G=[],Q=G.pop,J=G.push,K=G.push,Z=G.slice,ee=function(e,t){for(var n=0,r=e.length;r>n;n++)if(e[n]===t)return n;return-1},te="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",ne="[\\x20\\t\\r\\n\\f]",re="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",ie=re.replace("w","w#"),oe="\\["+ne+"*("+re+")(?:"+ne+"*([*^$|!~]?=)"+ne+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+ie+"))|)"+ne+"*\\]",se=":("+re+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+oe+")*)|.*)\\)|)",ae=new RegExp(ne+"+","g"),ue=new RegExp("^"+ne+"+|((?:^|[^\\\\])(?:\\\\.)*)"+ne+"+$","g"),le=new RegExp("^"+ne+"*,"+ne+"*"),ce=new RegExp("^"+ne+"*([>+~]|"+ne+")"+ne+"*"),fe=new RegExp("="+ne+"*([^\\]'\"]*?)"+ne+"*\\]","g"),pe=new RegExp(se),de=new RegExp("^"+ie+"$"),he={ID:new RegExp("^#("+re+")"),CLASS:new RegExp("^\\.("+re+")"),TAG:new RegExp("^("+re.replace("w","w*")+")"),ATTR:new RegExp("^"+oe),PSEUDO:new RegExp("^"+se),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ne+"*(even|odd|(([+-]|)(\\d*)n|)"+ne+"*(?:([+-]|)"+ne+"*(\\d+)|))"+ne+"*\\)|)","i"),bool:new RegExp("^(?:"+te+")$","i"),needsContext:new RegExp("^"+ne+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ne+"*((?:-\\d)?\\d*)"+ne+"*\\)|)(?=[^-]|$)","i")},ge=/^(?:input|select|textarea|button)$/i,me=/^h\d$/i,ve=/^[^{]+\{\s*\[native \w/,ye=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,xe=/[+~]/,be=/'|\\/g,we=new RegExp("\\\\([\\da-f]{1,6}"+ne+"?|("+ne+")|.)","ig"),Te=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},Ce=function(){L()};try{K.apply(G=Z.call($.childNodes),$.childNodes),G[$.childNodes.length].nodeType}catch(Ne){K={apply:G.length?function(e,t){J.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}w=t.support={},N=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},L=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:$;return r!==q&&9===r.nodeType&&r.documentElement?(q=r,H=r.documentElement,n=r.defaultView,n&&n!==n.top&&(n.addEventListener?n.addEventListener("unload",Ce,!1):n.attachEvent&&n.attachEvent("onunload",Ce)),O=!N(r),w.attributes=i(function(e){return e.className="i",!e.getAttribute("className")}),w.getElementsByTagName=i(function(e){return e.appendChild(r.createComment("")),!e.getElementsByTagName("*").length}),w.getElementsByClassName=ve.test(r.getElementsByClassName),w.getById=i(function(e){return H.appendChild(e).id=W,!r.getElementsByName||!r.getElementsByName(W).length}),w.getById?(T.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&O){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},T.filter.ID=function(e){var t=e.replace(we,Te);return function(e){return e.getAttribute("id")===t}}):(delete T.find.ID,T.filter.ID=function(e){var t=e.replace(we,Te);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}}),T.find.TAG=w.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):w.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},T.find.CLASS=w.getElementsByClassName&&function(e,t){return O?t.getElementsByClassName(e):void 0},P=[],F=[],(w.qsa=ve.test(r.querySelectorAll))&&(i(function(e){H.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&F.push("[*^$]="+ne+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||F.push("\\["+ne+"*(?:value|"+te+")"),e.querySelectorAll("[id~="+W+"-]").length||F.push("~="),e.querySelectorAll(":checked").length||F.push(":checked"),e.querySelectorAll("a#"+W+"+*").length||F.push(".#.+[+~]")}),i(function(e){var t=r.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&F.push("name"+ne+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||F.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),F.push(",.*:")})),(w.matchesSelector=ve.test(R=H.matches||H.webkitMatchesSelector||H.mozMatchesSelector||H.oMatchesSelector||H.msMatchesSelector))&&i(function(e){w.disconnectedMatch=R.call(e,"div"),R.call(e,"[s!='']:x"),P.push("!=",se)}),F=F.length&&new RegExp(F.join("|")),P=P.length&&new RegExp(P.join("|")),t=ve.test(H.compareDocumentPosition),M=t||ve.test(H.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},U=t?function(e,t){if(e===t)return A=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!w.sortDetached&&t.compareDocumentPosition(e)===n?e===r||e.ownerDocument===$&&M($,e)?-1:t===r||t.ownerDocument===$&&M($,t)?1:j?ee(j,e)-ee(j,t):0:4&n?-1:1)}:function(e,t){if(e===t)return A=!0,0;var n,i=0,o=e.parentNode,a=t.parentNode,u=[e],l=[t];if(!o||!a)return e===r?-1:t===r?1:o?-1:a?1:j?ee(j,e)-ee(j,t):0;if(o===a)return s(e,t);for(n=e;n=n.parentNode;)u.unshift(n);for(n=t;n=n.parentNode;)l.unshift(n);for(;u[i]===l[i];)i++;return i?s(u[i],l[i]):u[i]===$?-1:l[i]===$?1:0},r):q},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==q&&L(e),n=n.replace(fe,"='$1']"),!(!w.matchesSelector||!O||P&&P.test(n)||F&&F.test(n)))try{var r=R.call(e,n);if(r||w.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(i){}return t(n,q,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==q&&L(e),M(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==q&&L(e);var n=T.attrHandle[t.toLowerCase()],r=n&&Y.call(T.attrHandle,t.toLowerCase())?n(e,t,!O):void 0;return void 0!==r?r:w.attributes||!O?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],r=0,i=0;if(A=!w.detectDuplicates,j=!w.sortStable&&e.slice(0),e.sort(U),A){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return j=null,e},C=t.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=C(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=C(t);return n},T=t.selectors={cacheLength:50,createPseudo:r,match:he,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(we,Te),e[3]=(e[3]||e[4]||e[5]||"").replace(we,Te),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return he.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&pe.test(n)&&(t=k(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(we,Te).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=_[e+" "];return t||(t=new RegExp("(^|"+ne+")"+e+"("+ne+"|$)"))&&_(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,n,r){return function(i){var o=t.attr(i,e);return null==o?"!="===n:n?(o+="","="===n?o===r:"!="===n?o!==r:"^="===n?r&&0===o.indexOf(r):"*="===n?r&&o.indexOf(r)>-1:"$="===n?r&&o.slice(-r.length)===r:"~="===n?(" "+o.replace(ae," ")+" ").indexOf(r)>-1:"|="===n?o===r||o.slice(0,r.length+1)===r+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==s?"nextSibling":"previousSibling",m=t.parentNode,v=a&&t.nodeName.toLowerCase(),y=!u&&!a;if(m){if(o){for(;g;){for(f=t;f=f[g];)if(a?f.nodeName.toLowerCase()===v:1===f.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[s?m.firstChild:m.lastChild],s&&y){for(c=m[W]||(m[W]={}),l=c[e]||[],d=l[0]===I&&l[1],p=l[0]===I&&l[2],f=d&&m.childNodes[d];f=++d&&f&&f[g]||(p=d=0)||h.pop();)if(1===f.nodeType&&++p&&f===t){c[e]=[I,d,p];break}}else if(y&&(l=(t[W]||(t[W]={}))[e])&&l[0]===I)p=l[1];else for(;(f=++d&&f&&f[g]||(p=d=0)||h.pop())&&((a?f.nodeName.toLowerCase()!==v:1!==f.nodeType)||!++p||(y&&((f[W]||(f[W]={}))[e]=[I,p]),f!==t)););return p-=i,p===r||p%r===0&&p/r>=0}}},PSEUDO:function(e,n){var i,o=T.pseudos[e]||T.setFilters[e.toLowerCase()]||t.error("unsupported pseudo: "+e);return o[W]?o(n):o.length>1?(i=[e,e,"",n],T.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,i=o(e,n),s=i.length;s--;)r=ee(e,i[s]),e[r]=!(t[r]=i[s])}):function(e){return o(e,0,i)}):o}},pseudos:{not:r(function(e){var t=[],n=[],i=E(e.replace(ue,"$1"));return i[W]?r(function(e,t,n,r){for(var o,s=i(e,null,r,[]),a=e.length;a--;)(o=s[a])&&(e[a]=!(t[a]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){return t(e,n).length>0}}),contains:r(function(e){return e=e.replace(we,Te),function(t){return(t.textContent||t.innerText||C(t)).indexOf(e)>-1}}),lang:r(function(e){return de.test(e||"")||t.error("unsupported lang: "+e),e=e.replace(we,Te).toLowerCase(),function(t){var n;do if(n=O?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===H},focus:function(e){return e===q.activeElement&&(!q.hasFocus||q.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!T.pseudos.empty(e)},header:function(e){return me.test(e.nodeName)},input:function(e){return ge.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:l(function(){return[0]}),last:l(function(e,t){return[t-1]}),eq:l(function(e,t,n){return[0>n?n+t:n]}),even:l(function(e,t){for(var n=0;t>n;n+=2)e.push(n);return e}),odd:l(function(e,t){for(var n=1;t>n;n+=2)e.push(n);return e}),lt:l(function(e,t,n){for(var r=0>n?n+t:n;--r>=0;)e.push(r);return e}),gt:l(function(e,t,n){for(var r=0>n?n+t:n;++r2&&"ID"===(s=o[0]).type&&w.getById&&9===t.nodeType&&O&&T.relative[o[1].type]){if(t=(T.find.ID(s.matches[0].replace(we,Te),t)||[])[0],!t)return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=he.needsContext.test(e)?0:o.length;i--&&(s=o[i],!T.relative[a=s.type]);)if((u=T.find[a])&&(r=u(s.matches[0].replace(we,Te),xe.test(o[0].type)&&c(t.parentNode)||t))){if(o.splice(i,1),e=r.length&&p(o),!e)return K.apply(n,r),n;break}}return(l||E(e,f))(r,t,!O,n,xe.test(e)&&c(t.parentNode)||t),n},w.sortStable=W.split("").sort(U).join("")===W,w.detectDuplicates=!!A,L(),w.sortDetached=i(function(e){return 1&e.compareDocumentPosition(q.createElement("div"))}),i(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||o("type|href|height|width",function(e,t,n){return n?void 0:e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),w.attributes&&i(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||o("value",function(e,t,n){return n||"input"!==e.nodeName.toLowerCase()?void 0:e.defaultValue}),i(function(e){return null==e.getAttribute("disabled")})||o(te,function(e,t,n){var r;return n?void 0:e[t]===!0?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);Z.find=ie,Z.expr=ie.selectors,Z.expr[":"]=Z.expr.pseudos,Z.unique=ie.uniqueSort,Z.text=ie.getText,Z.isXMLDoc=ie.isXML,Z.contains=ie.contains;var oe=Z.expr.match.needsContext,se=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,ae=/^.[^:#\[\.,]*$/;Z.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?Z.find.matchesSelector(r,e)?[r]:[]:Z.find.matches(e,Z.grep(t,function(e){return 1===e.nodeType}))},Z.fn.extend({find:function(e){var t,n=this.length,r=[],i=this;if("string"!=typeof e)return this.pushStack(Z(e).filter(function(){
+for(t=0;n>t;t++)if(Z.contains(i[t],this))return!0}));for(t=0;n>t;t++)Z.find(e,i[t],r);return r=this.pushStack(n>1?Z.unique(r):r),r.selector=this.selector?this.selector+" "+e:e,r},filter:function(e){return this.pushStack(r(this,e||[],!1))},not:function(e){return this.pushStack(r(this,e||[],!0))},is:function(e){return!!r(this,"string"==typeof e&&oe.test(e)?Z(e):e||[],!1).length}});var ue,le=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,ce=Z.fn.init=function(e,t){var n,r;if(!e)return this;if("string"==typeof e){if(n="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:le.exec(e),!n||!n[1]&&t)return!t||t.jquery?(t||ue).find(e):this.constructor(t).find(e);if(n[1]){if(t=t instanceof Z?t[0]:t,Z.merge(this,Z.parseHTML(n[1],t&&t.nodeType?t.ownerDocument||t:J,!0)),se.test(n[1])&&Z.isPlainObject(t))for(n in t)Z.isFunction(this[n])?this[n](t[n]):this.attr(n,t[n]);return this}return r=J.getElementById(n[2]),r&&r.parentNode&&(this.length=1,this[0]=r),this.context=J,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):Z.isFunction(e)?"undefined"!=typeof ue.ready?ue.ready(e):e(Z):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),Z.makeArray(e,this))};ce.prototype=Z.fn,ue=Z(J);var fe=/^(?:parents|prev(?:Until|All))/,pe={children:!0,contents:!0,next:!0,prev:!0};Z.extend({dir:function(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&Z(e).is(n))break;r.push(e)}return r},sibling:function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}}),Z.fn.extend({has:function(e){var t=Z(e,this),n=t.length;return this.filter(function(){for(var e=0;n>e;e++)if(Z.contains(this,t[e]))return!0})},closest:function(e,t){for(var n,r=0,i=this.length,o=[],s=oe.test(e)||"string"!=typeof e?Z(e,t||this.context):0;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(s?s.index(n)>-1:1===n.nodeType&&Z.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?Z.unique(o):o)},index:function(e){return e?"string"==typeof e?U.call(Z(e),this[0]):U.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(Z.unique(Z.merge(this.get(),Z(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),Z.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return Z.dir(e,"parentNode")},parentsUntil:function(e,t,n){return Z.dir(e,"parentNode",n)},next:function(e){return i(e,"nextSibling")},prev:function(e){return i(e,"previousSibling")},nextAll:function(e){return Z.dir(e,"nextSibling")},prevAll:function(e){return Z.dir(e,"previousSibling")},nextUntil:function(e,t,n){return Z.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return Z.dir(e,"previousSibling",n)},siblings:function(e){return Z.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return Z.sibling(e.firstChild)},contents:function(e){return e.contentDocument||Z.merge([],e.childNodes)}},function(e,t){Z.fn[e]=function(n,r){var i=Z.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=Z.filter(r,i)),this.length>1&&(pe[e]||Z.unique(i),fe.test(e)&&i.reverse()),this.pushStack(i)}});var de=/\S+/g,he={};Z.Callbacks=function(e){e="string"==typeof e?he[e]||o(e):Z.extend({},e);var t,n,r,i,s,a,u=[],l=!e.once&&[],c=function(o){for(t=e.memory&&o,n=!0,a=i||0,i=0,s=u.length,r=!0;u&&s>a;a++)if(u[a].apply(o[0],o[1])===!1&&e.stopOnFalse){t=!1;break}r=!1,u&&(l?l.length&&c(l.shift()):t?u=[]:f.disable())},f={add:function(){if(u){var n=u.length;!function o(t){Z.each(t,function(t,n){var r=Z.type(n);"function"===r?e.unique&&f.has(n)||u.push(n):n&&n.length&&"string"!==r&&o(n)})}(arguments),r?s=u.length:t&&(i=n,c(t))}return this},remove:function(){return u&&Z.each(arguments,function(e,t){for(var n;(n=Z.inArray(t,u,n))>-1;)u.splice(n,1),r&&(s>=n&&s--,a>=n&&a--)}),this},has:function(e){return e?Z.inArray(e,u)>-1:!(!u||!u.length)},empty:function(){return u=[],s=0,this},disable:function(){return u=l=t=void 0,this},disabled:function(){return!u},lock:function(){return l=void 0,t||f.disable(),this},locked:function(){return!l},fireWith:function(e,t){return!u||n&&!l||(t=t||[],t=[e,t.slice?t.slice():t],r?l.push(t):c(t)),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!n}};return f},Z.extend({Deferred:function(e){var t=[["resolve","done",Z.Callbacks("once memory"),"resolved"],["reject","fail",Z.Callbacks("once memory"),"rejected"],["notify","progress",Z.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return Z.Deferred(function(n){Z.each(t,function(t,o){var s=Z.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&Z.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[o[0]+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?Z.extend(e,r):r}},i={};return r.pipe=r.then,Z.each(t,function(e,o){var s=o[2],a=o[3];r[o[1]]=s.add,a&&s.add(function(){n=a},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=s.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t,n,r,i=0,o=_.call(arguments),s=o.length,a=1!==s||e&&Z.isFunction(e.promise)?s:0,u=1===a?e:Z.Deferred(),l=function(e,n,r){return function(i){n[e]=this,r[e]=arguments.length>1?_.call(arguments):i,r===t?u.notifyWith(n,r):--a||u.resolveWith(n,r)}};if(s>1)for(t=new Array(s),n=new Array(s),r=new Array(s);s>i;i++)o[i]&&Z.isFunction(o[i].promise)?o[i].promise().done(l(i,r,o)).fail(u.reject).progress(l(i,n,t)):--a;return a||u.resolveWith(r,o),u.promise()}});var ge;Z.fn.ready=function(e){return Z.ready.promise().done(e),this},Z.extend({isReady:!1,readyWait:1,holdReady:function(e){e?Z.readyWait++:Z.ready(!0)},ready:function(e){(e===!0?--Z.readyWait:Z.isReady)||(Z.isReady=!0,e!==!0&&--Z.readyWait>0||(ge.resolveWith(J,[Z]),Z.fn.triggerHandler&&(Z(J).triggerHandler("ready"),Z(J).off("ready"))))}}),Z.ready.promise=function(t){return ge||(ge=Z.Deferred(),"complete"===J.readyState?setTimeout(Z.ready):(J.addEventListener("DOMContentLoaded",s,!1),e.addEventListener("load",s,!1))),ge.promise(t)},Z.ready.promise();var me=Z.access=function(e,t,n,r,i,o,s){var a=0,u=e.length,l=null==n;if("object"===Z.type(n)){i=!0;for(a in n)Z.access(e,t,a,n[a],!0,o,s)}else if(void 0!==r&&(i=!0,Z.isFunction(r)||(s=!0),l&&(s?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(Z(e),n)})),t))for(;u>a;a++)t(e[a],n,s?r:r.call(e[a],a,t(e[a],n)));return i?e:l?t.call(e):u?t(e[0],n):o};Z.acceptData=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType},a.uid=1,a.accepts=Z.acceptData,a.prototype={key:function(e){if(!a.accepts(e))return 0;var t={},n=e[this.expando];if(!n){n=a.uid++;try{t[this.expando]={value:n},Object.defineProperties(e,t)}catch(r){t[this.expando]=n,Z.extend(e,t)}}return this.cache[n]||(this.cache[n]={}),n},set:function(e,t,n){var r,i=this.key(e),o=this.cache[i];if("string"==typeof t)o[t]=n;else if(Z.isEmptyObject(o))Z.extend(this.cache[i],t);else for(r in t)o[r]=t[r];return o},get:function(e,t){var n=this.cache[this.key(e)];return void 0===t?n:n[t]},access:function(e,t,n){var r;return void 0===t||t&&"string"==typeof t&&void 0===n?(r=this.get(e,t),void 0!==r?r:this.get(e,Z.camelCase(t))):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r,i,o=this.key(e),s=this.cache[o];if(void 0===t)this.cache[o]={};else{Z.isArray(t)?r=t.concat(t.map(Z.camelCase)):(i=Z.camelCase(t),t in s?r=[t,i]:(r=i,r=r in s?[r]:r.match(de)||[])),n=r.length;for(;n--;)delete s[r[n]]}},hasData:function(e){return!Z.isEmptyObject(this.cache[e[this.expando]]||{})},discard:function(e){e[this.expando]&&delete this.cache[e[this.expando]]}};var ve=new a,ye=new a,xe=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,be=/([A-Z])/g;Z.extend({hasData:function(e){return ye.hasData(e)||ve.hasData(e)},data:function(e,t,n){return ye.access(e,t,n)},removeData:function(e,t){ye.remove(e,t)},_data:function(e,t,n){return ve.access(e,t,n)},_removeData:function(e,t){ve.remove(e,t)}}),Z.fn.extend({data:function(e,t){var n,r,i,o=this[0],s=o&&o.attributes;if(void 0===e){if(this.length&&(i=ye.get(o),1===o.nodeType&&!ve.get(o,"hasDataAttrs"))){for(n=s.length;n--;)s[n]&&(r=s[n].name,0===r.indexOf("data-")&&(r=Z.camelCase(r.slice(5)),u(o,r,i[r])));ve.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof e?this.each(function(){ye.set(this,e)}):me(this,function(t){var n,r=Z.camelCase(e);if(o&&void 0===t){if(n=ye.get(o,e),void 0!==n)return n;if(n=ye.get(o,r),void 0!==n)return n;if(n=u(o,r,void 0),void 0!==n)return n}else this.each(function(){var n=ye.get(this,r);ye.set(this,r,t),-1!==e.indexOf("-")&&void 0!==n&&ye.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){ye.remove(this,e)})}}),Z.extend({queue:function(e,t,n){var r;return e?(t=(t||"fx")+"queue",r=ve.get(e,t),n&&(!r||Z.isArray(n)?r=ve.access(e,t,Z.makeArray(n)):r.push(n)),r||[]):void 0},dequeue:function(e,t){t=t||"fx";var n=Z.queue(e,t),r=n.length,i=n.shift(),o=Z._queueHooks(e,t),s=function(){Z.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,s,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return ve.get(e,n)||ve.access(e,n,{empty:Z.Callbacks("once memory").add(function(){ve.remove(e,[t+"queue",n])})})}}),Z.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.lengthx",Q.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();var ke="undefined";Q.focusinBubbles="onfocusin"in e;var Ee=/^key/,Se=/^(?:mouse|pointer|contextmenu)|click/,De=/^(?:focusinfocus|focusoutblur)$/,je=/^([^.]*)(?:\.(.+)|)$/;Z.event={global:{},add:function(e,t,n,r,i){var o,s,a,u,l,c,f,p,d,h,g,m=ve.get(e);if(m)for(n.handler&&(o=n,n=o.handler,i=o.selector),n.guid||(n.guid=Z.guid++),(u=m.events)||(u=m.events={}),(s=m.handle)||(s=m.handle=function(t){return typeof Z!==ke&&Z.event.triggered!==t.type?Z.event.dispatch.apply(e,arguments):void 0}),t=(t||"").match(de)||[""],l=t.length;l--;)a=je.exec(t[l])||[],d=g=a[1],h=(a[2]||"").split(".").sort(),d&&(f=Z.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=Z.event.special[d]||{},c=Z.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&Z.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||(p=u[d]=[],p.delegateCount=0,f.setup&&f.setup.call(e,r,h,s)!==!1||e.addEventListener&&e.addEventListener(d,s,!1)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),Z.event.global[d]=!0)},remove:function(e,t,n,r,i){var o,s,a,u,l,c,f,p,d,h,g,m=ve.hasData(e)&&ve.get(e);if(m&&(u=m.events)){for(t=(t||"").match(de)||[""],l=t.length;l--;)if(a=je.exec(t[l])||[],d=g=a[1],h=(a[2]||"").split(".").sort(),d){for(f=Z.event.special[d]||{},d=(r?f.delegateType:f.bindType)||d,p=u[d]||[],a=a[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=p.length;o--;)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));s&&!p.length&&(f.teardown&&f.teardown.call(e,h,m.handle)!==!1||Z.removeEvent(e,d,m.handle),delete u[d])}else for(d in u)Z.event.remove(e,d+t[l],n,r,!0);Z.isEmptyObject(u)&&(delete m.handle,ve.remove(e,"events"))}},trigger:function(t,n,r,i){var o,s,a,u,l,c,f,p=[r||J],d=G.call(t,"type")?t.type:t,h=G.call(t,"namespace")?t.namespace.split("."):[];if(s=a=r=r||J,3!==r.nodeType&&8!==r.nodeType&&!De.test(d+Z.event.triggered)&&(d.indexOf(".")>=0&&(h=d.split("."),d=h.shift(),h.sort()),l=d.indexOf(":")<0&&"on"+d,t=t[Z.expando]?t:new Z.Event(d,"object"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=h.join("."),t.namespace_re=t.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:Z.makeArray(n,[t]),f=Z.event.special[d]||{},i||!f.trigger||f.trigger.apply(r,n)!==!1)){if(!i&&!f.noBubble&&!Z.isWindow(r)){for(u=f.delegateType||d,De.test(u+d)||(s=s.parentNode);s;s=s.parentNode)p.push(s),a=s;a===(r.ownerDocument||J)&&p.push(a.defaultView||a.parentWindow||e)}for(o=0;(s=p[o++])&&!t.isPropagationStopped();)t.type=o>1?u:f.bindType||d,c=(ve.get(s,"events")||{})[t.type]&&ve.get(s,"handle"),c&&c.apply(s,n),c=l&&s[l],c&&c.apply&&Z.acceptData(s)&&(t.result=c.apply(s,n),t.result===!1&&t.preventDefault());return t.type=d,i||t.isDefaultPrevented()||f._default&&f._default.apply(p.pop(),n)!==!1||!Z.acceptData(r)||l&&Z.isFunction(r[d])&&!Z.isWindow(r)&&(a=r[l],a&&(r[l]=null),Z.event.triggered=d,r[d](),Z.event.triggered=void 0,a&&(r[l]=a)),t.result}},dispatch:function(e){e=Z.event.fix(e);var t,n,r,i,o,s=[],a=_.call(arguments),u=(ve.get(this,"events")||{})[e.type]||[],l=Z.event.special[e.type]||{};if(a[0]=e,e.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,e)!==!1){for(s=Z.event.handlers.call(this,e,u),t=0;(i=s[t++])&&!e.isPropagationStopped();)for(e.currentTarget=i.elem,n=0;(o=i.handlers[n++])&&!e.isImmediatePropagationStopped();)(!e.namespace_re||e.namespace_re.test(o.namespace))&&(e.handleObj=o,e.data=o.data,r=((Z.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,a),void 0!==r&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()));return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,s=[],a=t.delegateCount,u=e.target;if(a&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!==this;u=u.parentNode||this)if(u.disabled!==!0||"click"!==e.type){for(r=[],n=0;a>n;n++)o=t[n],i=o.selector+" ",void 0===r[i]&&(r[i]=o.needsContext?Z(i,this).index(u)>=0:Z.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&s.push({elem:u,handlers:r})}return a]*)\/>/gi,Le=/<([\w:]+)/,qe=/<|?\w+;/,He=/<(?:script|style|link)/i,Oe=/checked\s*(?:[^=]|=\s*.checked.)/i,Fe=/^$|\/(?:java|ecma)script/i,Pe=/^true\/(.*)/,Re=/^\s*\s*$/g,Me={option:[1,""],thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};Me.optgroup=Me.option,Me.tbody=Me.tfoot=Me.colgroup=Me.caption=Me.thead,Me.th=Me.td,Z.extend({clone:function(e,t,n){var r,i,o,s,a=e.cloneNode(!0),u=Z.contains(e.ownerDocument,e);if(!(Q.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||Z.isXMLDoc(e)))for(s=v(a),o=v(e),r=0,i=o.length;i>r;r++)y(o[r],s[r]);if(t)if(n)for(o=o||v(e),s=s||v(a),r=0,i=o.length;i>r;r++)m(o[r],s[r]);else m(e,a);return s=v(a,"script"),s.length>0&&g(s,!u&&v(e,"script")),a},buildFragment:function(e,t,n,r){for(var i,o,s,a,u,l,c=t.createDocumentFragment(),f=[],p=0,d=e.length;d>p;p++)if(i=e[p],i||0===i)if("object"===Z.type(i))Z.merge(f,i.nodeType?[i]:i);else if(qe.test(i)){for(o=o||c.appendChild(t.createElement("div")),s=(Le.exec(i)||["",""])[1].toLowerCase(),a=Me[s]||Me._default,o.innerHTML=a[1]+i.replace(Ae,"<$1>$2>")+a[2],l=a[0];l--;)o=o.lastChild;Z.merge(f,o.childNodes),o=c.firstChild,o.textContent=""}else f.push(t.createTextNode(i));for(c.textContent="",p=0;i=f[p++];)if((!r||-1===Z.inArray(i,r))&&(u=Z.contains(i.ownerDocument,i),o=v(c.appendChild(i),"script"),u&&g(o),n))for(l=0;i=o[l++];)Fe.test(i.type||"")&&n.push(i);return c},cleanData:function(e){for(var t,n,r,i,o=Z.event.special,s=0;void 0!==(n=e[s]);s++){if(Z.acceptData(n)&&(i=n[ve.expando],i&&(t=ve.cache[i]))){if(t.events)for(r in t.events)o[r]?Z.event.remove(n,r):Z.removeEvent(n,r,t.handle);ve.cache[i]&&delete ve.cache[i]}delete ye.cache[n[ye.expando]]}}}),Z.fn.extend({text:function(e){return me(this,function(e){return void 0===e?Z.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=e)})},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=p(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=p(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){for(var n,r=e?Z.filter(e,this):this,i=0;null!=(n=r[i]);i++)t||1!==n.nodeType||Z.cleanData(v(n)),n.parentNode&&(t&&Z.contains(n.ownerDocument,n)&&g(v(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(Z.cleanData(v(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return Z.clone(this,e,t)})},html:function(e){return me(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!He.test(e)&&!Me[(Le.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(Ae,"<$1>$2>");try{for(;r>n;n++)t=this[n]||{},1===t.nodeType&&(Z.cleanData(v(t,!1)),t.innerHTML=e);t=0}catch(i){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=arguments[0];return this.domManip(arguments,function(t){e=this.parentNode,Z.cleanData(v(this)),e&&e.replaceChild(t,this)}),e&&(e.length||e.nodeType)?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t){e=z.apply([],e);var n,r,i,o,s,a,u=0,l=this.length,c=this,f=l-1,p=e[0],g=Z.isFunction(p);if(g||l>1&&"string"==typeof p&&!Q.checkClone&&Oe.test(p))return this.each(function(n){var r=c.eq(n);g&&(e[0]=p.call(this,n,r.html())),r.domManip(e,t)});if(l&&(n=Z.buildFragment(e,this[0].ownerDocument,!1,this),r=n.firstChild,1===n.childNodes.length&&(n=r),r)){for(i=Z.map(v(n,"script"),d),o=i.length;l>u;u++)s=n,u!==f&&(s=Z.clone(s,!0,!0),o&&Z.merge(i,v(s,"script"))),t.call(this[u],s,u);if(o)for(a=i[i.length-1].ownerDocument,Z.map(i,h),u=0;o>u;u++)s=i[u],Fe.test(s.type||"")&&!ve.access(s,"globalEval")&&Z.contains(a,s)&&(s.src?Z._evalUrl&&Z._evalUrl(s.src):Z.globalEval(s.textContent.replace(Re,"")))}return this}}),Z.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){Z.fn[e]=function(e){for(var n,r=[],i=Z(e),o=i.length-1,s=0;o>=s;s++)n=s===o?this:this.clone(!0),Z(i[s])[t](n),X.apply(r,n.get());return this.pushStack(r)}});var We,$e={},Ie=/^margin/,Be=new RegExp("^("+we+")(?!px)[a-z%]+$","i"),_e=function(t){return t.ownerDocument.defaultView.opener?t.ownerDocument.defaultView.getComputedStyle(t,null):e.getComputedStyle(t,null)};!function(){function t(){s.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",s.innerHTML="",i.appendChild(o);var t=e.getComputedStyle(s,null);n="1%"!==t.top,r="4px"===t.width,i.removeChild(o)}var n,r,i=J.documentElement,o=J.createElement("div"),s=J.createElement("div");s.style&&(s.style.backgroundClip="content-box",s.cloneNode(!0).style.backgroundClip="",Q.clearCloneStyle="content-box"===s.style.backgroundClip,o.style.cssText="border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute",o.appendChild(s),e.getComputedStyle&&Z.extend(Q,{pixelPosition:function(){return t(),n},boxSizingReliable:function(){return null==r&&t(),r},reliableMarginRight:function(){var t,n=s.appendChild(J.createElement("div"));return n.style.cssText=s.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",n.style.marginRight=n.style.width="0",s.style.width="1px",i.appendChild(o),t=!parseFloat(e.getComputedStyle(n,null).marginRight),i.removeChild(o),s.removeChild(n),t}}))}(),Z.swap=function(e,t,n,r){var i,o,s={};for(o in t)s[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=s[o];return i};var ze=/^(none|table(?!-c[ea]).+)/,Xe=new RegExp("^("+we+")(.*)$","i"),Ue=new RegExp("^([+-])=("+we+")","i"),Ve={position:"absolute",visibility:"hidden",display:"block"},Ye={letterSpacing:"0",fontWeight:"400"},Ge=["Webkit","O","Moz","ms"];Z.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=w(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,s,a=Z.camelCase(t),u=e.style;return t=Z.cssProps[a]||(Z.cssProps[a]=C(u,a)),s=Z.cssHooks[t]||Z.cssHooks[a],void 0===n?s&&"get"in s&&void 0!==(i=s.get(e,!1,r))?i:u[t]:(o=typeof n,"string"===o&&(i=Ue.exec(n))&&(n=(i[1]+1)*i[2]+parseFloat(Z.css(e,t)),o="number"),void(null!=n&&n===n&&("number"!==o||Z.cssNumber[a]||(n+="px"),Q.clearCloneStyle||""!==n||0!==t.indexOf("background")||(u[t]="inherit"),s&&"set"in s&&void 0===(n=s.set(e,n,r))||(u[t]=n))))}},css:function(e,t,n,r){var i,o,s,a=Z.camelCase(t);return t=Z.cssProps[a]||(Z.cssProps[a]=C(e.style,a)),s=Z.cssHooks[t]||Z.cssHooks[a],s&&"get"in s&&(i=s.get(e,!0,n)),void 0===i&&(i=w(e,t,r)),"normal"===i&&t in Ye&&(i=Ye[t]),""===n||n?(o=parseFloat(i),n===!0||Z.isNumeric(o)?o||0:i):i}}),Z.each(["height","width"],function(e,t){Z.cssHooks[t]={get:function(e,n,r){return n?ze.test(Z.css(e,"display"))&&0===e.offsetWidth?Z.swap(e,Ve,function(){return E(e,t,r)}):E(e,t,r):void 0},set:function(e,n,r){var i=r&&_e(e);return N(e,n,r?k(e,t,r,"border-box"===Z.css(e,"boxSizing",!1,i),i):0)}}}),Z.cssHooks.marginRight=T(Q.reliableMarginRight,function(e,t){return t?Z.swap(e,{display:"inline-block"},w,[e,"marginRight"]):void 0}),Z.each({margin:"",padding:"",border:"Width"},function(e,t){Z.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];4>r;r++)i[e+Te[r]+t]=o[r]||o[r-2]||o[0];return i}},Ie.test(e)||(Z.cssHooks[e+t].set=N)}),Z.fn.extend({css:function(e,t){return me(this,function(e,t,n){var r,i,o={},s=0;if(Z.isArray(t)){for(r=_e(e),i=t.length;i>s;s++)o[t[s]]=Z.css(e,t[s],!1,r);return o}return void 0!==n?Z.style(e,t,n):Z.css(e,t)},e,t,arguments.length>1)},show:function(){return S(this,!0)},hide:function(){return S(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){Ce(this)?Z(this).show():Z(this).hide()})}}),Z.Tween=D,D.prototype={constructor:D,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(Z.cssNumber[n]?"":"px")},cur:function(){var e=D.propHooks[this.prop];return e&&e.get?e.get(this):D.propHooks._default.get(this)},run:function(e){var t,n=D.propHooks[this.prop];return this.pos=t=this.options.duration?Z.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):D.propHooks._default.set(this),this}},D.prototype.init.prototype=D.prototype,D.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=Z.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){Z.fx.step[e.prop]?Z.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[Z.cssProps[e.prop]]||Z.cssHooks[e.prop])?Z.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},D.propHooks.scrollTop=D.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},Z.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},Z.fx=D.prototype.init,Z.fx.step={};var Qe,Je,Ke=/^(?:toggle|show|hide)$/,Ze=new RegExp("^(?:([+-])=|)("+we+")([a-z%]*)$","i"),et=/queueHooks$/,tt=[q],nt={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Ze.exec(t),o=i&&i[3]||(Z.cssNumber[e]?"":"px"),s=(Z.cssNumber[e]||"px"!==o&&+r)&&Ze.exec(Z.css(n.elem,e)),a=1,u=20;if(s&&s[3]!==o){o=o||s[3],i=i||[],s=+r||1;do a=a||".5",s/=a,Z.style(n.elem,e,s+o);while(a!==(a=n.cur()/r)&&1!==a&&--u)}return i&&(s=n.start=+s||+r||0,n.unit=o,n.end=i[1]?s+(i[1]+1)*i[2]:+i[2]),n}]};Z.Animation=Z.extend(O,{tweener:function(e,t){Z.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");for(var n,r=0,i=e.length;i>r;r++)n=e[r],nt[n]=nt[n]||[],nt[n].unshift(t)},prefilter:function(e,t){t?tt.unshift(e):tt.push(e)}}),Z.speed=function(e,t,n){var r=e&&"object"==typeof e?Z.extend({},e):{complete:n||!n&&t||Z.isFunction(e)&&e,duration:e,easing:n&&t||t&&!Z.isFunction(t)&&t};return r.duration=Z.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in Z.fx.speeds?Z.fx.speeds[r.duration]:Z.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){Z.isFunction(r.old)&&r.old.call(this),r.queue&&Z.dequeue(this,r.queue)},r},Z.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Ce).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=Z.isEmptyObject(e),o=Z.speed(t,n,r),s=function(){var t=O(this,Z.extend({},e),o);(i||ve.get(this,"finish"))&&t.stop(!0)};return s.finish=s,i||o.queue===!1?this.each(s):this.queue(o.queue,s)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=void 0),t&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",o=Z.timers,s=ve.get(this);if(i)s[i]&&s[i].stop&&r(s[i]);else for(i in s)s[i]&&s[i].stop&&et.test(i)&&r(s[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));(t||!n)&&Z.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=ve.get(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=Z.timers,s=r?r.length:0;for(n.finish=!0,Z.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),
+o.splice(t,1));for(t=0;s>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),Z.each(["toggle","show","hide"],function(e,t){var n=Z.fn[t];Z.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(A(t,!0),e,r,i)}}),Z.each({slideDown:A("show"),slideUp:A("hide"),slideToggle:A("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){Z.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),Z.timers=[],Z.fx.tick=function(){var e,t=0,n=Z.timers;for(Qe=Z.now();t1)},removeAttr:function(e){return this.each(function(){Z.removeAttr(this,e)})}}),Z.extend({attr:function(e,t,n){var r,i,o=e.nodeType;return e&&3!==o&&8!==o&&2!==o?typeof e.getAttribute===ke?Z.prop(e,t,n):(1===o&&Z.isXMLDoc(e)||(t=t.toLowerCase(),r=Z.attrHooks[t]||(Z.expr.match.bool.test(t)?it:rt)),void 0===n?r&&"get"in r&&null!==(i=r.get(e,t))?i:(i=Z.find.attr(e,t),null==i?void 0:i):null!==n?r&&"set"in r&&void 0!==(i=r.set(e,n,t))?i:(e.setAttribute(t,n+""),n):void Z.removeAttr(e,t)):void 0},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(de);if(o&&1===e.nodeType)for(;n=o[i++];)r=Z.propFix[n]||n,Z.expr.match.bool.test(n)&&(e[r]=!1),e.removeAttribute(n)},attrHooks:{type:{set:function(e,t){if(!Q.radioValue&&"radio"===t&&Z.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}}}),it={set:function(e,t,n){return t===!1?Z.removeAttr(e,n):e.setAttribute(n,n),n}},Z.each(Z.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ot[t]||Z.find.attr;ot[t]=function(e,t,r){var i,o;return r||(o=ot[t],ot[t]=i,i=null!=n(e,t,r)?t.toLowerCase():null,ot[t]=o),i}});var st=/^(?:input|select|textarea|button)$/i;Z.fn.extend({prop:function(e,t){return me(this,Z.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[Z.propFix[e]||e]})}}),Z.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(e,t,n){var r,i,o,s=e.nodeType;return e&&3!==s&&8!==s&&2!==s?(o=1!==s||!Z.isXMLDoc(e),o&&(t=Z.propFix[t]||t,i=Z.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]):void 0},propHooks:{tabIndex:{get:function(e){return e.hasAttribute("tabindex")||st.test(e.nodeName)||e.href?e.tabIndex:-1}}}}),Q.optSelected||(Z.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null}}),Z.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){Z.propFix[this.toLowerCase()]=this});var at=/[\t\r\n\f]/g;Z.fn.extend({addClass:function(e){var t,n,r,i,o,s,a="string"==typeof e&&e,u=0,l=this.length;if(Z.isFunction(e))return this.each(function(t){Z(this).addClass(e.call(this,t,this.className))});if(a)for(t=(e||"").match(de)||[];l>u;u++)if(n=this[u],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(at," "):" ")){for(o=0;i=t[o++];)r.indexOf(" "+i+" ")<0&&(r+=i+" ");s=Z.trim(r),n.className!==s&&(n.className=s)}return this},removeClass:function(e){var t,n,r,i,o,s,a=0===arguments.length||"string"==typeof e&&e,u=0,l=this.length;if(Z.isFunction(e))return this.each(function(t){Z(this).removeClass(e.call(this,t,this.className))});if(a)for(t=(e||"").match(de)||[];l>u;u++)if(n=this[u],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(at," "):"")){for(o=0;i=t[o++];)for(;r.indexOf(" "+i+" ")>=0;)r=r.replace(" "+i+" "," ");s=e?Z.trim(r):"",n.className!==s&&(n.className=s)}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):this.each(Z.isFunction(e)?function(n){Z(this).toggleClass(e.call(this,n,this.className,t),t)}:function(){if("string"===n)for(var t,r=0,i=Z(this),o=e.match(de)||[];t=o[r++];)i.hasClass(t)?i.removeClass(t):i.addClass(t);else(n===ke||"boolean"===n)&&(this.className&&ve.set(this,"__className__",this.className),this.className=this.className||e===!1?"":ve.get(this,"__className__")||"")})},hasClass:function(e){for(var t=" "+e+" ",n=0,r=this.length;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(at," ").indexOf(t)>=0)return!0;return!1}});var ut=/\r/g;Z.fn.extend({val:function(e){var t,n,r,i=this[0];return arguments.length?(r=Z.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,Z(this).val()):e,null==i?i="":"number"==typeof i?i+="":Z.isArray(i)&&(i=Z.map(i,function(e){return null==e?"":e+""})),t=Z.valHooks[this.type]||Z.valHooks[this.nodeName.toLowerCase()],t&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))})):i?(t=Z.valHooks[i.type]||Z.valHooks[i.nodeName.toLowerCase()],t&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:(n=i.value,"string"==typeof n?n.replace(ut,""):null==n?"":n)):void 0}}),Z.extend({valHooks:{option:{get:function(e){var t=Z.find.attr(e,"value");return null!=t?t:Z.trim(Z.text(e))}},select:{get:function(e){for(var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,s=o?null:[],a=o?i+1:r.length,u=0>i?a:o?i:0;a>u;u++)if(n=r[u],!(!n.selected&&u!==i||(Q.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&Z.nodeName(n.parentNode,"optgroup"))){if(t=Z(n).val(),o)return t;s.push(t)}return s},set:function(e,t){for(var n,r,i=e.options,o=Z.makeArray(t),s=i.length;s--;)r=i[s],(r.selected=Z.inArray(r.value,o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),Z.each(["radio","checkbox"],function(){Z.valHooks[this]={set:function(e,t){return Z.isArray(t)?e.checked=Z.inArray(Z(e).val(),t)>=0:void 0}},Q.checkOn||(Z.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),Z.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){Z.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),Z.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var lt=Z.now(),ct=/\?/;Z.parseJSON=function(e){return JSON.parse(e+"")},Z.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{n=new DOMParser,t=n.parseFromString(e,"text/xml")}catch(r){t=void 0}return(!t||t.getElementsByTagName("parsererror").length)&&Z.error("Invalid XML: "+e),t};var ft=/#.*$/,pt=/([?&])_=[^&]*/,dt=/^(.*?):[ \t]*([^\r\n]*)$/gm,ht=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,gt=/^(?:GET|HEAD)$/,mt=/^\/\//,vt=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,yt={},xt={},bt="*/".concat("*"),wt=e.location.href,Tt=vt.exec(wt.toLowerCase())||[];Z.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:wt,type:"GET",isLocal:ht.test(Tt[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":bt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":Z.parseJSON,"text xml":Z.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?R(R(e,Z.ajaxSettings),t):R(Z.ajaxSettings,e)},ajaxPrefilter:F(yt),ajaxTransport:F(xt),ajax:function(e,t){function n(e,t,n,s){var u,c,v,y,b,T=t;2!==x&&(x=2,a&&clearTimeout(a),r=void 0,o=s||"",w.readyState=e>0?4:0,u=e>=200&&300>e||304===e,n&&(y=M(f,w,n)),y=W(f,y,w,u),u?(f.ifModified&&(b=w.getResponseHeader("Last-Modified"),b&&(Z.lastModified[i]=b),b=w.getResponseHeader("etag"),b&&(Z.etag[i]=b)),204===e||"HEAD"===f.type?T="nocontent":304===e?T="notmodified":(T=y.state,c=y.data,v=y.error,u=!v)):(v=T,(e||!T)&&(T="error",0>e&&(e=0))),w.status=e,w.statusText=(t||T)+"",u?h.resolveWith(p,[c,T,w]):h.rejectWith(p,[w,T,v]),w.statusCode(m),m=void 0,l&&d.trigger(u?"ajaxSuccess":"ajaxError",[w,f,u?c:v]),g.fireWith(p,[w,T]),l&&(d.trigger("ajaxComplete",[w,f]),--Z.active||Z.event.trigger("ajaxStop")))}"object"==typeof e&&(t=e,e=void 0),t=t||{};var r,i,o,s,a,u,l,c,f=Z.ajaxSetup({},t),p=f.context||f,d=f.context&&(p.nodeType||p.jquery)?Z(p):Z.event,h=Z.Deferred(),g=Z.Callbacks("once memory"),m=f.statusCode||{},v={},y={},x=0,b="canceled",w={readyState:0,getResponseHeader:function(e){var t;if(2===x){if(!s)for(s={};t=dt.exec(o);)s[t[1].toLowerCase()]=t[2];t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===x?o:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return x||(e=y[n]=y[n]||e,v[e]=t),this},overrideMimeType:function(e){return x||(f.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>x)for(t in e)m[t]=[m[t],e[t]];else w.always(e[w.status]);return this},abort:function(e){var t=e||b;return r&&r.abort(t),n(0,t),this}};if(h.promise(w).complete=g.add,w.success=w.done,w.error=w.fail,f.url=((e||f.url||wt)+"").replace(ft,"").replace(mt,Tt[1]+"//"),f.type=t.method||t.type||f.method||f.type,f.dataTypes=Z.trim(f.dataType||"*").toLowerCase().match(de)||[""],null==f.crossDomain&&(u=vt.exec(f.url.toLowerCase()),f.crossDomain=!(!u||u[1]===Tt[1]&&u[2]===Tt[2]&&(u[3]||("http:"===u[1]?"80":"443"))===(Tt[3]||("http:"===Tt[1]?"80":"443")))),f.data&&f.processData&&"string"!=typeof f.data&&(f.data=Z.param(f.data,f.traditional)),P(yt,f,t,w),2===x)return w;l=Z.event&&f.global,l&&0===Z.active++&&Z.event.trigger("ajaxStart"),f.type=f.type.toUpperCase(),f.hasContent=!gt.test(f.type),i=f.url,f.hasContent||(f.data&&(i=f.url+=(ct.test(i)?"&":"?")+f.data,delete f.data),f.cache===!1&&(f.url=pt.test(i)?i.replace(pt,"$1_="+lt++):i+(ct.test(i)?"&":"?")+"_="+lt++)),f.ifModified&&(Z.lastModified[i]&&w.setRequestHeader("If-Modified-Since",Z.lastModified[i]),Z.etag[i]&&w.setRequestHeader("If-None-Match",Z.etag[i])),(f.data&&f.hasContent&&f.contentType!==!1||t.contentType)&&w.setRequestHeader("Content-Type",f.contentType),w.setRequestHeader("Accept",f.dataTypes[0]&&f.accepts[f.dataTypes[0]]?f.accepts[f.dataTypes[0]]+("*"!==f.dataTypes[0]?", "+bt+"; q=0.01":""):f.accepts["*"]);for(c in f.headers)w.setRequestHeader(c,f.headers[c]);if(f.beforeSend&&(f.beforeSend.call(p,w,f)===!1||2===x))return w.abort();b="abort";for(c in{success:1,error:1,complete:1})w[c](f[c]);if(r=P(xt,f,t,w)){w.readyState=1,l&&d.trigger("ajaxSend",[w,f]),f.async&&f.timeout>0&&(a=setTimeout(function(){w.abort("timeout")},f.timeout));try{x=1,r.send(v,n)}catch(T){if(!(2>x))throw T;n(-1,T)}}else n(-1,"No Transport");return w},getJSON:function(e,t,n){return Z.get(e,t,n,"json")},getScript:function(e,t){return Z.get(e,void 0,t,"script")}}),Z.each(["get","post"],function(e,t){Z[t]=function(e,n,r,i){return Z.isFunction(n)&&(i=i||r,r=n,n=void 0),Z.ajax({url:e,type:t,dataType:i,data:n,success:r})}}),Z._evalUrl=function(e){return Z.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},Z.fn.extend({wrapAll:function(e){var t;return Z.isFunction(e)?this.each(function(t){Z(this).wrapAll(e.call(this,t))}):(this[0]&&(t=Z(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this)},wrapInner:function(e){return this.each(Z.isFunction(e)?function(t){Z(this).wrapInner(e.call(this,t))}:function(){var t=Z(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=Z.isFunction(e);return this.each(function(n){Z(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){Z.nodeName(this,"body")||Z(this).replaceWith(this.childNodes)}).end()}}),Z.expr.filters.hidden=function(e){return e.offsetWidth<=0&&e.offsetHeight<=0},Z.expr.filters.visible=function(e){return!Z.expr.filters.hidden(e)};var Ct=/%20/g,Nt=/\[\]$/,kt=/\r?\n/g,Et=/^(?:submit|button|image|reset|file)$/i,St=/^(?:input|select|textarea|keygen)/i;Z.param=function(e,t){var n,r=[],i=function(e,t){t=Z.isFunction(t)?t():null==t?"":t,r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(void 0===t&&(t=Z.ajaxSettings&&Z.ajaxSettings.traditional),Z.isArray(e)||e.jquery&&!Z.isPlainObject(e))Z.each(e,function(){i(this.name,this.value)});else for(n in e)$(n,e[n],t,i);return r.join("&").replace(Ct,"+")},Z.fn.extend({serialize:function(){return Z.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=Z.prop(this,"elements");return e?Z.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!Z(this).is(":disabled")&&St.test(this.nodeName)&&!Et.test(e)&&(this.checked||!Ne.test(e))}).map(function(e,t){var n=Z(this).val();return null==n?null:Z.isArray(n)?Z.map(n,function(e){return{name:t.name,value:e.replace(kt,"\r\n")}}):{name:t.name,value:n.replace(kt,"\r\n")}}).get()}}),Z.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(e){}};var Dt=0,jt={},At={0:200,1223:204},Lt=Z.ajaxSettings.xhr();e.attachEvent&&e.attachEvent("onunload",function(){for(var e in jt)jt[e]()}),Q.cors=!!Lt&&"withCredentials"in Lt,Q.ajax=Lt=!!Lt,Z.ajaxTransport(function(e){var t;return Q.cors||Lt&&!e.crossDomain?{send:function(n,r){var i,o=e.xhr(),s=++Dt;if(o.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(i in e.xhrFields)o[i]=e.xhrFields[i];e.mimeType&&o.overrideMimeType&&o.overrideMimeType(e.mimeType),e.crossDomain||n["X-Requested-With"]||(n["X-Requested-With"]="XMLHttpRequest");for(i in n)o.setRequestHeader(i,n[i]);t=function(e){return function(){t&&(delete jt[s],t=o.onload=o.onerror=null,"abort"===e?o.abort():"error"===e?r(o.status,o.statusText):r(At[o.status]||o.status,o.statusText,"string"==typeof o.responseText?{text:o.responseText}:void 0,o.getAllResponseHeaders()))}},o.onload=t(),o.onerror=t("error"),t=jt[s]=t("abort");try{o.send(e.hasContent&&e.data||null)}catch(a){if(t)throw a}},abort:function(){t&&t()}}:void 0}),Z.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return Z.globalEval(e),e}}}),Z.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),Z.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(r,i){t=Z("
+
+