<commit_before>/*
 * jQuery UI Dialog
 *
 * Copyright (c) 2008 Richard D. Worth (rdworth.org)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Dialog
 *
 * Depends:
 *	ui.core.js
 *	ui.draggable.js
 *	ui.resizable.js
 *
 * Revision: $Id: ui.dialog.js 5608 2008-05-15 14:41:12Z scott.gonzalez $
 */
(function($) {

var setDataSwitch = {
	dragStart: "start.draggable",
	drag: "drag.draggable",
	dragStop: "stop.draggable",
	maxHeight: "maxHeight.resizable",
	minHeight: "minHeight.resizable",
	maxWidth: "maxWidth.resizable",
	minWidth: "minWidth.resizable",
	resizeStart: "start.resizable",
	resize: "drag.resizable",
	resizeStop: "stop.resizable"
};

$.widget("ui.dialog", {
	init: function() {
		var self = this,
			options = this.options,
			resizeHandles = typeof options.resizable == 'string'
				? options.resizable
				: 'n,e,s,w,se,sw,ne,nw',

			uiDialogContent = this.element
				.addClass('ui-dialog-content')
				.wrap('
')
				.wrap('
'),

			uiDialogContainer = uiDialogContent.parent()
				.addClass('ui-dialog-container')
				.css({position: 'relative'}),

			title = options.title || uiDialogContent.attr('title') || '',
			uiDialogTitlebar = (this.uiDialogTitlebar =
				$('
'))
				.append('' + title + '')
				.append('X')
				.prependTo(uiDialogContainer),

			uiDialog = (this.uiDialog = uiDialogContainer.parent())
				.hide()
				.appendTo(document.body)
				.addClass('ui-dialog')
				.addClass(options.dialogClass)
				// add content classes to dialog
				// to inherit theme at top level of element
				.addClass(uiDialogContent.attr('className'))
					.removeClass('ui-dialog-content')
				.css({
					position: 'absolute',
					width: options.width,
					height: options.height,
					overflow: 'hidden',
					zIndex: options.zIndex
				})
				// setting tabIndex makes the div focusable
				// setting outline to 0 prevents a border on focus in Mozilla
				.attr('tabIndex', -1).css('outline', 0).keydown(function(ev) {
					if (options.closeOnEscape) {
						var ESC = 27;
						(ev.keyCode && ev.keyCode == ESC && self.close());
					}
				})
				.mousedown(function() {
					self.moveToTop();
				});

		this.uiDialogTitlebarClose = $('.ui-dialog-titlebar-close', uiDialogTitlebar)
			.hover(
				function() {
					$(this).addClass('ui-dialog-titlebar-close-hover');
				},
				function() {
					$(this).removeClass('ui-dialog-titlebar-close-hover');
				}
			)
			.mousedown(function(ev) {
				ev.stopPropagation();
			})
			.click(function() {
				self.close();
				return false;
			});

		var hasButtons = false;
		$.each(options.buttons, function() { return !(hasButtons = true); });
		if (hasButtons) {
			var uiDialogButtonPane = $('
')
				.appendTo(uiDialog);
			$.each(options.buttons, function(name, fn) {
				$('<button/>')
					.text(name)
					.click(function() { fn.apply(self.element, arguments); })
					.appendTo(uiDialogButtonPane);
			});
		}

		if ($.fn.draggable) {
			uiDialog.draggable({
				handle: '.ui-dialog-titlebar',
				start: function(e, ui) {
					self.moveToTop();
					(options.dragStart && options.dragStart.apply(this, arguments));
				},
				drag: options.drag,
				stop: function(e, ui) {
					(options.dragStop && options.dragStop.apply(this, arguments));
					$.ui.dialog.overlay.resize();
				}
			});
			(options.draggable || uiDialog.draggable('disable'));
		}

		if ($.fn.resizable) {
			uiDialog.resizable({
				maxWidth: options.maxWidth,
				maxHeight: options.maxHeight,
				minWidth: options.minWidth,
				minHeight: options.minHeight,
				start: options.resizeStart,
				resize: options.resize,
				handles: resizeHandles,
				stop: function(e, ui) {
					(options.resizeStop && options.resizeStop.apply(this, arguments));
					$.ui.dialog.overlay.resize();
				}
			});
			(options.resizable || uiDialog.resizable('disable'));
		}

		(options.bgiframe && $.fn.bgiframe && uiDialog.bgiframe());
		(options.autoOpen && this.open());
	},

	setData: function(key, value){
		(setDataSwitch[key] && this.uiDialog.data(setDataSwitch[key], value));
		switch (key) {
			case "draggable":
				this.uiDialog.draggable(value ? 'enable' : 'disable');
				break;
			case "height":
				this.uiDialog.height(value);
				break;
			case "position":
				this.position(value);
				break;
			case "resizable":
				(typeof value == 'string' && this.uiDialog.data('handles.resizable', value));
				this.uiDialog.resizable(value ? 'enable' : 'disable');
				break;
			case "title":
				$(".ui-dialog-title", this.uiDialogTitlebar).text(value);
				break;
			case "width":
				this.uiDialog.width(value);
				break;
		}

		$.widget.prototype.setData.apply(this, arguments);
	},

	position: function(pos) {
		var wnd = $(window), doc = $(document),
			pTop = doc.scrollTop(), pLeft = doc.scrollLeft(),
			minTop = pTop;

		if ($.inArray(pos, ['center','top','right','bottom','left']) >= 0) {
			pos = [
				pos == 'right' || pos == 'left' ? pos : 'center',
				pos == 'top' || pos == 'bottom' ? pos : 'middle'
			];
		}
		if (pos.constructor != Array) {
			pos = ['center', 'middle'];
		}
		if (pos[0].constructor == Number) {
			pLeft += pos[0];
		} else {
			switch (pos[0]) {
				case 'left':
					pLeft += 0;
					break;
				case 'right':
					pLeft += (wnd.width()) - (this.uiDialog.width());
					break;
				default:
				case 'center':
					pLeft += (wnd.width() / 2) - (this.uiDialog.width() / 2);
			}
		}
		if (pos[1].constructor == Number) {
			pTop += pos[1];
		} else {
			switch (pos[1]) {
				case 'top':
					pTop += 0;
					break;
				case 'bottom':
					pTop += (wnd.height()) - (this.uiDialog.height());
					break;
				default:
				case 'middle':
					pTop += (wnd.height() / 2) - (this.uiDialog.height() / 2);
			}
		}

		// prevent the dialog from being too high (make sure the titlebar
		// is accessible)
		pTop = Math.max(pTop, minTop);
		this.uiDialog.css({top: pTop, left: pLeft});
	},

	open: function() {
		this.overlay = this.options.modal ? new $.ui.dialog.overlay(this) : null;
		this.uiDialog.appendTo('body');
		this.position(this.options.position);
		this.uiDialog.show();
		this.moveToTop(true);

		// CALLBACK: open
		var openEV = null;
		var openUI = {
			options: this.options
		};
		this.uiDialogTitlebarClose.focus();
		this.element.triggerHandler("dialogopen", [openEV, openUI], this.options.open);
	},

	// the force parameter allows us to move modal dialogs to their correct
	// position on open
	moveToTop: function(force) {
		if ((this.options.modal && !force) || !this.options.stack) { return; }

		var maxZ = this.options.zIndex, options = this.options;
		$('.ui-dialog:visible').each(function() {
			maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10) || options.zIndex);
		});
		(this.overlay && this.overlay.$el.css('z-index', ++maxZ));
		this.uiDialog.css('z-index', ++maxZ);
	},

	close: function() {
		(this.overlay && this.overlay.destroy());
		this.uiDialog.hide();

		// CALLBACK: close
		var closeEV = null;
		var closeUI = {
			options: this.options
		};
		this.element.triggerHandler("dialogclose", [closeEV, closeUI], this.options.close);
		$.ui.dialog.overlay.resize();
	},

	destroy: function() {
		(this.overlay && this.overlay.destroy());
		this.uiDialog.hide();
		this.element
			.unbind('.dialog')
			.removeData('dialog')
			.removeClass('ui-dialog-content')
			.hide().appendTo('body');
		this.uiDialog.remove();
	}
});

$.extend($.ui.dialog, {
	defaults: {
		autoOpen: true,
		bgiframe: false,
		buttons: {},
		closeOnEscape: true,
		draggable: true,
		height: 200,
		minHeight: 100,
		minWidth: 150,
		modal: false,
		overlay: {},
		position: 'center',
		resizable: true,
		stack: true,
		width: 300,
		zIndex: 1000
	},

	overlay: function(dialog) {
		this.$el = $.ui.dialog.overlay.create(dialog);
	}
});

$.extend($.ui.dialog.overlay, {
	instances: [],
	events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
		function(e) { return e + '.dialog-overlay'; }).join(' '),
	create: function(dialog) {
		if (this.instances.length === 0) {
			// prevent use of anchors and inputs
			// we use a setTimeout in case the overlay is created from an
			// event that we're going to be cancelling (see #2804)
			setTimeout(function() {
				$('a, :input').bind($.ui.dialog.overlay.events, function() {
					// allow use of the element if inside a dialog and
					// - there are no modal dialogs
					// - there are modal dialogs, but we are in front of the topmost modal
					var allow = false;
					var $dialog = $(this).parents('.ui-dialog');
					if ($dialog.length) {
						var $overlays = $('.ui-dialog-overlay');
						if ($overlays.length) {
							var maxZ = parseInt($overlays.css('z-index'), 10);
							$overlays.each(function() {
								maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10));
							});
							allow = parseInt($dialog.css('z-index'), 10) > maxZ;
						} else {
							allow = true;
						}
					}
					return allow;
				});
			}, 1);

			// allow closing by pressing the escape key
			$(document).bind('keydown.dialog-overlay', function(e) {
				var ESC = 27;
				(e.keyCode && e.keyCode == ESC && dialog.close());
			});

			// handle window resize
			$(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
		}

		var $el = $('
').appendTo(document.body)
			.addClass('ui-dialog-overlay').css($.extend({
				borderWidth: 0, margin: 0, padding: 0,
				position: 'absolute', top: 0, left: 0,
				width: this.width(),
				height: this.height()
			}, dialog.options.overlay));

		(dialog.options.bgiframe && $.fn.bgiframe && $el.bgiframe());

		this.instances.push($el);
		return $el;
	},

	destroy: function($el) {
		this.instances.splice($.inArray(this.instances, $el), 1);

		if (this.instances.length === 0) {
			$('a, :input').add([document, window]).unbind('.dialog-overlay');
		}

		$el.remove();
	},

	height: function() {
		if ($.browser.msie && $.browser.version < 7) {
			var scrollHeight = Math.max(
				document.documentElement.scrollHeight,
				document.body.scrollHeight
			);
			var offsetHeight = Math.max(
				document.documentElement.offsetHeight,
				document.body.offsetHeight
			);

			if (scrollHeight < offsetHeight) {
				return $(window).height() + 'px';
			} else {
				return scrollHeight + 'px';
			}
		} else {
			return $(document).height() + 'px';
		}
	},

	width: function() {
		if ($.browser.msie && $.browser.version < 7) {
			var scrollWidth = Math.max(
				document.documentElement.scrollWidth,
				document.body.scrollWidth
			);
			var offsetWidth = Math.max(
				document.documentElement.offsetWidth,
				document.body.offsetWidth
			);

			if (scrollWidth < offsetWidth) {
				return $(window).width() + 'px';
			} else {
				return scrollWidth + 'px';
			}
		} else {
			return $(document).width() + 'px';
		}
	},

	resize: function() {
		/* If the dialog is draggable and the user drags it past the
		 * right edge of the window, the document becomes wider so we
		 * need to stretch the overlay. If the user then drags the
		 * dialog back to the left, the document will become narrower,
		 * so we need to shrink the overlay to the appropriate size.
		 * This is handled by shrinking the overlay before setting it
		 * to the full document size.
		 */
		var $overlays = $([]);
		$.each($.ui.dialog.overlay.instances, function() {
			$overlays = $overlays.add(this);
		});

		$overlays.css({
			width: 0,
			height: 0
		}).css({
			width: $.ui.dialog.overlay.width(),
			height: $.ui.dialog.overlay.height()
		});
	}
});

$.extend($.ui.dialog.overlay.prototype, {
	destroy: function() {
		$.ui.dialog.overlay.destroy(this.$el);
	}
});

})(jQuery);
<commit_msg>Dialog: Removed unneeded parens.<commit_after>/*
 * jQuery UI Dialog
 *
 * Copyright (c) 2008 Richard D. Worth (rdworth.org)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Dialog
 *
 * Depends:
 *	ui.core.js
 *	ui.draggable.js
 *	ui.resizable.js
 *
 * Revision: $Id: ui.dialog.js 5608 2008-05-15 14:41:12Z scott.gonzalez $
 */
(function($) {

var setDataSwitch = {
	dragStart: "start.draggable",
	drag: "drag.draggable",
	dragStop: "stop.draggable",
	maxHeight: "maxHeight.resizable",
	minHeight: "minHeight.resizable",
	maxWidth: "maxWidth.resizable",
	minWidth: "minWidth.resizable",
	resizeStart: "start.resizable",
	resize: "drag.resizable",
	resizeStop: "stop.resizable"
};

$.widget("ui.dialog", {
	init: function() {
		var self = this,
			options = this.options,
			resizeHandles = typeof options.resizable == 'string'
				? options.resizable
				: 'n,e,s,w,se,sw,ne,nw',

			uiDialogContent = this.element
				.addClass('ui-dialog-content')
				.wrap('
')
				.wrap('
'),

			uiDialogContainer = uiDialogContent.parent()
				.addClass('ui-dialog-container')
				.css({position: 'relative'}),

			title = options.title || uiDialogContent.attr('title') || '',
			uiDialogTitlebar = (this.uiDialogTitlebar =
				$('
'))
				.append('' + title + '')
				.append('X')
				.prependTo(uiDialogContainer),

			uiDialog = (this.uiDialog = uiDialogContainer.parent())
				.hide()
				.appendTo(document.body)
				.addClass('ui-dialog')
				.addClass(options.dialogClass)
				// add content classes to dialog
				// to inherit theme at top level of element
				.addClass(uiDialogContent.attr('className'))
					.removeClass('ui-dialog-content')
				.css({
					position: 'absolute',
					width: options.width,
					height: options.height,
					overflow: 'hidden',
					zIndex: options.zIndex
				})
				// setting tabIndex makes the div focusable
				// setting outline to 0 prevents a border on focus in Mozilla
				.attr('tabIndex', -1).css('outline', 0).keydown(function(ev) {
					if (options.closeOnEscape) {
						var ESC = 27;
						(ev.keyCode && ev.keyCode == ESC && self.close());
					}
				})
				.mousedown(function() {
					self.moveToTop();
				});

		this.uiDialogTitlebarClose = $('.ui-dialog-titlebar-close', uiDialogTitlebar)
			.hover(
				function() {
					$(this).addClass('ui-dialog-titlebar-close-hover');
				},
				function() {
					$(this).removeClass('ui-dialog-titlebar-close-hover');
				}
			)
			.mousedown(function(ev) {
				ev.stopPropagation();
			})
			.click(function() {
				self.close();
				return false;
			});

		var hasButtons = false;
		$.each(options.buttons, function() { return !(hasButtons = true); });
		if (hasButtons) {
			var uiDialogButtonPane = $('
')
				.appendTo(uiDialog);
			$.each(options.buttons, function(name, fn) {
				$('<button/>')
					.text(name)
					.click(function() { fn.apply(self.element, arguments); })
					.appendTo(uiDialogButtonPane);
			});
		}

		if ($.fn.draggable) {
			uiDialog.draggable({
				handle: '.ui-dialog-titlebar',
				start: function(e, ui) {
					self.moveToTop();
					(options.dragStart && options.dragStart.apply(this, arguments));
				},
				drag: options.drag,
				stop: function(e, ui) {
					(options.dragStop && options.dragStop.apply(this, arguments));
					$.ui.dialog.overlay.resize();
				}
			});
			(options.draggable || uiDialog.draggable('disable'));
		}

		if ($.fn.resizable) {
			uiDialog.resizable({
				maxWidth: options.maxWidth,
				maxHeight: options.maxHeight,
				minWidth: options.minWidth,
				minHeight: options.minHeight,
				start: options.resizeStart,
				resize: options.resize,
				handles: resizeHandles,
				stop: function(e, ui) {
					(options.resizeStop && options.resizeStop.apply(this, arguments));
					$.ui.dialog.overlay.resize();
				}
			});
			(options.resizable || uiDialog.resizable('disable'));
		}

		(options.bgiframe && $.fn.bgiframe && uiDialog.bgiframe());
		(options.autoOpen && this.open());
	},

	setData: function(key, value){
		(setDataSwitch[key] && this.uiDialog.data(setDataSwitch[key], value));
		switch (key) {
			case "draggable":
				this.uiDialog.draggable(value ? 'enable' : 'disable');
				break;
			case "height":
				this.uiDialog.height(value);
				break;
			case "position":
				this.position(value);
				break;
			case "resizable":
				(typeof value == 'string' && this.uiDialog.data('handles.resizable', value));
				this.uiDialog.resizable(value ? 'enable' : 'disable');
				break;
			case "title":
				$(".ui-dialog-title", this.uiDialogTitlebar).text(value);
				break;
			case "width":
				this.uiDialog.width(value);
				break;
		}

		$.widget.prototype.setData.apply(this, arguments);
	},

	position: function(pos) {
		var wnd = $(window), doc = $(document),
			pTop = doc.scrollTop(), pLeft = doc.scrollLeft(),
			minTop = pTop;

		if ($.inArray(pos, ['center','top','right','bottom','left']) >= 0) {
			pos = [
				pos == 'right' || pos == 'left' ? pos : 'center',
				pos == 'top' || pos == 'bottom' ? pos : 'middle'
			];
		}
		if (pos.constructor != Array) {
			pos = ['center', 'middle'];
		}
		if (pos[0].constructor == Number) {
			pLeft += pos[0];
		} else {
			switch (pos[0]) {
				case 'left':
					pLeft += 0;
					break;
				case 'right':
					pLeft += wnd.width() - this.uiDialog.width();
					break;
				default:
				case 'center':
					pLeft += (wnd.width() - this.uiDialog.width()) / 2;
			}
		}
		if (pos[1].constructor == Number) {
			pTop += pos[1];
		} else {
			switch (pos[1]) {
				case 'top':
					pTop += 0;
					break;
				case 'bottom':
					pTop += wnd.height() - this.uiDialog.height();
					break;
				default:
				case 'middle':
					pTop += (wnd.height() - this.uiDialog.height()) / 2;
			}
		}

		// prevent the dialog from being too high (make sure the titlebar
		// is accessible)
		pTop = Math.max(pTop, minTop);
		this.uiDialog.css({top: pTop, left: pLeft});
	},

	open: function() {
		this.overlay = this.options.modal ? new $.ui.dialog.overlay(this) : null;
		this.uiDialog.appendTo('body');
		this.position(this.options.position);
		this.uiDialog.show();
		this.moveToTop(true);

		// CALLBACK: open
		var openEV = null;
		var openUI = {
			options: this.options
		};
		this.uiDialogTitlebarClose.focus();
		this.element.triggerHandler("dialogopen", [openEV, openUI], this.options.open);
	},

	// the force parameter allows us to move modal dialogs to their correct
	// position on open
	moveToTop: function(force) {
		if ((this.options.modal && !force) || !this.options.stack) { return; }

		var maxZ = this.options.zIndex, options = this.options;
		$('.ui-dialog:visible').each(function() {
			maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10) || options.zIndex);
		});
		(this.overlay && this.overlay.$el.css('z-index', ++maxZ));
		this.uiDialog.css('z-index', ++maxZ);
	},

	close: function() {
		(this.overlay && this.overlay.destroy());
		this.uiDialog.hide();

		// CALLBACK: close
		var closeEV = null;
		var closeUI = {
			options: this.options
		};
		this.element.triggerHandler("dialogclose", [closeEV, closeUI], this.options.close);
		$.ui.dialog.overlay.resize();
	},

	destroy: function() {
		(this.overlay && this.overlay.destroy());
		this.uiDialog.hide();
		this.element
			.unbind('.dialog')
			.removeData('dialog')
			.removeClass('ui-dialog-content')
			.hide().appendTo('body');
		this.uiDialog.remove();
	}
});

$.extend($.ui.dialog, {
	defaults: {
		autoOpen: true,
		bgiframe: false,
		buttons: {},
		closeOnEscape: true,
		draggable: true,
		height: 200,
		minHeight: 100,
		minWidth: 150,
		modal: false,
		overlay: {},
		position: 'center',
		resizable: true,
		stack: true,
		width: 300,
		zIndex: 1000
	},

	overlay: function(dialog) {
		this.$el = $.ui.dialog.overlay.create(dialog);
	}
});

$.extend($.ui.dialog.overlay, {
	instances: [],
	events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
		function(e) { return e + '.dialog-overlay'; }).join(' '),
	create: function(dialog) {
		if (this.instances.length === 0) {
			// prevent use of anchors and inputs
			// we use a setTimeout in case the overlay is created from an
			// event that we're going to be cancelling (see #2804)
			setTimeout(function() {
				$('a, :input').bind($.ui.dialog.overlay.events, function() {
					// allow use of the element if inside a dialog and
					// - there are no modal dialogs
					// - there are modal dialogs, but we are in front of the topmost modal
					var allow = false;
					var $dialog = $(this).parents('.ui-dialog');
					if ($dialog.length) {
						var $overlays = $('.ui-dialog-overlay');
						if ($overlays.length) {
							var maxZ = parseInt($overlays.css('z-index'), 10);
							$overlays.each(function() {
								maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10));
							});
							allow = parseInt($dialog.css('z-index'), 10) > maxZ;
						} else {
							allow = true;
						}
					}
					return allow;
				});
			}, 1);

			// allow closing by pressing the escape key
			$(document).bind('keydown.dialog-overlay', function(e) {
				var ESC = 27;
				(e.keyCode && e.keyCode == ESC && dialog.close());
			});

			// handle window resize
			$(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
		}

		var $el = $('
').appendTo(document.body)
			.addClass('ui-dialog-overlay').css($.extend({
				borderWidth: 0, margin: 0, padding: 0,
				position: 'absolute', top: 0, left: 0,
				width: this.width(),
				height: this.height()
			}, dialog.options.overlay));

		(dialog.options.bgiframe && $.fn.bgiframe && $el.bgiframe());

		this.instances.push($el);
		return $el;
	},

	destroy: function($el) {
		this.instances.splice($.inArray(this.instances, $el), 1);

		if (this.instances.length === 0) {
			$('a, :input').add([document, window]).unbind('.dialog-overlay');
		}

		$el.remove();
	},

	height: function() {
		if ($.browser.msie && $.browser.version < 7) {
			var scrollHeight = Math.max(
				document.documentElement.scrollHeight,
				document.body.scrollHeight
			);
			var offsetHeight = Math.max(
				document.documentElement.offsetHeight,
				document.body.offsetHeight
			);

			if (scrollHeight < offsetHeight) {
				return $(window).height() + 'px';
			} else {
				return scrollHeight + 'px';
			}
		} else {
			return $(document).height() + 'px';
		}
	},

	width: function() {
		if ($.browser.msie && $.browser.version < 7) {
			var scrollWidth = Math.max(
				document.documentElement.scrollWidth,
				document.body.scrollWidth
			);
			var offsetWidth = Math.max(
				document.documentElement.offsetWidth,
				document.body.offsetWidth
			);

			if (scrollWidth < offsetWidth) {
				return $(window).width() + 'px';
			} else {
				return scrollWidth + 'px';
			}
		} else {
			return $(document).width() + 'px';
		}
	},

	resize: function() {
		/* If the dialog is draggable and the user drags it past the
		 * right edge of the window, the document becomes wider so we
		 * need to stretch the overlay. If the user then drags the
		 * dialog back to the left, the document will become narrower,
		 * so we need to shrink the overlay to the appropriate size.
		 * This is handled by shrinking the overlay before setting it
		 * to the full document size.
		 */
		var $overlays = $([]);
		$.each($.ui.dialog.overlay.instances, function() {
			$overlays = $overlays.add(this);
		});

		$overlays.css({
			width: 0,
			height: 0
		}).css({
			width: $.ui.dialog.overlay.width(),
			height: $.ui.dialog.overlay.height()
		});
	}
});

$.extend($.ui.dialog.overlay.prototype, {
	destroy: function() {
		$.ui.dialog.overlay.destroy(this.$el);
	}
});

})(jQuery);
<|endoftext|>


<commit_before>// Start of Async Drift Code
$(document).ready(function() {
  !function() {
    var t;
    if (t = window.driftt = window.drift = window.driftt || [], !t.init) return t.invoked ? void (window.console && console.error && console.error("Drift snippet included twice.")) : (t.invoked = !0,
    t.methods = [ "identify", "config", "track", "reset", "debug", "show", "ping", "page", "hide", "off", "on" ],
    t.factory = function(e) {
      return function() {
        var n;
        return n = Array.prototype.slice.call(arguments), n.unshift(e), t.push(n), t;
      };
    }, t.methods.forEach(function(e) {
      t[e] = t.factory(e);
    }), t.load = function(t) {
      var e, n, o, i;
      e = 3e5, i = Math.ceil(new Date() / e) * e, o = document.createElement("script"),
      o.type = "text/javascript", o.async = !0, o.crossorigin = "anonymous", o.src = "https://js.driftt.com/include/" + i + "/" + t + ".js",
      n = document.getElementsByTagName("script")[0], n.parentNode.insertBefore(o, n);
    });
  }();
  drift.SNIPPET_VERSION = '0.3.1';
  drift.load('wmmk7c67hfg2');
});
// End of Async Drift Code -->

// Start of Drift events for Google Analytics
$(document).ready(function() {
  drift.on('ready', function(api) {
    drift.on('welcomeMessage:open', function() {
      ga('send', 'event', {
        'eventCategory': 'Drift Widget',
        'eventAction': 'Drift Clicked Button',
        'eventLabel': event.conversationId,
      });
    });
    drift.on('startConversation', function(event) {
      ga('send', 'event', {
        'eventCategory': 'Drift Widget',
        'eventAction': 'Drift Started Conversation',
        'eventLabel': event.conversationId,
      });
    });
    drift.on('sidebarOpen', function(event) {
      ga('send', 'event', {
        'eventCategory': 'Drift Widget',
        'eventAction': 'Drift Continued Conversation',
        'eventLabel': event.conversationId,
      });
    });
  });
});
// End of Drift events for Google Analytics
<commit_msg>Remove jQuery from Drift setup<commit_after>// Start of Async Drift Code
/* eslint-disable */
function ready(fn) {
  if (document.attachEvent ? document.readyState === 'complete' : document.readyState !== 'loading') {
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}

ready(function() {
  (!function() {
    var t;
    if (t = window.driftt = window.drift = window.driftt || [], !t.init) return t.invoked ? void (window.console && console.error && console.error("Drift snippet included twice.")) : (t.invoked = !0,
    t.methods = [ "identify", "config", "track", "reset", "debug", "show", "ping", "page", "hide", "off", "on" ],
    t.factory = function(e) {
      return function() {
        var n;
        return n = Array.prototype.slice.call(arguments), n.unshift(e), t.push(n), t;
      };
    }, t.methods.forEach(function(e) {
      t[e] = t.factory(e);
    }), t.load = function(t) {
      var e, n, o, i;
      e = 3e5, i = Math.ceil(new Date() / e) * e, o = document.createElement("script"),
      o.type = "text/javascript", o.async = !0, o.crossorigin = "anonymous", o.src = "https://js.driftt.com/include/" + i + "/" + t + ".js",
      n = document.getElementsByTagName("script")[0], n.parentNode.insertBefore(o, n);
    });
  })();

  drift.SNIPPET_VERSION = '0.3.1';
  drift.load('wmmk7c67hfg2');

  drift.on('ready', function() {
    drift.on('welcomeMessage:open', function() {
      ga('send', 'event', {
        'eventCategory': 'Drift Widget',
        'eventAction': 'Drift Clicked Button',
        'eventLabel': event.conversationId,
      });
    });
    drift.on('startConversation', function(event) {
      ga('send', 'event', {
        'eventCategory': 'Drift Widget',
        'eventAction': 'Drift Started Conversation',
        'eventLabel': event.conversationId,
      });
    });
    drift.on('sidebarOpen', function(event) {
      ga('send', 'event', {
        'eventCategory': 'Drift Widget',
        'eventAction': 'Drift Continued Conversation',
        'eventLabel': event.conversationId,
      });
    });
  });
});
// End of Async Drift Code -->
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// @flow

import * as React from 'react';
import classNames from 'classnames';
import {
  formatNumber,
  formatPercent,
  formatBytes,
  formatMicroseconds,
  formatMilliseconds,
  formatValueTotal,
} from '../../utils/format-numbers';
import explicitConnect from '../../utils/connect';
import { selectorsForThread } from '../../reducers/profile-view';
import { getImplementationFilter } from '../../reducers/url-state';

import Backtrace from './Backtrace';

import { bailoutTypeInformation } from '../../profile-logic/marker-info';
import type { TracingMarker } from '../../types/profile-derived';
import type { NotVoidOrNull } from '../../types/utils';
import type { ImplementationFilter } from '../../types/actions';
import type { Thread, ThreadIndex } from '../../types/profile';
import type {
  DOMEventMarkerPayload,
  PaintProfilerMarkerTracing,
  StyleMarkerPayload,
} from '../../types/markers';
import type {
  ExplicitConnectOptions,
  ConnectedProps,
} from '../../utils/connect';

function _markerDetail<T: NotVoidOrNull>(
  key: string,
  label: string,
  value: T,
  fn: T => string = String
): React.Node {
  return [

      {label}:

,
    fn(value),
  ];
}

function _markerDetailNullable<T: NotVoidOrNull>(
  key: string,
  label: string,
  value: T | void | null,
  fn: T => string = String
): React.Node {
  if (value === undefined || value === null) {
    return null;
  }
  return _markerDetail(key, label, value, fn);
}

function _markerDetailDeltaTimeNullable(
  key: string,
  label: string,
  value1?: number,
  value2?: number
): React.Node {
  if (
    value1 === undefined ||
    value2 === undefined ||
    value1 === null ||
    value2 === null
  ) {
    return null;
  }
  const valueResult = value1 - value2;
  return _markerDetail(key, label, formatMilliseconds(valueResult));
}

function _markerBacktrace(
  marker: TracingMarker,
  data: StyleMarkerPayload | PaintProfilerMarkerTracing | DOMEventMarkerPayload,
  thread: Thread,
  implementationFilter: ImplementationFilter
): React.Node {
  if (data.category === 'DOMEvent') {
    const latency =
      data.timeStamp === undefined
        ? null
        : formatMilliseconds(marker.start - data.timeStamp);
    return (

        {_markerDetail('type', 'Type', data.eventType)}
        {latency === null ? null : _markerDetail('latency', 'Latency', latency)}

    );
  }
  if ('cause' in data && data.cause) {
    const { cause } = data;
    const causeAge = marker.start - cause.time;
    return (

          First invalidated {formatNumber(causeAge)}ms before the flush, at:

        <Backtrace
          cause={cause}
          thread={thread}
          implementationFilter={implementationFilter}
        />

    );
  }
  return null;
}

function getMarkerDetails(
  marker: TracingMarker,
  thread: Thread,
  implementationFilter: ImplementationFilter
): React.Node {
  const data = marker.data;
  if (data) {
    switch (data.type) {
      case 'UserTiming': {
        return (

            {_markerDetail('name', 'Name', data.name)}

        );
      }
      case 'GCMinor': {
        if (data.nursery) {
          const nursery = data.nursery;
          switch (nursery.status) {
            case 'complete': {
              return (

                  {_markerDetail('gcreason', 'Reason', nursery.reason)}
                  {_markerDetail(
                    'gcpromotion',
                    'Bytes tenured',
                    formatValueTotal(
                      nursery.bytes_tenured,
                      nursery.bytes_used,
                      formatBytes
                    )
                  )}
                  {nursery.cur_capacity === undefined
                    ? null
                    : _markerDetail(
                        'gcnurseryusage',
                        'Bytes used',
                        formatValueTotal(
                          nursery.bytes_used,
                          nursery.cur_capacity,
                          formatBytes
                        )
                      )}
                  {nursery.new_capacity === undefined
                    ? null
                    : _markerDetail(
                        'gcnewnurserysize',
                        'New nursery size',
                        nursery.new_capacity,
                        formatBytes
                      )}
                  {nursery.lazy_capacity === undefined
                    ? null
                    : _markerDetail(
                        'gclazynurserysize',
                        'Lazy-allocated size',
                        nursery.lazy_capacity,
                        formatBytes
                      )}
                  {nursery.chunk_alloc_us === undefined
                    ? null
                    : _markerDetail(
                        'gctimeinchunkalloc',
                        'Time spent allocating chunks in mutator',
                        nursery.chunk_alloc_us,
                        formatMicroseconds
                      )}

              );
            }
            case 'nursery disabled':
              return (

                  {_markerDetail('gcstatus', 'Status', 'Nursery disabled')}

              );
            case 'nursery empty':
              return (

                  {_markerDetail('gcstatus', 'Status', 'Nursery empty')}

              );
            default:
              return null;
          }
        } else {
          return null;
        }
      }
      case 'GCMajor': {
        const timings = data.timings;
        switch (timings.status) {
          case 'aborted':
            return (

                {_markerDetail('status', 'Status', 'Aborted (OOM)')}

            );
          case 'completed': {
            let nonIncrementalReason;
            if (
              timings.nonincremental_reason &&
              timings.nonincremental_reason !== 'None'
            ) {
              nonIncrementalReason = _markerDetail(
                'gcnonincrementalreason',
                'Non-incremental reason',
                timings.nonincremental_reason
              );
            }
            return (

                {_markerDetail('gcreason', 'Reason', timings.reason)}
                {nonIncrementalReason}
                {_markerDetail(
                  'gctime',
                  'Total slice times',
                  timings.total_time,
                  x =>
                    formatMilliseconds(
                      x,
                      /* significantDigits */ 3,
                      /* maxFractionalDigits */ 2
                    )
                )}
                {_markerDetail(
                  'gcmaxpause',
                  'Max Pause',
                  timings.max_pause,
                  x =>
                    formatMilliseconds(
                      x,
                      /* significantDigits */ 3,
                      /* maxFractionalDigits */ 2
                    )
                )}
                {_markerDetail(
                  'gcusage',
                  'Heap usage',
                  timings.allocated_bytes,
                  formatBytes
                )}
                {_markerDetail(
                  'gcmmu20ms',
                  'MMU 20ms',
                  timings.mmu_20ms,
                  formatPercent
                )}
                {_markerDetail(
                  'gcmmu50ms',
                  'MMU 50ms',
                  timings.mmu_50ms,
                  formatPercent
                )}
                {_markerDetail('gcnumminors', 'Minor GCs', timings.minor_gcs)}
                {_markerDetail('gcnumslices', 'Slices', timings.slices)}
                {_markerDetail(
                  'gcnumzones',
                  'Zones',
                  formatValueTotal(
                    timings.zones_collected,
                    timings.total_zones,
                    String
                  )
                )}
                {_markerDetail(
                  'gcnumcompartments',
                  'Compartments',
                  timings.total_compartments
                )}

            );
          }
          default:
            return null;
        }
      }
      case 'GCSlice': {
        const timings = data.timings;
        let triggers;
        if (timings.trigger_amount && timings.trigger_threshold) {
          triggers = _markerDetail(
            'gctrigger',
            'Trigger (amt/trig)',
            formatValueTotal(
              timings.trigger_amount,
              timings.trigger_threshold,
              formatBytes,
              false
            )
          );
        }
        return (

            {_markerDetail('gcreason', 'Reason', timings.reason)}
            {_markerDetail('gcbudget', 'Budget', timings.budget)}
            {_markerDetail(
              'gcstate',
              'States',
              timings.initial_state + ' – ' + timings.final_state
            )}
            {triggers}
            {timings.page_faults === undefined
              ? null
              : _markerDetail('gcfaults', 'Page faults', timings.page_faults)}

        );
      }
      case 'Bailout': {
        return (

            {_markerDetail('bailoutType', 'Type', data.bailoutType)}
            {_markerDetail('where', 'Where', data.where)}
            {_markerDetail('script', 'Script', data.script)}
            {_markerDetail('functionLine', 'Function Line', data.functionLine)}
            {_markerDetail('bailoutLine', 'Bailout Line', data.bailoutLine)}

Description:

              {bailoutTypeInformation['Bailout_' + data.bailoutType]}

        );
      }
      case 'Invalidation': {
        return (

            {_markerDetail('url', 'URL', data.url)}
            {_markerDetail('line', 'Line', data.line)}

        );
      }
      case 'Network': {
        if (
          data.status !== 'STATUS_STOP' &&
          data.status !== 'STATUS_REDIRECT'
        ) {
          return (

              {_markerDetailNullable('url', 'URL', data.URI)}
              {_markerDetail('pri', 'pri', data.pri)}
              {_markerDetailNullable('count', 'count', data.count)}
              {_markerDetail('status', 'Status', data.status)}

          );
        } else {
          return (

              {_markerDetail('status', 'Status', data.status)}
              {_markerDetailNullable('url', 'URL', data.URI)}
              {_markerDetailNullable(
                'redirect_url',
                'Redirect URL',
                data.RedirectURI
              )}
              {_markerDetail('pri', 'pri', data.pri)}
              {_markerDetailNullable('count', 'count', data.count)}
              {_markerDetailDeltaTimeNullable(
                'domainLookup',
                'domainLookup',
                data.domainLookupEnd,
                data.domainLookupStart
              )}
              {_markerDetailDeltaTimeNullable(
                'tcpConnect',
                'tcpConnect',
                data.tcpConnectEnd,
                data.connectStart
              )}
              {_markerDetailDeltaTimeNullable(
                'secureConnectionStart',
                'secureConnectionStart',
                data.secureConnectionStart,
                data.tcpConnectEnd
              )}
              {_markerDetailDeltaTimeNullable(
                'connect',
                'connect',
                data.connectEnd,
                data.connectStart
              )}
              {_markerDetailDeltaTimeNullable(
                'requestStart',
                'requestStart @',
                data.startTime,
                data.requestStart
              )}
              {_markerDetailDeltaTimeNullable(
                'response',
                'response',
                data.responseEnd,
                data.responseStart
              )}

          );
        }
      }
      case 'Styles': {
        return [

            {_markerDetail(
              'elementsTraversed',
              'Elements traversed',
              data.elementsTraversed
            )}
            {_markerDetail(
              'elementsStyled',
              'Elements styled',
              data.elementsStyled
            )}
            {_markerDetail(
              'elementsMatched',
              'Elements matched',
              data.elementsMatched
            )}
            {_markerDetail('stylesShared', 'Styles shared', data.stylesShared)}
            {_markerDetail('stylesReused', 'Styles reused', data.stylesReused)}

,
          _markerBacktrace(marker, data, thread, implementationFilter),
        ];
      }
      case 'tracing': {
        return _markerBacktrace(marker, data, thread, implementationFilter);
      }
      default:
    }
  }
  return null;
}

type OwnProps = {|
  +marker: TracingMarker,
  +threadIndex: ThreadIndex,
  +className?: string,
|};

type StateProps = {|
  +threadName?: string,
  +thread: Thread,
  +implementationFilter: ImplementationFilter,
|};

type Props = ConnectedProps<OwnProps, StateProps, {||}>;

class MarkerTooltipContents extends React.PureComponent<Props> {
  render() {
    const {
      marker,
      className,
      threadName,
      thread,
      implementationFilter,
    } = this.props;
    const details = getMarkerDetails(marker, thread, implementationFilter);

    return (

              {/* tracing markers with no start have a negative start, while the
                ones with no end have an infinite duration */}
              {Number.isFinite(marker.dur) && marker.start >= 0
                ? formatNumber(marker.dur) + 'ms'
                : 'unknown duration'}

{marker.title || marker.name}

          {threadName ? (

Thread:

              {threadName}

          ) : null}

        {details}

    );
  }
}

const options: ExplicitConnectOptions<OwnProps, StateProps, {||}> = {
  mapStateToProps: (state, props) => {
    const { threadIndex } = props;
    const selectors = selectorsForThread(threadIndex);
    const threadName = selectors.getFriendlyThreadName(state);
    const thread = selectors.getThread(state);
    const implementationFilter = getImplementationFilter(state);
    return {
      threadName,
      thread,
      implementationFilter,
    };
  },
  component: MarkerTooltipContents,
};

export default explicitConnect(options);
<commit_msg>format count value in Bytes<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// @flow

import * as React from 'react';
import classNames from 'classnames';
import {
  formatNumber,
  formatPercent,
  formatBytes,
  formatMicroseconds,
  formatMilliseconds,
  formatValueTotal,
} from '../../utils/format-numbers';
import explicitConnect from '../../utils/connect';
import { selectorsForThread } from '../../reducers/profile-view';
import { getImplementationFilter } from '../../reducers/url-state';

import Backtrace from './Backtrace';

import { bailoutTypeInformation } from '../../profile-logic/marker-info';
import type { TracingMarker } from '../../types/profile-derived';
import type { NotVoidOrNull } from '../../types/utils';
import type { ImplementationFilter } from '../../types/actions';
import type { Thread, ThreadIndex } from '../../types/profile';
import type {
  DOMEventMarkerPayload,
  PaintProfilerMarkerTracing,
  StyleMarkerPayload,
} from '../../types/markers';
import type {
  ExplicitConnectOptions,
  ConnectedProps,
} from '../../utils/connect';

function _markerDetail<T: NotVoidOrNull>(
  key: string,
  label: string,
  value: T,
  fn: T => string = String
): React.Node {
  return [

      {label}:

,
    fn(value),
  ];
}

function _markerDetailNullable<T: NotVoidOrNull>(
  key: string,
  label: string,
  value: T | void | null,
  fn: T => string = String
): React.Node {
  if (value === undefined || value === null) {
    return null;
  }
  return _markerDetail(key, label, value, fn);
}

function _markerDetailBytesNullable<T: NotVoidOrNull>(
  key: string,
  label: string,
  value: T | void | null
): React.Node {
  if (value === undefined || value === null) {
    return null;
  }
  return _markerDetail(key, label, formatBytes(value));
}

function _markerDetailDeltaTimeNullable(
  key: string,
  label: string,
  value1?: number,
  value2?: number
): React.Node {
  if (
    value1 === undefined ||
    value2 === undefined ||
    value1 === null ||
    value2 === null
  ) {
    return null;
  }
  const valueResult = value1 - value2;
  return _markerDetail(key, label, formatMilliseconds(valueResult));
}

function _markerBacktrace(
  marker: TracingMarker,
  data: StyleMarkerPayload | PaintProfilerMarkerTracing | DOMEventMarkerPayload,
  thread: Thread,
  implementationFilter: ImplementationFilter
): React.Node {
  if (data.category === 'DOMEvent') {
    const latency =
      data.timeStamp === undefined
        ? null
        : formatMilliseconds(marker.start - data.timeStamp);
    return (

        {_markerDetail('type', 'Type', data.eventType)}
        {latency === null ? null : _markerDetail('latency', 'Latency', latency)}

    );
  }
  if ('cause' in data && data.cause) {
    const { cause } = data;
    const causeAge = marker.start - cause.time;
    return (

          First invalidated {formatNumber(causeAge)}ms before the flush, at:

        <Backtrace
          cause={cause}
          thread={thread}
          implementationFilter={implementationFilter}
        />

    );
  }
  return null;
}

function getMarkerDetails(
  marker: TracingMarker,
  thread: Thread,
  implementationFilter: ImplementationFilter
): React.Node {
  const data = marker.data;
  if (data) {
    switch (data.type) {
      case 'UserTiming': {
        return (

            {_markerDetail('name', 'Name', data.name)}

        );
      }
      case 'GCMinor': {
        if (data.nursery) {
          const nursery = data.nursery;
          switch (nursery.status) {
            case 'complete': {
              return (

                  {_markerDetail('gcreason', 'Reason', nursery.reason)}
                  {_markerDetail(
                    'gcpromotion',
                    'Bytes tenured',
                    formatValueTotal(
                      nursery.bytes_tenured,
                      nursery.bytes_used,
                      formatBytes
                    )
                  )}
                  {nursery.cur_capacity === undefined
                    ? null
                    : _markerDetail(
                        'gcnurseryusage',
                        'Bytes used',
                        formatValueTotal(
                          nursery.bytes_used,
                          nursery.cur_capacity,
                          formatBytes
                        )
                      )}
                  {nursery.new_capacity === undefined
                    ? null
                    : _markerDetail(
                        'gcnewnurserysize',
                        'New nursery size',
                        nursery.new_capacity,
                        formatBytes
                      )}
                  {nursery.lazy_capacity === undefined
                    ? null
                    : _markerDetail(
                        'gclazynurserysize',
                        'Lazy-allocated size',
                        nursery.lazy_capacity,
                        formatBytes
                      )}
                  {nursery.chunk_alloc_us === undefined
                    ? null
                    : _markerDetail(
                        'gctimeinchunkalloc',
                        'Time spent allocating chunks in mutator',
                        nursery.chunk_alloc_us,
                        formatMicroseconds
                      )}

              );
            }
            case 'nursery disabled':
              return (

                  {_markerDetail('gcstatus', 'Status', 'Nursery disabled')}

              );
            case 'nursery empty':
              return (

                  {_markerDetail('gcstatus', 'Status', 'Nursery empty')}

              );
            default:
              return null;
          }
        } else {
          return null;
        }
      }
      case 'GCMajor': {
        const timings = data.timings;
        switch (timings.status) {
          case 'aborted':
            return (

                {_markerDetail('status', 'Status', 'Aborted (OOM)')}

            );
          case 'completed': {
            let nonIncrementalReason;
            if (
              timings.nonincremental_reason &&
              timings.nonincremental_reason !== 'None'
            ) {
              nonIncrementalReason = _markerDetail(
                'gcnonincrementalreason',
                'Non-incremental reason',
                timings.nonincremental_reason
              );
            }
            return (

                {_markerDetail('gcreason', 'Reason', timings.reason)}
                {nonIncrementalReason}
                {_markerDetail(
                  'gctime',
                  'Total slice times',
                  timings.total_time,
                  x =>
                    formatMilliseconds(
                      x,
                      /* significantDigits */ 3,
                      /* maxFractionalDigits */ 2
                    )
                )}
                {_markerDetail(
                  'gcmaxpause',
                  'Max Pause',
                  timings.max_pause,
                  x =>
                    formatMilliseconds(
                      x,
                      /* significantDigits */ 3,
                      /* maxFractionalDigits */ 2
                    )
                )}
                {_markerDetail(
                  'gcusage',
                  'Heap usage',
                  timings.allocated_bytes,
                  formatBytes
                )}
                {_markerDetail(
                  'gcmmu20ms',
                  'MMU 20ms',
                  timings.mmu_20ms,
                  formatPercent
                )}
                {_markerDetail(
                  'gcmmu50ms',
                  'MMU 50ms',
                  timings.mmu_50ms,
                  formatPercent
                )}
                {_markerDetail('gcnumminors', 'Minor GCs', timings.minor_gcs)}
                {_markerDetail('gcnumslices', 'Slices', timings.slices)}
                {_markerDetail(
                  'gcnumzones',
                  'Zones',
                  formatValueTotal(
                    timings.zones_collected,
                    timings.total_zones,
                    String
                  )
                )}
                {_markerDetail(
                  'gcnumcompartments',
                  'Compartments',
                  timings.total_compartments
                )}

            );
          }
          default:
            return null;
        }
      }
      case 'GCSlice': {
        const timings = data.timings;
        let triggers;
        if (timings.trigger_amount && timings.trigger_threshold) {
          triggers = _markerDetail(
            'gctrigger',
            'Trigger (amt/trig)',
            formatValueTotal(
              timings.trigger_amount,
              timings.trigger_threshold,
              formatBytes,
              false
            )
          );
        }
        return (

            {_markerDetail('gcreason', 'Reason', timings.reason)}
            {_markerDetail('gcbudget', 'Budget', timings.budget)}
            {_markerDetail(
              'gcstate',
              'States',
              timings.initial_state + ' – ' + timings.final_state
            )}
            {triggers}
            {timings.page_faults === undefined
              ? null
              : _markerDetail('gcfaults', 'Page faults', timings.page_faults)}

        );
      }
      case 'Bailout': {
        return (

            {_markerDetail('bailoutType', 'Type', data.bailoutType)}
            {_markerDetail('where', 'Where', data.where)}
            {_markerDetail('script', 'Script', data.script)}
            {_markerDetail('functionLine', 'Function Line', data.functionLine)}
            {_markerDetail('bailoutLine', 'Bailout Line', data.bailoutLine)}

Description:

              {bailoutTypeInformation['Bailout_' + data.bailoutType]}

        );
      }
      case 'Invalidation': {
        return (

            {_markerDetail('url', 'URL', data.url)}
            {_markerDetail('line', 'Line', data.line)}

        );
      }
      case 'Network': {
        if (
          data.status !== 'STATUS_STOP' &&
          data.status !== 'STATUS_REDIRECT'
        ) {
          return (

              {_markerDetailNullable('url', 'URL', data.URI)}
              {_markerDetail('pri', 'pri', data.pri)}
              {_markerDetailBytesNullable('count', 'Req bites', data.count)}
              {_markerDetail('status', 'Status', data.status)}

          );
        } else {
          return (

              {_markerDetail('status', 'Status', data.status)}
              {_markerDetailNullable('url', 'URL', data.URI)}
              {_markerDetailNullable(
                'redirect_url',
                'Redirect URL',
                data.RedirectURI
              )}
              {_markerDetail('pri', 'pri', data.pri)}
              {_markerDetailBytesNullable('count', 'Req bites', data.count)}
              {_markerDetailDeltaTimeNullable(
                'domainLookup',
                'domainLookup',
                data.domainLookupEnd,
                data.domainLookupStart
              )}
              {_markerDetailDeltaTimeNullable(
                'tcpConnect',
                'tcpConnect',
                data.tcpConnectEnd,
                data.connectStart
              )}
              {_markerDetailDeltaTimeNullable(
                'secureConnectionStart',
                'secureConnectionStart',
                data.secureConnectionStart,
                data.tcpConnectEnd
              )}
              {_markerDetailDeltaTimeNullable(
                'connect',
                'connect',
                data.connectEnd,
                data.connectStart
              )}
              {_markerDetailDeltaTimeNullable(
                'requestStart',
                'requestStart @',
                data.startTime,
                data.requestStart
              )}
              {_markerDetailDeltaTimeNullable(
                'response',
                'response',
                data.responseEnd,
                data.responseStart
              )}

          );
        }
      }
      case 'Styles': {
        return [

            {_markerDetail(
              'elementsTraversed',
              'Elements traversed',
              data.elementsTraversed
            )}
            {_markerDetail(
              'elementsStyled',
              'Elements styled',
              data.elementsStyled
            )}
            {_markerDetail(
              'elementsMatched',
              'Elements matched',
              data.elementsMatched
            )}
            {_markerDetail('stylesShared', 'Styles shared', data.stylesShared)}
            {_markerDetail('stylesReused', 'Styles reused', data.stylesReused)}

,
          _markerBacktrace(marker, data, thread, implementationFilter),
        ];
      }
      case 'tracing': {
        return _markerBacktrace(marker, data, thread, implementationFilter);
      }
      default:
    }
  }
  return null;
}

type OwnProps = {|
  +marker: TracingMarker,
  +threadIndex: ThreadIndex,
  +className?: string,
|};

type StateProps = {|
  +threadName?: string,
  +thread: Thread,
  +implementationFilter: ImplementationFilter,
|};

type Props = ConnectedProps<OwnProps, StateProps, {||}>;

class MarkerTooltipContents extends React.PureComponent<Props> {
  render() {
    const {
      marker,
      className,
      threadName,
      thread,
      implementationFilter,
    } = this.props;
    const details = getMarkerDetails(marker, thread, implementationFilter);
    return (

              {/* tracing markers with no start have a negative start, while the
                ones with no end have an infinite duration */}
              {Number.isFinite(marker.dur) && marker.start >= 0
                ? formatNumber(marker.dur) + 'ms'
                : 'unknown duration'}

{marker.title || marker.name}

          {threadName ? (

Thread:

              {threadName}

          ) : null}

        {details}

    );
  }
}

const options: ExplicitConnectOptions<OwnProps, StateProps, {||}> = {
  mapStateToProps: (state, props) => {
    const { threadIndex } = props;
    const selectors = selectorsForThread(threadIndex);
    const threadName = selectors.getFriendlyThreadName(state);
    const thread = selectors.getThread(state);
    const implementationFilter = getImplementationFilter(state);
    return {
      threadName,
      thread,
      implementationFilter,
    };
  },
  component: MarkerTooltipContents,
};

export default explicitConnect(options);
<|endoftext|>


<commit_before>/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true, forin: true */
/*global Backbone, $, window, EJS, GraphViewerUI */

window.graphView = Backbone.View.extend({
  el: '#content',

  template: new EJS({url: 'js/templates/graphView.ejs'}),

  initialize: function () {
    var self = this;
    this.graphs = [];
    $.ajax({
      cache: false,
      type: 'GET',
      url: "/_api/graph",
      contentType: "application/json",
      success: function(data) {
        console.log(data);
        self.graphs = _.pluck(data.graphs, "_key");
        self.render();
      }
    });
  },

  events: {
    "click input[type='radio'][name='loadtype']": "toggleLoadtypeDisplay",
    "click #createViewer": "createViewer"
  },

  toggleLoadtypeDisplay: function() {
    var selected = $("input[type='radio'][name='loadtype']:checked").attr("id");
    if (selected === "collections") {
      $("#collection_config").css("display", "block");
      $("#graph_config").css("display", "none");
    } else {
      $("#collection_config").css("display", "none");
      $("#graph_config").css("display", "block");
    }
  },

  createViewer: function() {
    var ecol,
    ncol,
    aaconfig,
    undirected,
    randomStart,
    label,
    config,
    ui;

    ecol = $("#edgeCollection").val();
    ncol = $("#nodeCollection").val();
    undirected = !!$("#undirected").attr("checked");
    label = $("#nodeLabel").val();
    randomStart = !!$("#randomStart").attr("checked");

    aaconfig = {
      type: "arango",
      nodeCollection: ncol,
      edgeCollection: ecol,
      undirected: undirected
    };

    if (label !== undefined && label !== "") {
      config = {
        nodeShaper: {
          label: label
        }
      };
    }

    $("#background").remove();
    if (randomStart) {
      $.ajax({
        cache: false,
        type: 'PUT',
        url: '/_api/simple/any',
        data: JSON.stringify({
          collection: ncol
        }),
        contentType: "application/json",
        success: function(data) {
          ui = new GraphViewerUI($("#content")[0], aaconfig, 940, 680, config, data.document._id);
        }
      });
    } else {
      ui = new GraphViewerUI($("#content")[0], aaconfig, 940, 680, config);
    }
  },

  render: function() {
    $(this.el).html(this.template.render({col: this.collection, gs: this.graphs}));

    return this;
  }

});
<commit_msg>AdminInterface: Fixed reloading bug, the graphviewer was quite intrusive<commit_after>/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true, forin: true */
/*global Backbone, $, window, EJS, GraphViewerUI */

window.graphView = Backbone.View.extend({
  el: '#content',

  template: new EJS({url: 'js/templates/graphView.ejs'}),

  initialize: function () {
    var self = this;
    this.graphs = [];
  },

  events: {
    "click input[type='radio'][name='loadtype']": "toggleLoadtypeDisplay",
    "click #createViewer": "createViewer"
  },

  toggleLoadtypeDisplay: function() {
    var selected = $("input[type='radio'][name='loadtype']:checked").attr("id");
    if (selected === "collections") {
      $("#collection_config").css("display", "block");
      $("#graph_config").css("display", "none");
    } else {
      $("#collection_config").css("display", "none");
      $("#graph_config").css("display", "block");
    }
  },

  createViewer: function() {
    var ecol,
    ncol,
    aaconfig,
    undirected,
    randomStart,
    label,
    config,
    ui;

    ecol = $("#edgeCollection").val();
    ncol = $("#nodeCollection").val();
    undirected = !!$("#undirected").attr("checked");
    label = $("#nodeLabel").val();
    randomStart = !!$("#randomStart").attr("checked");

    aaconfig = {
      type: "arango",
      nodeCollection: ncol,
      edgeCollection: ecol,
      undirected: undirected
    };

    if (label !== undefined && label !== "") {
      config = {
        nodeShaper: {
          label: label
        }
      };
    }

    $("#background").remove();
    if (randomStart) {
      $.ajax({
        cache: false,
        type: 'PUT',
        url: '/_api/simple/any',
        data: JSON.stringify({
          collection: ncol
        }),
        contentType: "application/json",
        success: function(data) {
          ui = new GraphViewerUI($("#content")[0], aaconfig, 940, 680, config, data.document._id);
        }
      });
    } else {
      ui = new GraphViewerUI($("#content")[0], aaconfig, 940, 680, config);
    }
  },

  render: function() {
    var self = this;
    $.ajax({
      cache: false,
      type: 'GET',
      url: "/_api/graph",
      contentType: "application/json",
      success: function(data) {
        self.graphs = _.pluck(data.graphs, "_key");
        $(self.el).html(self.template.render({col: self.collection, gs: self.graphs}));
      }
    });
    return this;
  }

});
<|endoftext|>


<commit_before>import R from 'ramda';
import getNiceTickValues from './getNiceTickValues';
import getTickValues from './getTickValues';
import Arithmetric from '../util/arithmetric';
/**
 * 线性映射
 *
 * @param  {Array} domain      定义域
 * @param  {Array} range       值域
 * @param  {Function} inputFn  定义域的计算函数
 * @param  {Function} outputFn 值域的计算函数
 * @return {Function}          将定义域映射到值域的一个线性映射
 */
function scaleLinear(domain, range, inputFn, outputFn) {
  const input = inputFn(domain[0], domain[1]);
  const output = outputFn(range[0], range[1]);

  return R.compose(output, input);
}
/**
 * 转化为数值类型
 * @param  {Number|String} a 输入值
 * @return {Number}   数值
 */
function toNumber(a) {
  return +a;
}
/**
 * 线性刻度
 *
 * @param {Array}   domain     定义域
 * @param {Array}   range      值域
 * @param {Boolean} isNice     是否对刻度进行美化处理
 * @param {Boolean} isTruncate 是否对定义域做截断处理
 * 例如，定义域为[0, 10]，输入值为-1，isTruncate为true，则映射到0，否则映射到 -0.1
 * @param {Number}  tickCount  刻度数
 * @return {Number}   输出值
 */
function linear(domain = [0, 1], range = [0, 1], interpolate = interpolateNumber, isTruncate = false) {
  let output;
  let input;
  let tickValues;

  function scale(x) {
    return output(x);
  }

  function rescale() {
    const inputFn = isTruncate ? uninterpolateTruncation : uninterpolateNumber;

    // 根据输入值，获取输出值
    output = scaleLinear(domain, range, inputFn, interpolate);

    // 根据输出值，反过来得到输入值
    input = scaleLinear(range, domain, inputFn, interpolateNumber);

    return scale;
  }

  // Note: requires range is coercible to number!
  scale.invert = function(y) {
    return input(y);
  };

  scale.domain = function(x) {
    if (!arguments.length) return domain;

    domain = R.map(toNumber)(x);

    return rescale();
  };

  scale.range = function(x) {
    if (!arguments.length) return range;

    range = R.map(toNumber)(x);

    return rescale();
  };

  scale.nice = function(tickCount) {
    tickValues = getNiceTickValues(domain, tickCount);

    domain = [tickValues[0], tickValues[tickValues.length - 1]];

    return rescale();
  };

  scale.truncate = function(x) {
    if (!arguments.length) return isTruncate;

    isTruncate = x;

    return rescale();
  };

  scale.interpolate = function(x) {
    if (!arguments.length) return interpolate;

    interpolate = x;

    return rescale();
  };

  scale.getTickValues = function(tickCount) {
    tickValues = tickValues || getTickValues(domain[0], domain[1], tickCount);

    return tickValues;
  };

  scale.copy = function() {
    return linear(domain, range, interpolate, isTruncate);
  };

  return rescale();
}

export default linear;
<commit_msg>fix: fix import bug<commit_after>import R from 'ramda';
import getNiceTickValues from './getNiceTickValues';
import getTickValues from './getTickValues';
import Arithmetic from '../util/arithmetic';
/**
 * 线性映射
 *
 * @param  {Array} domain      定义域
 * @param  {Array} range       值域
 * @param  {Function} inputFn  定义域的计算函数
 * @param  {Function} outputFn 值域的计算函数
 * @return {Function}          将定义域映射到值域的一个线性映射
 */
function scaleLinear(domain, range, inputFn, outputFn) {
  const input = inputFn(domain[0], domain[1]);
  const output = outputFn(range[0], range[1]);

  return R.compose(output, input);
}
/**
 * 转化为数值类型
 * @param  {Number|String} a 输入值
 * @return {Number}   数值
 */
function toNumber(a) {
  return +a;
}
/**
 * 线性刻度
 *
 * @param {Array}   domain     定义域
 * @param {Array}   range      值域
 * @param {Boolean} isNice     是否对刻度进行美化处理
 * @param {Boolean} isTruncate 是否对定义域做截断处理
 * 例如，定义域为[0, 10]，输入值为-1，isTruncate为true，则映射到0，否则映射到 -0.1
 * @param {Number}  tickCount  刻度数
 * @return {Number}   输出值
 */
function linear(domain = [0, 1], range = [0, 1], interpolate = Arithmetic.interpolateNumber, isTruncate = false) {
  let output;
  let input;
  let tickValues;

  function scale(x) {
    return output(x);
  }

  function rescale() {
    const inputFn = isTruncate ? uninterpolateTruncation : Arithmetic.uninterpolateNumber;

    // 根据输入值，获取输出值
    output = scaleLinear(domain, range, inputFn, interpolate);

    // 根据输出值，反过来得到输入值
    input = scaleLinear(range, domain, inputFn, Arithmetic.interpolateNumber);

    return scale;
  }

  // Note: requires range is coercible to number!
  scale.invert = function(y) {
    return input(y);
  };

  scale.domain = function(x) {
    if (!arguments.length) return domain;

    domain = R.map(toNumber)(x);

    return rescale();
  };

  scale.range = function(x) {
    if (!arguments.length) return range;

    range = R.map(toNumber)(x);

    return rescale();
  };

  scale.nice = function(tickCount) {
    tickValues = getNiceTickValues(domain, tickCount);

    domain = [tickValues[0], tickValues[tickValues.length - 1]];

    return rescale();
  };

  scale.truncate = function(x) {
    if (!arguments.length) return isTruncate;

    isTruncate = x;

    return rescale();
  };

  scale.interpolate = function(x) {
    if (!arguments.length) return interpolate;

    interpolate = x;

    return rescale();
  };

  scale.getTickValues = function(tickCount) {
    tickValues = tickValues || getTickValues(domain[0], domain[1], tickCount);

    return tickValues;
  };

  scale.copy = function() {
    return linear(domain, range, interpolate, isTruncate);
  };

  return rescale();
}

export default linear;
<|endoftext|>


<commit_before>'use strict';

describe('Services Tests ', function () {

    beforeEach(module('<%= angularAppName %>'));

    describe('AuthenticationSharedService', function () {
        var serviceTested,
            httpBackend,
            authServiceSpied;

        beforeEach(inject(function($httpBackend, AuthenticationSharedService, authService) {
            serviceTested = AuthenticationSharedService;
            httpBackend = $httpBackend;
            authServiceSpied = authService;
            //Request on app init
            httpBackend.expectGET('i18n/en.json').respond(200, '');
        }));
        //make sure no expectations were missed in your tests.
        //(e.g. expectGET or expectPOST)
        afterEach(function() {
            httpBackend.verifyNoOutstandingExpectation();
            httpBackend.verifyNoOutstandingRequest();
        });

        it('should call backend on logout then call authService.loginCancelled', function(){
            //GIVEN
            //set up some data for the http call to return and test later.
            var returnData = { result: 'ok' };
            //expectGET to make sure this is called once.
            httpBackend.expectGET('app/logout').respond(returnData);<% if (websocket == 'atmosphere') { %>
            // WebSocket tries to authenticate after logout
            httpBackend.expectGET('app/rest/authenticate').respond(400, '');
            httpBackend.expectGET('views/main.html').respond(200, '');<% } %>

            //Set spy
            spyOn(authServiceSpied, 'loginCancelled');

             //WHEN
            serviceTested.logout();
            //flush the backend to "execute" the request to do the expectedGET assertion.
            httpBackend.flush();

            //THEN
            expect(authServiceSpied.loginCancelled).toHaveBeenCalled();
        });

    });
});

<commit_msg>Fix #457<commit_after>'use strict';

describe('Services Tests ', function () {

    beforeEach(module('<%= angularAppName %>'));

    describe('AuthenticationSharedService', function () {
        var serviceTested,
            httpBackend,
            authServiceSpied;

        beforeEach(inject(function($httpBackend, AuthenticationSharedService, authService) {
            serviceTested = AuthenticationSharedService;
            httpBackend = $httpBackend;
            authServiceSpied = authService;
            //Request on app init
            httpBackend.expectGET('i18n/en.json').respond(200, '');
        }));
        //make sure no expectations were missed in your tests.
        //(e.g. expectGET or expectPOST)
        afterEach(function() {
            httpBackend.verifyNoOutstandingExpectation();
            httpBackend.verifyNoOutstandingRequest();
        });

        it('should call backend on logout then call authService.loginCancelled', function(){
            //GIVEN
            //set up some data for the http call to return and test later.
            var returnData = { result: 'ok' };
            //expectGET to make sure this is called once.
            httpBackend.expectGET('app/logout').respond(returnData);<% if (websocket == 'atmosphere') { %>
            // WebSocket tries to authenticate after logout
            httpBackend.expectGET('protected/authentication_check.gif').respond(401, '');
            httpBackend.expectGET('views/main.html').respond(401, '');<% } %>

            //Set spy
            spyOn(authServiceSpied, 'loginCancelled');

             //WHEN
            serviceTested.logout();
            //flush the backend to "execute" the request to do the expectedGET assertion.
            httpBackend.flush();

            //THEN
            expect(authServiceSpied.loginCancelled).toHaveBeenCalled();
        });

    });
});
<|endoftext|>


<commit_before>var uri = URI(window.location.href);
var query = uri.query(true);

var params = {
	width: [$(window).width() - 50, parseInt], //800,
	height: [$(window).height() - 50, parseInt], //600,
	hours: [48, parseInt],
	minbin: [10, parseInt],
	pool: ['osg', String],
	project: ['all', String],
	user: ['all', String],
	groupby: ['ProjectName', String],
	rel: ['default', String],
	start: ['default', String],
	end: ['default', String],
};

var groupings = {
	'project': 'ProjectName',
	'user': 'Owner',
};

for (var key in params) {
	if (key in query) {
		params[key] = params[key][1](query[key]);
	}
	else {
		params[key] = params[key][0];
	}
}

function load() {
	$('#crowgraph').css({width: params.width, height: params.height});

	/* Start with one bin per hour */
	bins = params.hours;
	millis = 3600 * 1000;

	/* Bin width is chartwidth/bins.  If this is too small, then make fewer bins */
	while (params.width / bins < params.minbin) {
		bins /= 2;
		millis *= 2;
	}

	yLabels = {
		running: 'Jobs Running',
		started: 'Jobs Started',
		finished: 'Jobs Completed',
		submitted: 'Jobs Submitted',
	}

	var options = {
			chart: {
				renderTo: 'crowgraph',
				zoomType: 'xy',
				type: 'column',
				//margin: [ 60, 30, 45, 70 ],
				width: params.width,
				height: params.height
			},
			plotOptions: {
				column: {
					stacking: 'normal',
					pointPadding: 0.0,
					groupPadding: 0,
					pointInterval: millis,	/* how many millis per data point/bin */
				}
			},
			title: { text: '' },
			xAxis: { type: 'datetime', tickWidth: 0, gridLineWidth: 1, title: { text: 'Date/Time' } },
			yAxis: { title: { text: yLabels[params.rel] } },
			legend: { align: 'left', verticalAlign: 'top', y: 10, floating: true, borderWidth: 0 },
			//exporting: {	   buttons: { contextButton: {	text: 'Export' } }, sourceHeight:1050, sourceWidth: 1485	},
			credits: { enabled: false },
			tooltip: { formatter: function() {
				return ('' + this.series.name + '
' +
					Highcharts.dateFormat('%a %d %b %Y, %H:%M', this.x) + ' UTC
' +
					'Jobs: ' + this.y)
			} }
	};

	var failtimer = setTimeout(function () {
		$('#flying img').attr('src', 'standing.png').addClass('failed');
		$('#moon').css('background-color', '#c00');
		$('span.status').html('has failed. probably.');
	}, 60000);

	// why? $.ajaxSetup({async: false});
	$.ajax({
		type: "POST",
		url: "/service/mongo-crow/starts",
		data: JSON.stringify({
			"project": params.project,
			"user": params.user,
			"task": "all",
			"hours": params.hours,
			"pool": params.pool,
			"groupby": groupings[params.groupby],
			"bins": bins,
			"width": params.width,
			"rel": params.rel,
			"start": params.start,
			"end": params.end,
		}),
		contentType: "application/json; charset=utf-8",
		dataType: "json",
		success: function(data) {
			clearTimeout(failtimer);
			$('#crowgraph').show();
			options.series = data.plot;
			chart = new Highcharts.Chart(options);
			$('#flying').remove();
		},
		failure: function(errMsg) {
			alert(errMsg);
			$('#crowgraph').show();
		}
	});
}

$(document).ready(function() {
	$('#crowgraph').hide();

	// get title elements
	var name = $('.name');
	var status = $('span.status');

	// get ratio of name's width to font size
	name.css('font-size', '200%');
	var r = name.width() / 200.0;

	// compute ratio of status's width to that ratio
	var sz = status.width() / r;
	// and set the f-s to that value
	name.css('font-size', '' + sz + '%');

	// do it again for fine adjustments
	var r = name.width() / sz;
	var sz = status.width() / r;
	name.css('font-size', '' + sz + '%');

	load();
});
<commit_msg>delay crow animation 2s<commit_after>var uri = URI(window.location.href);
var query = uri.query(true);

var params = {
	width: [$(window).width() - 50, parseInt], //800,
	height: [$(window).height() - 50, parseInt], //600,
	hours: [48, parseInt],
	minbin: [10, parseInt],
	pool: ['osg', String],
	project: ['all', String],
	user: ['all', String],
	groupby: ['ProjectName', String],
	rel: ['default', String],
	start: ['default', String],
	end: ['default', String],
};

var groupings = {
	'project': 'ProjectName',
	'user': 'Owner',
};

for (var key in params) {
	if (key in query) {
		params[key] = params[key][1](query[key]);
	}
	else {
		params[key] = params[key][0];
	}
}

function load() {
	$('#crowgraph').css({width: params.width, height: params.height});

	/* Start with one bin per hour */
	bins = params.hours;
	millis = 3600 * 1000;

	/* Bin width is chartwidth/bins.  If this is too small, then make fewer bins */
	while (params.width / bins < params.minbin) {
		bins /= 2;
		millis *= 2;
	}

	yLabels = {
		running: 'Jobs Running',
		started: 'Jobs Started',
		finished: 'Jobs Completed',
		submitted: 'Jobs Submitted',
	}

	var options = {
			chart: {
				renderTo: 'crowgraph',
				zoomType: 'xy',
				type: 'column',
				//margin: [ 60, 30, 45, 70 ],
				width: params.width,
				height: params.height
			},
			plotOptions: {
				column: {
					stacking: 'normal',
					pointPadding: 0.0,
					groupPadding: 0,
					pointInterval: millis,	/* how many millis per data point/bin */
				}
			},
			title: { text: '' },
			xAxis: { type: 'datetime', tickWidth: 0, gridLineWidth: 1, title: { text: 'Date/Time' } },
			yAxis: { title: { text: yLabels[params.rel] } },
			legend: { align: 'left', verticalAlign: 'top', y: 10, floating: true, borderWidth: 0 },
			//exporting: {	   buttons: { contextButton: {	text: 'Export' } }, sourceHeight:1050, sourceWidth: 1485	},
			credits: { enabled: false },
			tooltip: { formatter: function() {
				return ('' + this.series.name + '
' +
					Highcharts.dateFormat('%a %d %b %Y, %H:%M', this.x) + ' UTC
' +
					'Jobs: ' + this.y)
			} }
	};

	var failtimer = setTimeout(function () {
		$('#flying img').attr('src', 'standing.png').addClass('failed');
		$('#moon').css('background-color', '#c00');
		$('span.status').html('has failed. probably.');
	}, 60000);

	// why? $.ajaxSetup({async: false});
	$.ajax({
		type: "POST",
		url: "/service/mongo-crow/starts",
		data: JSON.stringify({
			"project": params.project,
			"user": params.user,
			"task": "all",
			"hours": params.hours,
			"pool": params.pool,
			"groupby": groupings[params.groupby],
			"bins": bins,
			"width": params.width,
			"rel": params.rel,
			"start": params.start,
			"end": params.end,
		}),
		contentType: "application/json; charset=utf-8",
		dataType: "json",
		success: function(data) {
			clearTimeout(failtimer);
			$('#crowgraph').show();
			options.series = data.plot;
			chart = new Highcharts.Chart(options);
			$('#flying').remove();
		},
		failure: function(errMsg) {
			alert(errMsg);
			$('#crowgraph').show();
		}
	});
}

$(document).ready(function () {
	// delay the crow animation by 2s in case response is quick
	setTimeout(function () {
		//$('#crowgraph').hide();
		$('#flying').show();

		// get title elements
		var name = $('.name');
		var status = $('span.status');

		// get ratio of name's width to font size
		name.css('font-size', '200%');
		var r = name.width() / 200.0;

		// compute ratio of status's width to that ratio
		var sz = status.width() / r;
		// and set the f-s to that value
		name.css('font-size', '' + sz + '%');

		// do it again for fine adjustments
		var r = name.width() / sz;
		var sz = status.width() / r;
		name.css('font-size', '' + sz + '%');

	}, 2000);

	$('#flying').hide();
	load();
});
<|endoftext|>


<commit_before>/*global angular*/

(function() {
    'use strict';

    angular
        .module('angular-click-outside', [])
        .directive('clickOutside', ['$document', '$parse', '$timeout', clickOutside]);

    function clickOutside($document, $parse, $timeout) {
        return {
            restrict: 'A',
            link: function($scope, elem, attr) {

                // postpone linking to next digest to allow for unique id generation
                $timeout(function() {
                    var classList = (attr.outsideIfNot !== undefined) ? attr.outsideIfNot.replace(', ', ',').split(',') : [],
                        fn;

                    // add the elements id so it is not counted in the click listening
                    if (attr.id !== undefined) {
                        classList.push(attr.id);
                    }

                    function eventHandler(e) {

                        // check if our element already hidden and abort if so
                        if (angular.element(elem).hasClass("ng-hide")) {
                            return;
                        }

                        var i = 0,
                            element;

                        // if there is no click target, no point going on
                        if (!e || !e.target) {
                            return;
                        }

                        // loop through the available elements, looking for classes in the class list that might match and so will eat
                        for (element = e.target; element; element = element.parentNode) {
                            var id = element.id,
                                classNames = element.className,
                                l = classList.length;

                            // Unwrap SVGAnimatedString classes
                            if (classNames && classNames.baseVal !== undefined) {
                                classNames = classNames.baseVal;
                            }

                            // loop through the elements id's and classnames looking for exceptions
                            for (i = 0; i < l; i++) {
                                // check for exact matches on id's or classes, but only if they exist in the first place
                                if ((id !== undefined && id === classList[i]) || (classNames && classNames === classList[i])) {
                                    // now let's exit out as it is an element that has been defined as being ignored for clicking outside
                                    return;
                                }
                            }
                        }

                        // if we have got this far, then we are good to go with processing the command passed in via the click-outside attribute
                        $scope.$apply(function() {
                            fn = $parse(attr['clickOutside']);
                            fn($scope);
                        });
                    }

                    // if the devices has a touchscreen, listen for this event
                    if (_hasTouch()) {
                        $document.on('touchstart', eventHandler);
                    }

                    // still listen for the click event even if there is touch to cater for touchscreen laptops
                    $document.on('click', eventHandler);

                    // when the scope is destroyed, clean up the documents event handlers as we don't want it hanging around
                    $scope.$on('$destroy', function() {
                        if (_hasTouch()) {
                            $document.off('touchstart', eventHandler);
                        }

                        $document.off('click', eventHandler);
                    });

                    // private function to attempt to figure out if we are on a touch device
                    function _hasTouch() {
                        // works on most browsers, IE10/11 and Surface
                        return 'ontouchstart' in window || navigator.maxTouchPoints;
                    };
                });
            }
        };
    }
})();
<commit_msg>Checks excluded classes with RegExp with word boundary<commit_after>/*global angular*/

(function() {
    'use strict';

    angular
        .module('angular-click-outside', [])
        .directive('clickOutside', ['$document', '$parse', '$timeout', clickOutside]);

    function clickOutside($document, $parse, $timeout) {
        return {
            restrict: 'A',
            link: function($scope, elem, attr) {

                // postpone linking to next digest to allow for unique id generation
                $timeout(function() {
                    var classList = (attr.outsideIfNot !== undefined) ? attr.outsideIfNot.replace(', ', ',').split(',') : [],
                        fn;

                    // add the elements id so it is not counted in the click listening
                    if (attr.id !== undefined) {
                        classList.push(attr.id);
                    }

                    function eventHandler(e) {

                        // check if our element already hidden and abort if so
                        if (angular.element(elem).hasClass("ng-hide")) {
                            return;
                        }

                        var i = 0,
                            element;

                        // if there is no click target, no point going on
                        if (!e || !e.target) {
                            return;
                        }

                        // loop through the available elements, looking for classes in the class list that might match and so will eat
                        for (element = e.target; element; element = element.parentNode) {
                            var id = element.id,
                                classNames = element.className,
                                l = classList.length;

                            // Unwrap SVGAnimatedString classes
                            if (classNames && classNames.baseVal !== undefined) {
                                classNames = classNames.baseVal;
                            }

                            // loop through the elements id's and classnames looking for exceptions
                            for (i = 0; i < l; i++) {
                                //prepare regex for class word matching
                                var r = new RegExp('\\b' + classList[i] + '\\b');
                                // check for exact matches on id's or classes, but only if they exist in the first place
                                if ((id !== undefined && id === classList[i]) || (classNames && r.test(classNames))) {
                                    // now let's exit out as it is an element that has been defined as being ignored for clicking outside
                                    return;
                                }
                            }
                        }

                        // if we have got this far, then we are good to go with processing the command passed in via the click-outside attribute
                        $scope.$apply(function() {
                            fn = $parse(attr['clickOutside']);
                            fn($scope);
                        });
                    }

                    // if the devices has a touchscreen, listen for this event
                    if (_hasTouch()) {
                        $document.on('touchstart', eventHandler);
                    }

                    // still listen for the click event even if there is touch to cater for touchscreen laptops
                    $document.on('click', eventHandler);

                    // when the scope is destroyed, clean up the documents event handlers as we don't want it hanging around
                    $scope.$on('$destroy', function() {
                        if (_hasTouch()) {
                            $document.off('touchstart', eventHandler);
                        }

                        $document.off('click', eventHandler);
                    });

                    // private function to attempt to figure out if we are on a touch device
                    function _hasTouch() {
                        // works on most browsers, IE10/11 and Surface
                        return 'ontouchstart' in window || navigator.maxTouchPoints;
                    };
                });
            }
        };
    }
})();
<|endoftext|>