<commit_before>define([
	"dojo",
	"dojo/window"], function(dojo){

	// module:
	//		dijit/place
	// summary:
	//		Code to place a popup relative to another node

	function _place(/*DomNode*/ node, choices, layoutNode, aroundNodeCoords){
		// summary:
		//		Given a list of spots to put node, put it at the first spot where it fits,
		//		of if it doesn't fit anywhere then the place with the least overflow
		// choices: Array
		//		Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} }
		//		Above example says to put the top-left corner of the node at (10,20)
		// layoutNode: Function(node, aroundNodeCorner, nodeCorner, size)
		//		for things like tooltip, they are displayed differently (and have different dimensions)
		//		based on their orientation relative to the parent.	 This adjusts the popup based on orientation.
		//		It also passes in the available size for the popup, which is useful for tooltips to
		//		tell them that their width is limited to a certain amount.	 layoutNode() may return a value expressing
		//		how much the popup had to be modified to fit into the available space.	 This is used to determine
		//		what the best placement is.
		// aroundNodeCoords: Object
		//		Size of aroundNode, ex: {w: 200, h: 50}

		// get {x: 10, y: 10, w: 100, h:100} type obj representing position of
		// viewport over document
		var view = dojo.window.getBox();

		// This won't work if the node is inside a
,
		// so reattach it to dojo.doc.body.	 (Otherwise, the positioning will be wrong
		// and also it might get cutoff)
		if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){
			dojo.body().appendChild(node);
		}

		var best = null;
		dojo.some(choices, function(choice){
			var corner = choice.corner;
			var pos = choice.pos;
			var overflow = 0;

			// calculate amount of space available given specified position of node
			var spaceAvailable = {
				w: {
					'L': view.l + view.w - pos.x,
					'R': pos.x - view.l,
					'M': view.w
				   }[corner.charAt(1)],
				h: {
					'T': view.t + view.h - pos.y,
					'B': pos.y - view.t,
					'M': view.h
				   }[corner.charAt(0)]
			};

			// configure node to be displayed in given position relative to button
			// (need to do this in order to get an accurate size for the node, because
			// a tooltip's size changes based on position, due to triangle)
			if(layoutNode){
				var res = layoutNode(node, choice.aroundCorner, corner, spaceAvailable, aroundNodeCoords);
				overflow = typeof res == "undefined" ? 0 : res;
			}

			// get node's size
			var style = node.style;
			var oldDisplay = style.display;
			var oldVis = style.visibility;
			style.visibility = "hidden";
			style.display = "";
			var mb = dojo.marginBox(node);
			style.display = oldDisplay;
			style.visibility = oldVis;

			// coordinates and size of node with specified corner placed at pos,
			// and clipped by viewport
			var
				startXpos = {
					'L': pos.x,
					'R': pos.x - mb.w,
					'M': Math.max(view.l, Math.min(view.l + view.w, pos.x + (mb.w >> 1)) - mb.w) // M orientation is more flexible
				}[corner.charAt(1)],
				startYpos = {
					'T': pos.y,
					'B': pos.y - mb.h,
					'M': Math.max(view.t, Math.min(view.t + view.h, pos.y + (mb.h >> 1)) - mb.h)
				}[corner.charAt(0)],
				startX = Math.max(view.l, startXpos),
				startY = Math.max(view.t, startYpos),
				endX = Math.min(view.l + view.w, startXpos + mb.w),
				endY = Math.min(view.t + view.h, startYpos + mb.h),
				width = endX - startX,
				height = endY - startY;

			overflow += (mb.w - width) + (mb.h - height);

			if(best == null || overflow < best.overflow){
				best = {
					corner: corner,
					aroundCorner: choice.aroundCorner,
					x: startX,
					y: startY,
					w: width,
					h: height,
					overflow: overflow,
					spaceAvailable: spaceAvailable
				};
			}

			return !overflow;
		});

		// In case the best position is not the last one we checked, need to call
		// layoutNode() again.
		if(best.overflow && layoutNode){
			layoutNode(node, best.aroundCorner, best.corner, best.spaceAvailable, aroundNodeCoords);
		}

		// And then position the node.  Do this last, after the layoutNode() above
		// has sized the node, due to browser quirks when the viewport is scrolled
		// (specifically that a Tooltip will shrink to fit as though the window was
		// scrolled to the left).
		//
		// In RTL mode, set style.right rather than style.left so in the common case,
		// window resizes move the popup along with the aroundNode.
		var l = dojo._isBodyLtr(),
			s = node.style;
		s.top = best.y + "px";
		s[l ? "left" : "right"] = (l ? best.x : view.w - best.x - best.w) + "px";

		return best;
	}

	return {
		/*=====
		dijit.__Position = function(){
			// x: Integer
			//		horizontal coordinate in pixels, relative to document body
			// y: Integer
			//		vertical coordinate in pixels, relative to document body

			this.x = x;
			this.y = y;
		}
		=====*/

		at: function(node, pos, corners, padding){
			// summary:
			//		Positions one of the node's corners at specified position
			//		such that node is fully visible in viewport.
			// description:
			//		NOTE: node is assumed to be absolutely or relatively positioned.
			// node: DOMNode
			//		The node to position
			// pos: dijit.__Position
			//		Object like {x: 10, y: 20}
			// corners: String[]
			//		Array of Strings representing order to try corners in, like ["TR", "BL"].
			//		Possible values are:
			//			* "BL" - bottom left
			//			* "BR" - bottom right
			//			* "TL" - top left
			//			* "TR" - top right
			// padding: dijit.__Position?
			//		optional param to set padding, to put some buffer around the element you want to position.
			// example:
			//		Try to place node's top right corner at (10,20).
			//		If that makes node go (partially) off screen, then try placing
			//		bottom left corner at (10,20).
			//	|	place(node, {x: 10, y: 20}, ["TR", "BL"])
			var choices = dojo.map(corners, function(corner){
				var c = { corner: corner, pos: {x:pos.x,y:pos.y} };
				if(padding){
					c.pos.x += corner.charAt(1) == 'L' ? padding.x : -padding.x;
					c.pos.y += corner.charAt(0) == 'T' ? padding.y : -padding.y;
				}
				return c;
			});

			return _place(node, choices);
		},

		/*=====
		dijit.__Rectangle = function(){
			// x: Integer
			//		horizontal offset in pixels, relative to document body
			// y: Integer
			//		vertical offset in pixels, relative to document body
			// w: Integer
			//		width in pixels.   Can also be specified as "width" for backwards-compatibility.
			// h: Integer
			//		height in pixels.   Can also be specified as "height" from backwards-compatibility.

			this.x = x;
			this.y = y;
			this.w = w;
			this.h = h;
		}
		=====*/

		around: function(
			/*DomNode*/		node,
			/*Object*/		anchor,
			/*String[]*/	positions,
			/*Boolean*/		leftToRight,
			/*Function?*/	layoutNode){

			// summary:
			//		Position node adjacent or kitty-corner to anchor
			//		such that it's fully visible in viewport.
			//
			// description:
			//		Place node such that corner of node touches a corner of
			//		aroundNode, and that node is fully visible.
			//
			// anchor:
			//		Either a DOMNode or a __Rectangle (object with x, y, width, height).
			//
			// positions:
			//		Ordered list of positions to try matching up.
			//			* before: places drop down to the left of the anchor node/widget, or to the right in
			//				the case of RTL scripts like Hebrew and Arabic
			//			* after: places drop down to the right of the anchor node/widget, or to the left in
			//				the case of RTL scripts like Hebrew and Arabic
			//			* above: drop down goes above anchor node
			//			* above-alt: same as above except right sides aligned instead of left
			//			* below: drop down goes below anchor node
			//			* below-alt: same as below except right sides aligned instead of left
			//
			// layoutNode: Function(node, aroundNodeCorner, nodeCorner)
			//		For things like tooltip, they are displayed differently (and have different dimensions)
			//		based on their orientation relative to the parent.	 This adjusts the popup based on orientation.
			//
			// leftToRight:
			//		True if widget is LTR, false if widget is RTL.   Affects the behavior of "above" and "below"
			//		positions slightly.
			//
			// example:
			//	|	placeAroundNode(node, aroundNode, {'BL':'TL', 'TR':'BR'});
			//		This will try to position node such that node's top-left corner is at the same position
			//		as the bottom left corner of the aroundNode (ie, put node below
			//		aroundNode, with left edges aligned).	If that fails it will try to put
			// 		the bottom-right corner of node where the top right corner of aroundNode is
			//		(ie, put node above aroundNode, with right edges aligned)
			//

			// if around is a DOMNode (or DOMNode id), convert to coordinates
			if(typeof anchor == "string" || "offsetWidth" in anchor){
				anchor = dojo.position(anchor, true);
			}

			var x = anchor.x,
				y = anchor.y,
				width = "w" in anchor ? anchor.w : anchor.width;
				height = "h" in anchor ? anchor.h : anchor.height;

			// Convert positions arguments into choices argument for _place()
			var choices = [];
			function push(aroundCorner, corner){
				choices.push({
					aroundCorner: aroundCorner,
					corner: corner,
					pos: {
						x: {
							'L': x,
							'R': x + width,
							'M': x + (width >> 1)
						   }[aroundCorner.charAt(1)],
						y: {
							'T': y,
							'B': y + height,
							'M': y + (height >> 1)
						   }[aroundCorner.charAt(0)]
					}
				})
			}
			dojo.forEach(positions, function(pos){
				var ltr =  leftToRight;
				switch(pos){
					case "above-centered":
						push("TM", "BM");
						break;
					case "below-centered":
						push("BM", "TM");
						break;
					case "after":
						ltr = !ltr;
						// fall through
					case "before":
						push(ltr ? "ML" : "MR", ltr ? "MR" : "ML");
						break;
					case "below-alt":
						ltr = !ltr;
						// fall through
					case "below":
						// first try to align left borders, next try to align right borders (or reverse for RTL mode)
						push(ltr ? "BL" : "BR", ltr ? "TL" : "TR");
						push(ltr ? "BR" : "BL", ltr ? "TR" : "TL");
						break;
					case "above-alt":
						ltr = !ltr;
						// fall through
					case "above":
						// first try to align left borders, next try to align right borders (or reverse for RTL mode)
						push(ltr ? "TL" : "TR", ltr ? "BL" : "BR");
						push(ltr ? "TR" : "TL", ltr ? "BR" : "BL");
						break;
					default:
						push(pos.aroundCorner, pos.corner);
				}
			});

			return _place(node, choices, layoutNode, {w: width, h: height});
		}
	};
});
<commit_msg>just adding comment, refs #12728<commit_after>define([
	"dojo",
	"dojo/window"], function(dojo){

	// module:
	//		dijit/place
	// summary:
	//		Code to place a popup relative to another node

	function _place(/*DomNode*/ node, choices, layoutNode, aroundNodeCoords){
		// summary:
		//		Given a list of spots to put node, put it at the first spot where it fits,
		//		of if it doesn't fit anywhere then the place with the least overflow
		// choices: Array
		//		Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} }
		//		Above example says to put the top-left corner of the node at (10,20)
		// layoutNode: Function(node, aroundNodeCorner, nodeCorner, size)
		//		for things like tooltip, they are displayed differently (and have different dimensions)
		//		based on their orientation relative to the parent.	 This adjusts the popup based on orientation.
		//		It also passes in the available size for the popup, which is useful for tooltips to
		//		tell them that their width is limited to a certain amount.	 layoutNode() may return a value expressing
		//		how much the popup had to be modified to fit into the available space.	 This is used to determine
		//		what the best placement is.
		// aroundNodeCoords: Object
		//		Size of aroundNode, ex: {w: 200, h: 50}

		// get {x: 10, y: 10, w: 100, h:100} type obj representing position of
		// viewport over document
		var view = dojo.window.getBox();

		// This won't work if the node is inside a
,
		// so reattach it to dojo.doc.body.	 (Otherwise, the positioning will be wrong
		// and also it might get cutoff)
		if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){
			dojo.body().appendChild(node);
		}

		var best = null;
		dojo.some(choices, function(choice){
			var corner = choice.corner;
			var pos = choice.pos;
			var overflow = 0;

			// calculate amount of space available given specified position of node
			var spaceAvailable = {
				w: {
					'L': view.l + view.w - pos.x,
					'R': pos.x - view.l,
					'M': view.w
				   }[corner.charAt(1)],
				h: {
					'T': view.t + view.h - pos.y,
					'B': pos.y - view.t,
					'M': view.h
				   }[corner.charAt(0)]
			};

			// configure node to be displayed in given position relative to button
			// (need to do this in order to get an accurate size for the node, because
			// a tooltip's size changes based on position, due to triangle)
			if(layoutNode){
				var res = layoutNode(node, choice.aroundCorner, corner, spaceAvailable, aroundNodeCoords);
				overflow = typeof res == "undefined" ? 0 : res;
			}

			// get node's size
			var style = node.style;
			var oldDisplay = style.display;
			var oldVis = style.visibility;
			style.visibility = "hidden";
			style.display = "";
			var mb = dojo.marginBox(node);
			style.display = oldDisplay;
			style.visibility = oldVis;

			// coordinates and size of node with specified corner placed at pos,
			// and clipped by viewport
			var
				startXpos = {
					'L': pos.x,
					'R': pos.x - mb.w,
					'M': Math.max(view.l, Math.min(view.l + view.w, pos.x + (mb.w >> 1)) - mb.w) // M orientation is more flexible
				}[corner.charAt(1)],
				startYpos = {
					'T': pos.y,
					'B': pos.y - mb.h,
					'M': Math.max(view.t, Math.min(view.t + view.h, pos.y + (mb.h >> 1)) - mb.h)
				}[corner.charAt(0)],
				startX = Math.max(view.l, startXpos),
				startY = Math.max(view.t, startYpos),
				endX = Math.min(view.l + view.w, startXpos + mb.w),
				endY = Math.min(view.t + view.h, startYpos + mb.h),
				width = endX - startX,
				height = endY - startY;

			overflow += (mb.w - width) + (mb.h - height);

			if(best == null || overflow < best.overflow){
				best = {
					corner: corner,
					aroundCorner: choice.aroundCorner,
					x: startX,
					y: startY,
					w: width,
					h: height,
					overflow: overflow,
					spaceAvailable: spaceAvailable
				};
			}

			return !overflow;
		});

		// In case the best position is not the last one we checked, need to call
		// layoutNode() again.
		if(best.overflow && layoutNode){
			layoutNode(node, best.aroundCorner, best.corner, best.spaceAvailable, aroundNodeCoords);
		}

		// And then position the node.  Do this last, after the layoutNode() above
		// has sized the node, due to browser quirks when the viewport is scrolled
		// (specifically that a Tooltip will shrink to fit as though the window was
		// scrolled to the left).
		//
		// In RTL mode, set style.right rather than style.left so in the common case,
		// window resizes move the popup along with the aroundNode.
		var l = dojo._isBodyLtr(),
			s = node.style;
		s.top = best.y + "px";
		s[l ? "left" : "right"] = (l ? best.x : view.w - best.x - best.w) + "px";

		return best;
	}

	return {
		/*=====
		dijit.__Position = function(){
			// x: Integer
			//		horizontal coordinate in pixels, relative to document body
			// y: Integer
			//		vertical coordinate in pixels, relative to document body

			this.x = x;
			this.y = y;
		}
		=====*/

		at: function(node, pos, corners, padding){
			// summary:
			//		Positions one of the node's corners at specified position
			//		such that node is fully visible in viewport.
			// description:
			//		NOTE: node is assumed to be absolutely or relatively positioned.
			// node: DOMNode
			//		The node to position
			// pos: dijit.__Position
			//		Object like {x: 10, y: 20}
			// corners: String[]
			//		Array of Strings representing order to try corners in, like ["TR", "BL"].
			//		Possible values are:
			//			* "BL" - bottom left
			//			* "BR" - bottom right
			//			* "TL" - top left
			//			* "TR" - top right
			// padding: dijit.__Position?
			//		optional param to set padding, to put some buffer around the element you want to position.
			// example:
			//		Try to place node's top right corner at (10,20).
			//		If that makes node go (partially) off screen, then try placing
			//		bottom left corner at (10,20).
			//	|	place(node, {x: 10, y: 20}, ["TR", "BL"])
			var choices = dojo.map(corners, function(corner){
				var c = { corner: corner, pos: {x:pos.x,y:pos.y} };
				if(padding){
					c.pos.x += corner.charAt(1) == 'L' ? padding.x : -padding.x;
					c.pos.y += corner.charAt(0) == 'T' ? padding.y : -padding.y;
				}
				return c;
			});

			return _place(node, choices);
		},

		/*=====
		dijit.__Rectangle = function(){
			// x: Integer
			//		horizontal offset in pixels, relative to document body
			// y: Integer
			//		vertical offset in pixels, relative to document body
			// w: Integer
			//		width in pixels.   Can also be specified as "width" for backwards-compatibility.
			// h: Integer
			//		height in pixels.   Can also be specified as "height" from backwards-compatibility.

			this.x = x;
			this.y = y;
			this.w = w;
			this.h = h;
		}
		=====*/

		around: function(
			/*DomNode*/		node,
			/*Object*/		anchor,
			/*String[]*/	positions,
			/*Boolean*/		leftToRight,
			/*Function?*/	layoutNode){

			// summary:
			//		Position node adjacent or kitty-corner to anchor
			//		such that it's fully visible in viewport.
			//
			// description:
			//		Place node such that corner of node touches a corner of
			//		aroundNode, and that node is fully visible.
			//
			// anchor:
			//		Either a DOMNode or a __Rectangle (object with x, y, width, height).
			//
			// positions:
			//		Ordered list of positions to try matching up.
			//			* before: places drop down to the left of the anchor node/widget, or to the right in
			//				the case of RTL scripts like Hebrew and Arabic
			//			* after: places drop down to the right of the anchor node/widget, or to the left in
			//				the case of RTL scripts like Hebrew and Arabic
			//			* above: drop down goes above anchor node
			//			* above-alt: same as above except right sides aligned instead of left
			//			* below: drop down goes below anchor node
			//			* below-alt: same as below except right sides aligned instead of left
			//
			// layoutNode: Function(node, aroundNodeCorner, nodeCorner)
			//		For things like tooltip, they are displayed differently (and have different dimensions)
			//		based on their orientation relative to the parent.	 This adjusts the popup based on orientation.
			//
			// leftToRight:
			//		True if widget is LTR, false if widget is RTL.   Affects the behavior of "above" and "below"
			//		positions slightly.
			//
			// example:
			//	|	placeAroundNode(node, aroundNode, {'BL':'TL', 'TR':'BR'});
			//		This will try to position node such that node's top-left corner is at the same position
			//		as the bottom left corner of the aroundNode (ie, put node below
			//		aroundNode, with left edges aligned).	If that fails it will try to put
			// 		the bottom-right corner of node where the top right corner of aroundNode is
			//		(ie, put node above aroundNode, with right edges aligned)
			//

			// if around is a DOMNode (or DOMNode id), convert to coordinates
			if(typeof anchor == "string" || "offsetWidth" in anchor){
				anchor = dojo.position(anchor, true);
			}

			var x = anchor.x,
				y = anchor.y,
				width = "w" in anchor ? anchor.w : anchor.width;
				height = "h" in anchor ? anchor.h : anchor.height;

			// Convert positions arguments into choices argument for _place()
			var choices = [];
			function push(aroundCorner, corner){
				choices.push({
					aroundCorner: aroundCorner,
					corner: corner,
					pos: {
						x: {
							'L': x,
							'R': x + width,
							'M': x + (width >> 1)
						   }[aroundCorner.charAt(1)],
						y: {
							'T': y,
							'B': y + height,
							'M': y + (height >> 1)
						   }[aroundCorner.charAt(0)]
					}
				})
			}
			dojo.forEach(positions, function(pos){
				var ltr =  leftToRight;
				switch(pos){
					case "above-centered":
						push("TM", "BM");
						break;
					case "below-centered":
						push("BM", "TM");
						break;
					case "after":
						ltr = !ltr;
						// fall through
					case "before":
						push(ltr ? "ML" : "MR", ltr ? "MR" : "ML");
						break;
					case "below-alt":
						ltr = !ltr;
						// fall through
					case "below":
						// first try to align left borders, next try to align right borders (or reverse for RTL mode)
						push(ltr ? "BL" : "BR", ltr ? "TL" : "TR");
						push(ltr ? "BR" : "BL", ltr ? "TR" : "TL");
						break;
					case "above-alt":
						ltr = !ltr;
						// fall through
					case "above":
						// first try to align left borders, next try to align right borders (or reverse for RTL mode)
						push(ltr ? "TL" : "TR", ltr ? "BL" : "BR");
						push(ltr ? "TR" : "TL", ltr ? "BR" : "BL");
						break;
					default:
						// To assist dijit/_base/place, accept arguments of type {aroundCorner: "BL", corner: "TL"}.
						// Not meant to be used directly.
						push(pos.aroundCorner, pos.corner);
				}
			});

			return _place(node, choices, layoutNode, {w: width, h: height});
		}
	};
});
<|endoftext|>


<commit_before>(function () { // This prevents problems when concatenating scripts that aren't strict.
'use strict';

var project = {
	name: 'MCM',
	port: 5556,
	subProjects: {
		MCM: {
	        BOOTSTRAP_MODULE: 'js/app2',
	        BOOTSTRAP_MODULE_HOT_LOADER: 'hot_loader_app2',
	        SELECTOR: 'button-basic-usage',
	        APP_SRC: 'app',
	        APP_TITLE: 'McModelar',
	        COMPILATION: {},
	        SYM_LINKS_EXISTS: true
	    }
	}
}

var APP_SRC = project.subProjects.MCM.APP_SRC;
var APP_DEST = 'APP_DEST';

var APP_SRC_STR = 'APP_SRC_STR';
var APP_DEST_STR = 'APP_DEST_STR';

project.subProjects.MCM.COMPILATION = {
    ADD_ANTICACHE_SUFIX: false,
    INLINE_NG1: {
        SRC: project.subProjects.MCM.SYM_LINKS_EXISTS ?
            // this does work for symbolic links
            ['**/*.tpl.html'] :
            // this doesn't work for symbolic links
            [join(APP_SRC, '**/*.tpl.html')]
    },
    INLINE: {
        USE_RELATIVE_PATHS: true
    },
    COMPASS: {
        // NOTE: !!!if true, this will output css files into sass folder!!!
        // due to [issue-61](https://github.com/appleboy/gulp-compass/issues/61)
        GENERIC: false,
        // if value of the path key is not set to object, default values will be considered
        PATHS: {
            '': { destDir: APP_SRC, cssDir: 'css' },
            'components/collaboPlugins': { destDir: APP_SRC, cssDir: 'css' },
            'components/knalledgeMap': { destDir: APP_SRC, cssDir: 'css' },
            'components/login': { destDir: APP_SRC, cssDir: 'css' },
            'components/notify': { destDir: APP_SRC, cssDir: 'css' },
            'components/gardening': { destDir: APP_SRC, cssDir: 'css' },
            'components/rima': { destDir: APP_SRC, cssDir: 'css' },
            'components/topiChat': { destDir: APP_SRC, cssDir: 'css' },
            'components/mcmMap': { destDir: APP_SRC, cssDir: 'css' },
            'components/mcmMaps': { destDir: APP_SRC, cssDir: 'css' },
            'components/mapsList': { destDir: APP_SRC, cssDir: 'css' }
        }
    }
};

/* Configuration */
var plugins = {
	"ViewComponents": {
		"knalledgeMap.Main": {
			components: {
				TopPanel: {
					active: false,
					path: "/components/topPanel/topPanel"
				}
			}
		},
		"bottomPanel.BottomPanel": {
			components: {
				'brainstorming.BrainstormingPanelComponent': {
					false: true,
					path: "/components/brainstorming/brainstorming-panel.component"
				}
			}
		},
		"knalledgeMap.KnalledgeMapTools": {
			components: {
				GardeningControls: {
					active: true,
					path: "/components/gardening/gardening-controls.component"
				},
				RimaUsersList: {
					active: true,
					path: "/components/rima/rimaUsersList"
				},
				IbisTypesList: {
					active: true,
					path: "/components/knalledgeMap/ibisTypesList"
				}
			},
		}
	},

	puzzlesBuild: {
		knalledgeMap: {
			directive: {
				path: [APP_SRC_STR, 'components/knalledgeMap'],
				injectJs: [
					'js/directives.js', 'js/services.js'
				],
				injectCss: ['css/default.css', 'css/graph.css']
			},
			interaction: {
				path: [APP_SRC_STR, 'js/interaction'],
				injectJs: ['interaction.js', 'moveAndDrag.js', 'keyboard.js']
			},
			knalledge: {
				path: [APP_SRC_STR, 'js/knalledge'],
				injectJs: ['mapLayout.js', 'mapVisualization.js', 'mapLayoutTree.js', 'mapVisualizationTree.js', 'mapLayoutFlat.js', 'mapVisualizationFlat.js', 'mapLayoutGraph.js', 'mapVisualizationGraph.js', 'mapManager.js', 'map.js']
			}
		},
		collaboPlugins: {
			path: [APP_SRC_STR, 'components/collaboPlugins'],
			injectJs: ['js/directives.js', 'js/services.js'],
			injectCss: 'css/default.css'
		},

		// demoPuzzle: {
		// 	path: [APP_SRC_STR, 'components/demoPuzzle'],
		// 	injectJs: ['demoPuzzles.js', 'js/services.js'],
		// 	injectCss: 'css/demoPuzzle.css'
		// },

		rima: {
			path: [APP_SRC_STR, 'components/rima'],
			injectJs: ['js/directives.js', 'js/services.js', 'js/filters.js'],
			injectCss: 'css/default.css'
		},

		notify: {
			path: [APP_SRC_STR, 'components/notify'],
			injectJs: ['js/directives.js', 'js/services.js'],
			injectCss: 'css/default.css'
		},

		topiChat: {
			path: [APP_SRC_STR, 'components/topiChat'],
			injectJs: ['js/directives.js', 'js/services.js'],
			injectCss: 'css/default.css'
		},

		request: {
			path: [APP_SRC_STR, 'components/request'],
			injectJs: 'services.js',
			injectCss: 'css/request.component.css'
		},

		suggestion: {
			path: [APP_SRC_STR, 'components/suggestion'],
			injectJs: 'services.js',
			injectCss: 'css/suggestion.component.css'
		},
		bottomPanel: {
			path: [APP_SRC_STR, 'components/bottomPanel'],
			injectJs: [],
			injectCss: 'css/bottomPanel.css'
		},
		change: {
			path: [APP_SRC_STR, 'components/change'],
			injectJs: ['changes.js', 'services.js'],
			injectCss: 'css/change.component.css'
		},
		login: {
			path: [APP_SRC_STR, 'components/login'],
			injectJs: ['js/directives.js', 'js/services.js'],
			injectCss: 'css/default.css'
		},
		ontov: {
			path: [APP_SRC_STR, 'components/ontov'],
			injectJs: ['js/vendor/underscore-1.8.3.min.js', 'js/vendor/underscore-1.8.3.min.js',
			'js/vendor/backbone-1.1.2.min.js',
			'js/vendor/query-engine.js',
			'js/vendor/dependencies.js',
			'js/vendor/visualsearch.js'
			],
			injectCss: ['css/default.css', 'css/visualsearch/visualsearch-datauri.css']
		},

		mcMap: {
			path: [APP_SRC_STR, 'js/mcm'],
			injectJs: ['mcm.js', 'map.js', 'entitiesToolset.js']
		},
		mapsList: {
			path: [APP_SRC_STR, 'components/mapsList'],
			injectJs: 'css/maps-list.component.css'
		},

		brainstorming: {
			path: [APP_SRC_STR, 'components/brainstorming'],
			injectJs: ['brainstormings.js', 'js/services.js'],
			injectCss: 'css/brainstorming.component.css'
		},

		session: {
			path: [APP_SRC_STR, 'components/session'],
			injectJs: ['sessions.js', 'js/services.js'],
			injectCss: 'css/session.css'
		},

		gardening: {
			path: [APP_SRC_STR, 'components/gardening'],
			css: true,
			// { src: join('components/gardening/js/services.js'), inject: true, noNorm: true },

			// SUB_PROJECTS_FILES.KNALLEDGE.APP_ASSETS.NPM_DEPENDENCIES
			injectJs: 'js/services.js',
			// { src: join(APP_SRC, 'components/gardening/css/default.css'), inject: true, dest: CSS_DEST, noNorm: true },
			injectCss: 'css/default.css'
		}
	},
	puzzlesConfig: {
		// demoPuzzle: {
		// 	available: true
		// },
		knalledgeMap: {
			available: true
		},
		rima: {
			available: true
		},
		collaboPlugins: {
			available: true
		},
		notify: {
			available: true
		},
		topiChat: {
			available: true
		},
		request: {
			available: true
		},
		suggestion: {
			available: false
		},
		brainstorming: {
			available: false
		},
		session: {
			available: false
		},
		change: {
			available: true
		},
		login: {
			available: true
		},
		ontov: {
			available: true
		},
		mcMap: {
			available: true
		},
		mapsList: {
			available: true
		},
		gardening: {
			available: true
		}
	},
	puzzles: {
		knalledgeMap: {
	        active: true,
	        config: {
	            knalledgeMapVOsService: {
					// should map participants be broadcasted after loading map
	                broadcastMapUsers: true
	            },
				knAllEdgeRealTimeService: {
	                available: true
	            }
	        }
		},
		topPanel: {
	        active: false,
	        config: {
	            suggestion: {
					available: false
	            },
				request: {
					available: false
	            },
	        }
		},
		mapsList: {
			active: true,
			config: {
				title: 'MCM',
				//map_path,
				//
				openMap: {
					routes: [{
						route: 'mcmap',
						name: 'MCM-Map',
						icon: ''
					}, {
						route: 'map',
						name: 'KnAllEdge-Map',
						icon: ''
					}]
				}
			}
		},
		ontov: {
	        active: true
		},
		rima: {
	        active: true,
	        config: {
	            rimaService: {
					available: true,
					ANONYMOUS_USER_ID: "55268521fb9a901e442172f8",
					// should the service wait for users be broadcasted from other components
					// (like KnalledgeMapVOsService) or request loading all of them?
	                waitToReceiveRimaList: true
	            }
	        }
		},
		request: {
	        active: false,
	        services: {
	            requestService: {
					name: 'RequestService',
					path: 'request.RequestService'
					// icons: {
					// 	showRequests: {
					// 		position: "nw",
					// 		iconClass: "fa-bell",
					// 		action: "showRequests"
					// 	}
					// }
	            }
	        },
			plugins: {
				mapVisualizeHaloPlugins: ['requestService'],
				// mapInteractionPlugins: ['requestService'],
				keboardPlugins: ['requestService']
			}
		},
		notify: {
			active: true,
			services: {
				NotifyNodeService: {
				}
			},
			plugins: {
				mapVisualizePlugins: ['NotifyNodeService']
			}
		},
		collaboGrammar: {
			active: true,
			config: {
	            collaboGrammarService: {
					available: true
	            }
	        }
		},
		gardening: {
			active: true,
			services: {
				ApprovalNodeService: {
				}
			},
			plugins: {
				mapVisualizePlugins: ['ApprovalNodeService']
			}
		}
	}
};

if(typeof window !== 'undefined'){
	if(typeof window.Config === 'undefined') window.Config = {};
	window.Config.Plugins = plugins;
}

if(typeof angular !== 'undefined'){
	angular.module('Config')
		.constant("Plugins", plugins);
	}

if(typeof global !== 'undefined'){
	if(typeof global.Config === 'undefined') global.Config = {};
	global.Config.Plugins = plugins;
}

// node.js world
if(typeof module !== 'undefined'){
	module.exports = (function() {
		return {
			plugins: plugins,
			project: project
		};
	})();
}

}()); // end of 'use strict';
<commit_msg>cleaned out old ontov requirements<commit_after>(function () { // This prevents problems when concatenating scripts that aren't strict.
'use strict';

var project = {
	name: 'MCM',
	port: 5556,
	subProjects: {
		MCM: {
	        BOOTSTRAP_MODULE: 'js/app2',
	        BOOTSTRAP_MODULE_HOT_LOADER: 'hot_loader_app2',
	        SELECTOR: 'button-basic-usage',
	        APP_SRC: 'app',
	        APP_TITLE: 'McModelar',
	        COMPILATION: {},
	        SYM_LINKS_EXISTS: true
	    }
	}
}

var APP_SRC = project.subProjects.MCM.APP_SRC;
var APP_DEST = 'APP_DEST';

var APP_SRC_STR = 'APP_SRC_STR';
var APP_DEST_STR = 'APP_DEST_STR';

project.subProjects.MCM.COMPILATION = {
    ADD_ANTICACHE_SUFIX: false,
    INLINE_NG1: {
        SRC: project.subProjects.MCM.SYM_LINKS_EXISTS ?
            // this does work for symbolic links
            ['**/*.tpl.html'] :
            // this doesn't work for symbolic links
            [join(APP_SRC, '**/*.tpl.html')]
    },
    INLINE: {
        USE_RELATIVE_PATHS: true
    },
    COMPASS: {
        // NOTE: !!!if true, this will output css files into sass folder!!!
        // due to [issue-61](https://github.com/appleboy/gulp-compass/issues/61)
        GENERIC: false,
        // if value of the path key is not set to object, default values will be considered
        PATHS: {
            '': { destDir: APP_SRC, cssDir: 'css' },
            'components/collaboPlugins': { destDir: APP_SRC, cssDir: 'css' },
            'components/knalledgeMap': { destDir: APP_SRC, cssDir: 'css' },
            'components/login': { destDir: APP_SRC, cssDir: 'css' },
            'components/notify': { destDir: APP_SRC, cssDir: 'css' },
            'components/gardening': { destDir: APP_SRC, cssDir: 'css' },
            'components/rima': { destDir: APP_SRC, cssDir: 'css' },
            'components/topiChat': { destDir: APP_SRC, cssDir: 'css' },
            'components/mcmMap': { destDir: APP_SRC, cssDir: 'css' },
            'components/mcmMaps': { destDir: APP_SRC, cssDir: 'css' },
            'components/mapsList': { destDir: APP_SRC, cssDir: 'css' }
        }
    }
};

/* Configuration */
var plugins = {
	"ViewComponents": {
		"knalledgeMap.Main": {
			components: {
				TopPanel: {
					active: false,
					path: "/components/topPanel/topPanel"
				}
			}
		},
		"bottomPanel.BottomPanel": {
			components: {
				'brainstorming.BrainstormingPanelComponent': {
					false: true,
					path: "/components/brainstorming/brainstorming-panel.component"
				}
			}
		},
		"knalledgeMap.KnalledgeMapTools": {
			components: {
				GardeningControls: {
					active: true,
					path: "/components/gardening/gardening-controls.component"
				},
				RimaUsersList: {
					active: true,
					path: "/components/rima/rimaUsersList"
				},
				IbisTypesList: {
					active: true,
					path: "/components/knalledgeMap/ibisTypesList"
				}
			},
		}
	},

	puzzlesBuild: {
		knalledgeMap: {
			directive: {
				path: [APP_SRC_STR, 'components/knalledgeMap'],
				injectJs: [
					'js/directives.js', 'js/services.js'
				],
				injectCss: ['css/default.css', 'css/graph.css']
			},
			interaction: {
				path: [APP_SRC_STR, 'js/interaction'],
				injectJs: ['interaction.js', 'moveAndDrag.js', 'keyboard.js']
			},
			knalledge: {
				path: [APP_SRC_STR, 'js/knalledge'],
				injectJs: ['mapLayout.js', 'mapVisualization.js', 'mapLayoutTree.js', 'mapVisualizationTree.js', 'mapLayoutFlat.js', 'mapVisualizationFlat.js', 'mapLayoutGraph.js', 'mapVisualizationGraph.js', 'mapManager.js', 'map.js']
			}
		},
		collaboPlugins: {
			path: [APP_SRC_STR, 'components/collaboPlugins'],
			injectJs: ['js/directives.js', 'js/services.js'],
			injectCss: 'css/default.css'
		},

		// demoPuzzle: {
		// 	path: [APP_SRC_STR, 'components/demoPuzzle'],
		// 	injectJs: ['demoPuzzles.js', 'js/services.js'],
		// 	injectCss: 'css/demoPuzzle.css'
		// },

		rima: {
			path: [APP_SRC_STR, 'components/rima'],
			injectJs: ['js/directives.js', 'js/services.js', 'js/filters.js'],
			injectCss: 'css/default.css'
		},

		notify: {
			path: [APP_SRC_STR, 'components/notify'],
			injectJs: ['js/directives.js', 'js/services.js'],
			injectCss: 'css/default.css'
		},

		topiChat: {
			path: [APP_SRC_STR, 'components/topiChat'],
			injectJs: ['js/directives.js', 'js/services.js'],
			injectCss: 'css/default.css'
		},

		request: {
			path: [APP_SRC_STR, 'components/request'],
			injectJs: 'services.js',
			injectCss: 'css/request.component.css'
		},

		suggestion: {
			path: [APP_SRC_STR, 'components/suggestion'],
			injectJs: 'services.js',
			injectCss: 'css/suggestion.component.css'
		},
		bottomPanel: {
			path: [APP_SRC_STR, 'components/bottomPanel'],
			injectJs: [],
			injectCss: 'css/bottomPanel.css'
		},
		change: {
			path: [APP_SRC_STR, 'components/change'],
			injectJs: ['changes.js', 'services.js'],
			injectCss: 'css/change.component.css'
		},
		login: {
			path: [APP_SRC_STR, 'components/login'],
			injectJs: ['js/directives.js', 'js/services.js'],
			injectCss: 'css/default.css'
		},
		ontov: {
			path: [APP_SRC_STR, 'components/ontov'],
			injectJs: [
				'js/vendor/underscore-1.8.3.min.js',
				'js/vendor/backbone-1.1.2.min.js',
				'js/vendor/query-engine.js',
				'js/vendor/dependencies.js',
				'js/vendor/visualsearch.js'
			],
			injectCss: ['css/default.css', 'css/visualsearch/visualsearch-datauri.css']
		},

		mcMap: {
			path: [APP_SRC_STR, 'js/mcm'],
			injectJs: ['mcm.js', 'map.js', 'entitiesToolset.js']
		},
		mapsList: {
			path: [APP_SRC_STR, 'components/mapsList'],
			injectJs: 'css/maps-list.component.css'
		},

		brainstorming: {
			path: [APP_SRC_STR, 'components/brainstorming'],
			injectJs: ['brainstormings.js', 'js/services.js'],
			injectCss: 'css/brainstorming.component.css'
		},

		session: {
			path: [APP_SRC_STR, 'components/session'],
			injectJs: ['sessions.js', 'js/services.js'],
			injectCss: 'css/session.css'
		},

		gardening: {
			path: [APP_SRC_STR, 'components/gardening'],
			css: true,
			// { src: join('components/gardening/js/services.js'), inject: true, noNorm: true },

			// SUB_PROJECTS_FILES.KNALLEDGE.APP_ASSETS.NPM_DEPENDENCIES
			injectJs: 'js/services.js',
			// { src: join(APP_SRC, 'components/gardening/css/default.css'), inject: true, dest: CSS_DEST, noNorm: true },
			injectCss: 'css/default.css'
		}
	},
	puzzlesConfig: {
		// demoPuzzle: {
		// 	available: true
		// },
		knalledgeMap: {
			available: true
		},
		rima: {
			available: true
		},
		collaboPlugins: {
			available: true
		},
		notify: {
			available: true
		},
		topiChat: {
			available: true
		},
		request: {
			available: true
		},
		suggestion: {
			available: false
		},
		brainstorming: {
			available: false
		},
		session: {
			available: false
		},
		change: {
			available: true
		},
		login: {
			available: true
		},
		ontov: {
			available: true
		},
		mcMap: {
			available: true
		},
		mapsList: {
			available: true
		},
		gardening: {
			available: true
		}
	},
	puzzles: {
		knalledgeMap: {
	        active: true,
	        config: {
	            knalledgeMapVOsService: {
					// should map participants be broadcasted after loading map
	                broadcastMapUsers: true
	            },
				knAllEdgeRealTimeService: {
	                available: true
	            }
	        }
		},
		topPanel: {
	        active: false,
	        config: {
	            suggestion: {
					available: false
	            },
				request: {
					available: false
	            },
	        }
		},
		mapsList: {
			active: true,
			config: {
				title: 'MCM',
				//map_path,
				//
				openMap: {
					routes: [{
						route: 'mcmap',
						name: 'MCM-Map',
						icon: ''
					}, {
						route: 'map',
						name: 'KnAllEdge-Map',
						icon: ''
					}]
				}
			}
		},
		ontov: {
	        active: true
		},
		rima: {
	        active: true,
	        config: {
	            rimaService: {
					available: true,
					ANONYMOUS_USER_ID: "55268521fb9a901e442172f8",
					// should the service wait for users be broadcasted from other components
					// (like KnalledgeMapVOsService) or request loading all of them?
	                waitToReceiveRimaList: true
	            }
	        }
		},
		request: {
	        active: false,
	        services: {
	            requestService: {
					name: 'RequestService',
					path: 'request.RequestService'
					// icons: {
					// 	showRequests: {
					// 		position: "nw",
					// 		iconClass: "fa-bell",
					// 		action: "showRequests"
					// 	}
					// }
	            }
	        },
			plugins: {
				mapVisualizeHaloPlugins: ['requestService'],
				// mapInteractionPlugins: ['requestService'],
				keboardPlugins: ['requestService']
			}
		},
		notify: {
			active: true,
			services: {
				NotifyNodeService: {
				}
			},
			plugins: {
				mapVisualizePlugins: ['NotifyNodeService']
			}
		},
		collaboGrammar: {
			active: true,
			config: {
	            collaboGrammarService: {
					available: true
	            }
	        }
		},
		gardening: {
			active: true,
			services: {
				ApprovalNodeService: {
				}
			},
			plugins: {
				mapVisualizePlugins: ['ApprovalNodeService']
			}
		}
	}
};

if(typeof window !== 'undefined'){
	if(typeof window.Config === 'undefined') window.Config = {};
	window.Config.Plugins = plugins;
}

if(typeof angular !== 'undefined'){
	angular.module('Config')
		.constant("Plugins", plugins);
	}

if(typeof global !== 'undefined'){
	if(typeof global.Config === 'undefined') global.Config = {};
	global.Config.Plugins = plugins;
}

// node.js world
if(typeof module !== 'undefined'){
	module.exports = (function() {
		return {
			plugins: plugins,
			project: project
		};
	})();
}

}()); // end of 'use strict';
<|endoftext|>


<commit_before>// Copyright 2014 Volker Sorge
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview API of the Speech Rule Engine.
 *
 * @author volker.sorge@gmail.com (Volker Sorge)
 */
goog.provide('sre.Api');

goog.require('sre.DomUtil');
goog.require('sre.Engine.Mode');
goog.require('sre.System');

/**
 * Basic structure for api functions (not a constructor!).
 */
sre.Api = { };

/**
 * Exports the version number of SRE.
 */
module.exports.version = sre.System.getInstance().version;

/**
 * Exporting method to return an aural rendered speech string.
 */
module.exports.toSpeech = sre.System.getInstance().toSpeech;

/**
 * Exporting method to return an XML string of the semantic tree.
 */
module.exports.toSemantic = sre.System.getInstance().toSemantic;

/**
 * Exporting method to return an Json representation of the semantic tree.
 */
module.exports.toJson = sre.System.getInstance().toJson;

/**
 * Exporting method to return auditory descriptions of the input.
 */
module.exports.toDescription = sre.System.getInstance().toDescription;

/**
 * Exporting method to return semantically enriched MathML.
 */
module.exports.toEnriched = sre.System.getInstance().toEnriched;

/**
 * Exporting method to walk an expression.
 */
module.exports.walk = sre.System.getInstance().walk;

/**
 * Exporting method to move on an expression.
 */
module.exports.move = sre.System.getInstance().move;

/**
 * Object for file io.
 */
module.exports.file = {};

/**
 * Exporting method to aural render an expression from a file.
 */
module.exports.file.toSpeech = sre.System.getInstance().fileToSpeech;

/**
 * Exporting method to compute the semantic tree for an expression from a file.
 */
module.exports.file.toSemantic = sre.System.getInstance().fileToSemantic;

/**
 * Exporting method to compute the Json of the semantic tree for an expression
 * from a file.
 */
module.exports.file.toJson = sre.System.getInstance().fileToJson;

/**
 * Exporting method to compute auditory descriptions for an expression from a
 * file.
 */
module.exports.file.toDescription = sre.System.getInstance().fileToDescription;

/**
 * Exporting method to compute semantically enriched MathML for an expression
 * from a file.
 */
module.exports.file.toEnriched = sre.System.getInstance().fileToEnriched;

/**
 * Exporting method to set up and parameterise the Engine.
 */
module.exports.setupEngine = sre.System.getInstance().setupEngine;

/**
 * Exporting XML pretty printer.
 */
module.exports.pprintXML = sre.DomUtil.formatXml;

/**
 * Exporting readiness flag.
 */
module.exports.engineReady = sre.Engine.isReady;

/**
 * Default setup of the Engine.
 */
if (global && global.SRE_JSON_PATH) {
  (sre.System.getInstance()).setupEngine({'mode': sre.Engine.Mode.ASYNC});
}
<commit_msg>Changes setup to use async mode only after engine is ready.<commit_after>// Copyright 2014 Volker Sorge
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview API of the Speech Rule Engine.
 *
 * @author volker.sorge@gmail.com (Volker Sorge)
 */
goog.provide('sre.Api');

goog.require('sre.DomUtil');
goog.require('sre.Engine.Mode');
goog.require('sre.System');

/**
 * Basic structure for api functions (not a constructor!).
 */
sre.Api = { };

/**
 * Exports the version number of SRE.
 */
module.exports.version = sre.System.getInstance().version;

/**
 * Exporting method to return an aural rendered speech string.
 */
module.exports.toSpeech = sre.System.getInstance().toSpeech;

/**
 * Exporting method to return an XML string of the semantic tree.
 */
module.exports.toSemantic = sre.System.getInstance().toSemantic;

/**
 * Exporting method to return an Json representation of the semantic tree.
 */
module.exports.toJson = sre.System.getInstance().toJson;

/**
 * Exporting method to return auditory descriptions of the input.
 */
module.exports.toDescription = sre.System.getInstance().toDescription;

/**
 * Exporting method to return semantically enriched MathML.
 */
module.exports.toEnriched = sre.System.getInstance().toEnriched;

/**
 * Exporting method to walk an expression.
 */
module.exports.walk = sre.System.getInstance().walk;

/**
 * Exporting method to move on an expression.
 */
module.exports.move = sre.System.getInstance().move;

/**
 * Object for file io.
 */
module.exports.file = {};

/**
 * Exporting method to aural render an expression from a file.
 */
module.exports.file.toSpeech = sre.System.getInstance().fileToSpeech;

/**
 * Exporting method to compute the semantic tree for an expression from a file.
 */
module.exports.file.toSemantic = sre.System.getInstance().fileToSemantic;

/**
 * Exporting method to compute the Json of the semantic tree for an expression
 * from a file.
 */
module.exports.file.toJson = sre.System.getInstance().fileToJson;

/**
 * Exporting method to compute auditory descriptions for an expression from a
 * file.
 */
module.exports.file.toDescription = sre.System.getInstance().fileToDescription;

/**
 * Exporting method to compute semantically enriched MathML for an expression
 * from a file.
 */
module.exports.file.toEnriched = sre.System.getInstance().fileToEnriched;

/**
 * Exporting method to set up and parameterise the Engine.
 */
module.exports.setupEngine = sre.System.getInstance().setupEngine;

/**
 * Exporting XML pretty printer.
 */
module.exports.pprintXML = sre.DomUtil.formatXml;

/**
 * Exporting readiness flag.
 */
module.exports.engineReady = sre.Engine.isReady;

/**
 * Setting engine to async mode once it is ready.
 */
sre.Api.setAsync = function() {
  if (!sre.Engine.isReady()) {
    setTimeout(sre.Api.setAsync, 500);
  }
  (sre.System.getInstance()).setupEngine({'mode': sre.Engine.Mode.ASYNC});
};

/**
 * Default setup of the Engine.
 */
if (global && global.SRE_JSON_PATH) {
  sre.Api.setAsync();
}

<|endoftext|>


<commit_before>Template.outreach.helpers({
	headline: "Get Involved",
	content: "
We believe that everyone has a role and a responsibility
in this work. WCASA is always seeking passionate folks
to join up and help make a difference.
",
	items: [{
		tabs: [{
				title: 'Volunteer',
				id: 'volunteer',
				template : 'volunteer'
			},{
				title: 'Join The Board',
				id: 'joinTheBoard',
				template : 'joinTheBoard'
			},{
				title: 'WCASA Jobs',
				id: 'wcasaJobs',
				template: 'wcasaJobs'
			}
		]
	}]
});

Template.volunteer.helpers({
    headline: "Volunteer with WCASA",
    content: "
Interested in volunteering with WCASA? All interested parties should contact Kathleen Brandenburg, Office Manager at (608) 257-1516 or wcasa@wcasa.org.
",
    listHeadline: "Current Volunteering Opportunities",
    lists: [{
	    type: 'article', //accepts: generic, details, article
	    itemType: 'category',
	    style: 'striped',
	    categories: [{
	        title: 'Clerical',
	        id: 'jobA',
	        items: [{
	            content: '
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.

Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
',
	        }]
	    },{
 	        title: 'Another Position',
	        id: 'jobB',
	        items: [{
	            content: '
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.

Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
',
	        }]
        },{
 	        title: 'Yet Another Position',
	        id: 'jobC',
	        items: [{
	            content: '
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.

Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
',
	        }]
        }]
	}]
});

Template.joinTheBoard.helpers({
    headline: "Join The Board",
    content: "
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.

Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat..
",
});

Template.wcasaJobs.helpers({
    headline: "Join The Board",
    content: "
Interested in volunteering with WCASA? All interested parties should contact Kathleen Brandenburg, Office Manager at (608) 257-1516 or wcasa@wcasa.org.
",
    listHeadline: "Find a Job at WCASA",
    lists: [{
	    type: 'article', //accepts: generic, details, article
	    itemType: 'category',
	    style: 'striped',
	    categories: [{
	        title: 'Clerical',
	        id: 'jobA',
	        items: [{
	            content: '
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.

Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
',
	        }]
	    },{
 	        title: 'Another Position',
	        id: 'jobB',
	        items: [{
	            content: '
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.

Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
',
	        }]
        },{
 	        title: 'Yet Another Position',
	        id: 'jobC',
	        items: [{
	            content: '
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.

Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
',
	        }]
        }]
	}]
});<commit_msg>Correct terms.<commit_after>Template.outreach.helpers({
	headline: "Get Involved",
	content: "
We believe that everyone has a role and a responsibility
in this work. WCASA is always seeking passionate folks
to join up and help make a difference.
",
	items: [{
		tabs: [{
				title: 'Volunteer',
				id: 'volunteer',
				template : 'volunteer'
			},{
				title: 'Join The Board',
				id: 'joinTheBoard',
				template : 'joinTheBoard'
			},{
				title: 'WCASA Jobs',
				id: 'wcasaJobs',
				template: 'wcasaJobs'
			}
		]
	}]
});

Template.volunteer.helpers({
    headline: "Volunteer with WCASA",
    content: "
Interested in volunteering with WCASA? All interested parties should contact Kathleen Brandenburg, Office Manager at (608) 257-1516 or wcasa@wcasa.org.
",
    listHeadline: "Current Volunteering Opportunities",
    lists: [{
	    type: 'article', //accepts: generic, details, article
	    itemType: 'category',
	    style: 'striped',
	    categories: [{
	        title: 'Clerical',
	        id: 'jobA',
	        items: [{
	            content: '
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.

Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
',
	        }]
	    },{
 	        title: 'Another Position',
	        id: 'jobB',
	        items: [{
	            content: '
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.

Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
',
	        }]
        },{
 	        title: 'Yet Another Position',
	        id: 'jobC',
	        items: [{
	            content: '
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.

Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
',
	        }]
        }]
	}]
});

Template.joinTheBoard.helpers({
    headline: "Join The Board",
    content: "
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.

Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat..
",
});

Template.wcasaJobs.helpers({
    headline: "WCASA Jobs",
    content: "
Interested in volunteering with WCASA? All interested parties should contact Kathleen Brandenburg, Office Manager at (608) 257-1516 or wcasa@wcasa.org.
",
    listHeadline: "Find a Job at WCASA",
    lists: [{
	    type: 'article', //accepts: generic, details, article
	    itemType: 'category',
	    style: 'striped',
	    categories: [{
	        title: 'Clerical',
	        id: 'jobA',
	        items: [{
	            content: '
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.

Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
',
	        }]
	    },{
 	        title: 'Another Position',
	        id: 'jobB',
	        items: [{
	            content: '
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.

Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
',
	        }]
        },{
 	        title: 'Yet Another Position',
	        id: 'jobC',
	        items: [{
	            content: '
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.

Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
',
	        }]
        }]
	}]
});<|endoftext|>


<commit_before>physics = [
    {
        title: 'Decay Spectroscopy of 129Cd',
        authors: 'Y. Saito et al.',
        link: 'https://journals.aps.org/prc/accepted/1a07aPdaAd512f0d76050764d3e2f31a9010b1751',
        linkTitle: 'Accepted in Phys. Rev. C',
        openLink: 'https://arxiv.org/abs/2008.02959',
        openLinkTitle: 'arXiv:2008.02959'
    },
    {
        title: 'Beta-Decay of 132In and Spectroscopy of 132Sn and 131Sb with the GRIFFIN Spectrometer',
        authors: 'K. Whitmore et al.',
        link: 'https://link.aps.org/doi/10.1103/PhysRevC.102.024327',
        linkTitle: 'Phys. Rev. C 102, 024327 (2020)',
        openLink: 'https://arxiv.org/abs/2008.00548',
        openLinkTitle: 'arXiv:2008.00548'
    },
    {
        title: 'Collective 2p-2h intruder states in 118Sn studied via beta-decay of 118In using GRIFFIN',
        authors: 'K. Ortner et al.',
        link: 'https://link.aps.org/doi/10.1103/PhysRevC.102.024323',
        linkTitle: 'Phys. Rev. C 102, 024323 (2020)',
        openLink: 'https://arxiv.org/abs/2007.16202',
        openLinkTitle: 'arXiv:2007.16202'
    },
    {
        title: 'Detailed spectroscopy of 46Ca: An investigation of the beta decay of 46K',
        authors: 'J. Pore et al.',
        link: 'https://link.aps.org/doi/10.1103/PhysRevC.100.054327',
        linkTitle: 'Phys. Rev. C 100, 054327 (2019)',
        openLink: 'http://arxiv.org/abs/1912.02407',
        openLinkTitle: 'arXiv:1912.02407'
    },
    {
        title: 'Shape coexistence in the neutron-deficient Pb region: A systematic study of lifetimes in the even 188-200Hg with the GRIFFIN spectrometer at TRIUMF',
        authors: 'B. Olaizola et al.',
        link: 'https://link.aps.org/doi/10.1103/PhysRevC.100.024301',
        linkTitle: 'Phys. Rev. C 100, 024301 (2019)',
        openLink: 'http://arxiv.org/abs/1907.12274',
        openLinkTitle: 'arXiv:1907.12274'
    },
    {
        title: 'Beta-decay and beta-delayed neutron decay of the N=82 nucleus 131In',
        authors: 'R. Dunlop et al.',
        link: 'https://link.aps.org/doi/10.1103/PhysRevC.99.045805',
        linkTitle: 'Phys. Rev. C 99, 045805 (2019)',
        openLink: 'https://arxiv.org/abs/1903.12277',
        openLinkTitle: 'arXiv:1903.12277'
    },
    {
        title: 'High-precision half-life measurement for the superallowed Fermi beta+ emitter 22Mg',
        authors: 'M.R. Dunlop et al.',
        link: 'https://link.aps.org/doi/10.1103/PhysRevC.96.045502',
        linkTitle: 'Phys. Rev. C 96, 045502 (2017)',
        openLink: 'http://arxiv.org/abs/1711.00827',
        openLinkTitle: 'arXiv:1711.00827'
    },
    {
        title: 'Spectroscopy of 50Sc and ab initio calculations of B(M3) strengths',
        authors: 'A.B. Garnsworthy et al.',
        link: 'https://link.aps.org/doi/10.1103/PhysRevC.96.044329',
        linkTitle: 'Phys. Rev. C 96, 044329 (2017)',
        openLink: 'http://arxiv.org/abs/1710.06338',
        openLinkTitle: 'arXiv:1710.06338'
    },
    {
        title: 'Half-Lives of Neutron-Rich 128-130Cd',
        authors: 'R. Dunlop et al.',
        link: 'http://link.aps.org/doi/10.1103/PhysRevC.93.062801',
        linkTitle: 'Phys. Rev. C 93, 062801(R) (2016)',
        openLink: 'http://arxiv.org/abs/1711.05621',
        openLinkTitle: 'arXiv:1711.05621'
    }
]
conference = [

    {
        title: 'High-statistics beta-decay measurements at TRIUMF-ISAC and the transition from the 8pi spectrometer to GRIFFIN',
        authors: 'P.E. Garrett et al.',
        link: 'https://doi.org/10.1051/epjconf/201819304011',
        linkTitle: 'Proceedings of FUSION2017, EPJ Web Conf. 193, 04011 (2018)'
    },

    {
        title: 'First results from GRIFFIN including half-Lives of 128-130Cd',
        authors: 'R. Dunlop et al.',
        link: 'https://pos.sissa.it/archive/conferences/281/140/INPC2016_140.pdf',
        linkTitle: 'Proceedings of Science (INPC2016), 140 (2017)'
    },

    {
        title: 'High-statistics beta-decay measurements at TRIUMF-ISAC and the transition from the 8pi spectrometer to GRIFFIN',
        authors: 'P.E. Garrett et al.',
        link: 'http://www.actaphys.uj.edu.pl/fulltext?series=Reg&vol=48&page=523',
        linkTitle: 'Acta Phys.Pol. B, 48, 523 (2017)'
    },

    {
        title: 'Web-based parameter control and real-time waveform display for the GRIFFIN experiment',
        authors: 'B.J. Shaw and P.A. Amaudruz and D.P. Bishop',
        link: 'https://doi.org/10.1109/RTC.2016.7543140',
        linkTitle: 'Proceedings of 2016 IEEE-NPSS Real Time Conference (RT), 7543140 (2016)'
    },

    {
        title: 'Exploring exotic nuclei with the GRIFFIN Spectrometer at TRIUMF-ISAC',
        authors: 'A.B. Garnsworthy',
        link: 'http://www.actaphys.uj.edu.pl/fulltext?series=Reg&vol=47&page=713',
        linkTitle: 'Acta Phys.Pol. B, 47, 713 (2016)'
    },

    {
        title: 'Far from easy spectroscopy with the 8pi and GRIFFIN spectrometers at TRIUMF-ISAC',
        authors: 'P.E. Garrett et al.',
        link: 'http://iopscience.iop.org/article/10.1088/1742-6596/639/1/012006/pdf',
        linkTitle: 'Journal of Physics Conference Series 639, 012006 (2015)'
    }
]
technical = [
    {
        title: 'The GRIFFIN Facility for Decay-Spectroscopy Studies at TRIUMF-ISAC',
        authors: 'A.B. Garnsworthy et al.',
        link: 'https://doi.org/10.1016/j.nima.2018.11.115',
        linkTitle: 'Nucl. Inst. Meths. A 918, 9 (2019)',
        openLink: 'https://arxiv.org/abs/1809.07183',
        openLinkTitle: 'arxiv:1809.07183'
    },

    {
        title: 'Gamma-gamma angular correlation analysis techniques with the GRIFFIN spectrometer',
        authors: 'J.K. Smith et al.',
        link: 'https://doi.org/10.1016/j.nima.2018.10.097',
        linkTitle: 'Nucl. Inst. Meths. A 922, 47 (2019)',
        openLink: 'http://arxiv.org/abs/1807.07570',
        openLinkTitle: 'arXiv:1807.07570'
    },

    {
        title: 'The GRIFFIN data acquisition system',
        authors: 'A.B. Garnsworthy et al.',
        link: 'http://www.sciencedirect.com/science/article/pii/S0168900217302243',
        linkTitle: 'Nucl. Inst. Meths. A 853, 85 (2017)',
        openLink: 'http://arxiv.org/abs/1711.06236',
        openLinkTitle: 'arXiv:1711.06236'
    },

    {
        title: 'Characteristics of GRIFFIN high-purity germanium clover detectors',
        authors: 'U. Rizwan et al.',
        link: 'http://www.sciencedirect.com/science/article/pii/S0168900216300341',
        linkTitle: 'Nucl. Inst. Meths. A 820, 126 (2016)',
        openLink: 'http://arxiv.org/abs/1711.05287',
        openLinkTitle: 'arxiv:1711.05287'
    },

    {
        title: 'The GRIFFIN Spectrometer',
        authors: 'C.E. Svensson and A.B. Garnsworthy',
        link: 'http://link.springer.com/article/10.1007/s10751-013-0889-3',
        linkTitle: 'Hyperfine Interactions, 225, 127 (2014)'
    }
]
<commit_msg>updated citation<commit_after>physics = [
    {
        title: 'Decay Spectroscopy of 129Cd',
        authors: 'Y. Saito et al.',
        link: 'https://link.aps.org/doi/10.1103/PhysRevC.102.024337',
        linkTitle: 'Phys. Rev. C 102, 024337 (2020)',
        openLink: 'https://arxiv.org/abs/2008.02959',
        openLinkTitle: 'arXiv:2008.02959'
    },
    {
        title: 'Beta-Decay of 132In and Spectroscopy of 132Sn and 131Sb with the GRIFFIN Spectrometer',
        authors: 'K. Whitmore et al.',
        link: 'https://link.aps.org/doi/10.1103/PhysRevC.102.024327',
        linkTitle: 'Phys. Rev. C 102, 024327 (2020)',
        openLink: 'https://arxiv.org/abs/2008.00548',
        openLinkTitle: 'arXiv:2008.00548'
    },
    {
        title: 'Collective 2p-2h intruder states in 118Sn studied via beta-decay of 118In using GRIFFIN',
        authors: 'K. Ortner et al.',
        link: 'https://link.aps.org/doi/10.1103/PhysRevC.102.024323',
        linkTitle: 'Phys. Rev. C 102, 024323 (2020)',
        openLink: 'https://arxiv.org/abs/2007.16202',
        openLinkTitle: 'arXiv:2007.16202'
    },
    {
        title: 'Detailed spectroscopy of 46Ca: An investigation of the beta decay of 46K',
        authors: 'J. Pore et al.',
        link: 'https://link.aps.org/doi/10.1103/PhysRevC.100.054327',
        linkTitle: 'Phys. Rev. C 100, 054327 (2019)',
        openLink: 'http://arxiv.org/abs/1912.02407',
        openLinkTitle: 'arXiv:1912.02407'
    },
    {
        title: 'Shape coexistence in the neutron-deficient Pb region: A systematic study of lifetimes in the even 188-200Hg with the GRIFFIN spectrometer at TRIUMF',
        authors: 'B. Olaizola et al.',
        link: 'https://link.aps.org/doi/10.1103/PhysRevC.100.024301',
        linkTitle: 'Phys. Rev. C 100, 024301 (2019)',
        openLink: 'http://arxiv.org/abs/1907.12274',
        openLinkTitle: 'arXiv:1907.12274'
    },
    {
        title: 'Beta-decay and beta-delayed neutron decay of the N=82 nucleus 131In',
        authors: 'R. Dunlop et al.',
        link: 'https://link.aps.org/doi/10.1103/PhysRevC.99.045805',
        linkTitle: 'Phys. Rev. C 99, 045805 (2019)',
        openLink: 'https://arxiv.org/abs/1903.12277',
        openLinkTitle: 'arXiv:1903.12277'
    },
    {
        title: 'High-precision half-life measurement for the superallowed Fermi beta+ emitter 22Mg',
        authors: 'M.R. Dunlop et al.',
        link: 'https://link.aps.org/doi/10.1103/PhysRevC.96.045502',
        linkTitle: 'Phys. Rev. C 96, 045502 (2017)',
        openLink: 'http://arxiv.org/abs/1711.00827',
        openLinkTitle: 'arXiv:1711.00827'
    },
    {
        title: 'Spectroscopy of 50Sc and ab initio calculations of B(M3) strengths',
        authors: 'A.B. Garnsworthy et al.',
        link: 'https://link.aps.org/doi/10.1103/PhysRevC.96.044329',
        linkTitle: 'Phys. Rev. C 96, 044329 (2017)',
        openLink: 'http://arxiv.org/abs/1710.06338',
        openLinkTitle: 'arXiv:1710.06338'
    },
    {
        title: 'Half-Lives of Neutron-Rich 128-130Cd',
        authors: 'R. Dunlop et al.',
        link: 'http://link.aps.org/doi/10.1103/PhysRevC.93.062801',
        linkTitle: 'Phys. Rev. C 93, 062801(R) (2016)',
        openLink: 'http://arxiv.org/abs/1711.05621',
        openLinkTitle: 'arXiv:1711.05621'
    }
]
conference = [

    {
        title: 'High-statistics beta-decay measurements at TRIUMF-ISAC and the transition from the 8pi spectrometer to GRIFFIN',
        authors: 'P.E. Garrett et al.',
        link: 'https://doi.org/10.1051/epjconf/201819304011',
        linkTitle: 'Proceedings of FUSION2017, EPJ Web Conf. 193, 04011 (2018)'
    },

    {
        title: 'First results from GRIFFIN including half-Lives of 128-130Cd',
        authors: 'R. Dunlop et al.',
        link: 'https://pos.sissa.it/archive/conferences/281/140/INPC2016_140.pdf',
        linkTitle: 'Proceedings of Science (INPC2016), 140 (2017)'
    },

    {
        title: 'High-statistics beta-decay measurements at TRIUMF-ISAC and the transition from the 8pi spectrometer to GRIFFIN',
        authors: 'P.E. Garrett et al.',
        link: 'http://www.actaphys.uj.edu.pl/fulltext?series=Reg&vol=48&page=523',
        linkTitle: 'Acta Phys.Pol. B, 48, 523 (2017)'
    },

    {
        title: 'Web-based parameter control and real-time waveform display for the GRIFFIN experiment',
        authors: 'B.J. Shaw and P.A. Amaudruz and D.P. Bishop',
        link: 'https://doi.org/10.1109/RTC.2016.7543140',
        linkTitle: 'Proceedings of 2016 IEEE-NPSS Real Time Conference (RT), 7543140 (2016)'
    },

    {
        title: 'Exploring exotic nuclei with the GRIFFIN Spectrometer at TRIUMF-ISAC',
        authors: 'A.B. Garnsworthy',
        link: 'http://www.actaphys.uj.edu.pl/fulltext?series=Reg&vol=47&page=713',
        linkTitle: 'Acta Phys.Pol. B, 47, 713 (2016)'
    },

    {
        title: 'Far from easy spectroscopy with the 8pi and GRIFFIN spectrometers at TRIUMF-ISAC',
        authors: 'P.E. Garrett et al.',
        link: 'http://iopscience.iop.org/article/10.1088/1742-6596/639/1/012006/pdf',
        linkTitle: 'Journal of Physics Conference Series 639, 012006 (2015)'
    }
]
technical = [
    {
        title: 'The GRIFFIN Facility for Decay-Spectroscopy Studies at TRIUMF-ISAC',
        authors: 'A.B. Garnsworthy et al.',
        link: 'https://doi.org/10.1016/j.nima.2018.11.115',
        linkTitle: 'Nucl. Inst. Meths. A 918, 9 (2019)',
        openLink: 'https://arxiv.org/abs/1809.07183',
        openLinkTitle: 'arxiv:1809.07183'
    },

    {
        title: 'Gamma-gamma angular correlation analysis techniques with the GRIFFIN spectrometer',
        authors: 'J.K. Smith et al.',
        link: 'https://doi.org/10.1016/j.nima.2018.10.097',
        linkTitle: 'Nucl. Inst. Meths. A 922, 47 (2019)',
        openLink: 'http://arxiv.org/abs/1807.07570',
        openLinkTitle: 'arXiv:1807.07570'
    },

    {
        title: 'The GRIFFIN data acquisition system',
        authors: 'A.B. Garnsworthy et al.',
        link: 'http://www.sciencedirect.com/science/article/pii/S0168900217302243',
        linkTitle: 'Nucl. Inst. Meths. A 853, 85 (2017)',
        openLink: 'http://arxiv.org/abs/1711.06236',
        openLinkTitle: 'arXiv:1711.06236'
    },

    {
        title: 'Characteristics of GRIFFIN high-purity germanium clover detectors',
        authors: 'U. Rizwan et al.',
        link: 'http://www.sciencedirect.com/science/article/pii/S0168900216300341',
        linkTitle: 'Nucl. Inst. Meths. A 820, 126 (2016)',
        openLink: 'http://arxiv.org/abs/1711.05287',
        openLinkTitle: 'arxiv:1711.05287'
    },

    {
        title: 'The GRIFFIN Spectrometer',
        authors: 'C.E. Svensson and A.B. Garnsworthy',
        link: 'http://link.springer.com/article/10.1007/s10751-013-0889-3',
        linkTitle: 'Hyperfine Interactions, 225, 127 (2014)'
    }
]
<|endoftext|>


<commit_before>"use strict";

const webpack = require("webpack");
const Server = require("../../lib/Server");
const config = require("../fixtures/simple-config-other/webpack.config");
const runBrowser = require("../helpers/run-browser");
const port = require("../ports-map")["client-option"];

describe("client option", () => {
  describe("default behaviour", () => {
    let compiler;
    let server;
    let page;
    let browser;
    let pageErrors;
    let consoleMessages;

    beforeEach(async () => {
      compiler = webpack(config);

      server = new Server(
        {
          client: {
            webSocketTransport: "sockjs",
          },
          webSocketServer: "sockjs",
          port,
        },
        compiler
      );

      await server.start();

      ({ page, browser } = await runBrowser());

      pageErrors = [];
      consoleMessages = [];
    });

    afterEach(async () => {
      await browser.close();
      await server.stop();
    });

    it("overlay should be true by default", () => {
      expect(server.options.client.overlay).toBe(true);
    });

    it("responds with a 200 status code for /ws path", async () => {
      page
        .on("console", (message) => {
          consoleMessages.push(message);
        })
        .on("pageerror", (error) => {
          pageErrors.push(error);
        });

      const response = await page.goto(`http://127.0.0.1:${port}/ws`, {
        waitUntil: "networkidle0",
      });

      expect(response.status()).toMatchSnapshot("response status");

      expect(consoleMessages.map((message) => message.text())).toMatchSnapshot(
        "console messages"
      );

      expect(pageErrors).toMatchSnapshot("page errors");
    });
  });

  describe("should respect path option", () => {
    let compiler;
    let server;
    let page;
    let browser;
    let pageErrors;
    let consoleMessages;

    beforeEach(async () => {
      compiler = webpack(config);

      server = new Server(
        {
          client: {
            webSocketTransport: "sockjs",
          },
          webSocketServer: {
            type: "sockjs",
            options: {
              host: "localhost",
              port,
              path: "/foo/test/bar",
            },
          },
          port,
        },
        compiler
      );

      await server.start();

      ({ page, browser } = await runBrowser());

      pageErrors = [];
      consoleMessages = [];
    });

    afterEach(async () => {
      await browser.close();
      await server.stop();
    });

    it("responds with a 200 status code for /foo/test/bar path", async () => {
      page
        .on("console", (message) => {
          consoleMessages.push(message);
        })
        .on("pageerror", (error) => {
          pageErrors.push(error);
        });

      const response = await page.goto(
        `http://127.0.0.1:${port}/foo/test/bar`,
        {
          waitUntil: "networkidle0",
        }
      );

      expect(response.status()).toMatchSnapshot("response status");

      expect(consoleMessages.map((message) => message.text())).toMatchSnapshot(
        "console messages"
      );

      expect(pageErrors).toMatchSnapshot("page errors");
    });
  });

  describe("configure client entry", () => {
    let compiler;
    let server;
    let page;
    let browser;
    let pageErrors;
    let consoleMessages;

    beforeEach(async () => {
      compiler = webpack(config);

      server = new Server(
        {
          client: false,
          port,
        },
        compiler
      );

      await server.start();

      ({ page, browser } = await runBrowser());

      pageErrors = [];
      consoleMessages = [];
    });

    afterEach(async () => {
      await browser.close();
      await server.stop();
    });

    it("should disable client entry", async () => {
      page
        .on("console", (message) => {
          consoleMessages.push(message);
        })
        .on("pageerror", (error) => {
          pageErrors.push(error);
        });

      const response = await page.goto(`http://127.0.0.1:${port}/main.js`, {
        waitUntil: "networkidle0",
      });

      expect(response.status()).toMatchSnapshot("response status");

      expect(await response.text()).not.toMatch(/client\/index\.js/);

      expect(consoleMessages.map((message) => message.text())).toMatchSnapshot(
        "console messages"
      );

      expect(pageErrors).toMatchSnapshot("page errors");
    });
  });

  describe("webSocketTransport", () => {
    const clientModes = [
      {
        title: 'as a string ("sockjs")',
        client: {
          webSocketTransport: "sockjs",
        },
        webSocketServer: "sockjs",
        shouldThrow: false,
      },
      {
        title: 'as a string ("ws")',
        client: {
          webSocketTransport: "ws",
        },
        webSocketServer: "ws",
        shouldThrow: false,
      },
      {
        title: 'as a path ("sockjs")',
        client: {
          webSocketTransport: require.resolve(
            "../../client-src/clients/SockJSClient"
          ),
        },
        webSocketServer: "sockjs",
        shouldThrow: false,
      },
      {
        title: 'as a path ("ws")',
        client: {
          webSocketTransport: require.resolve(
            "../../client-src/clients/WebSocketClient"
          ),
        },
        webSocketServer: "ws",
        shouldThrow: false,
      },
      {
        title: "as a nonexistent path (sockjs)",
        client: {
          webSocketTransport: "/bad/path/to/implementation",
        },
        webSocketServer: "sockjs",
        shouldThrow: true,
      },
      {
        title: "as a nonexistent path (ws)",
        client: {
          webSocketTransport: "/bad/path/to/implementation",
        },
        webSocketServer: "ws",
        shouldThrow: true,
      },
    ];

    describe("passed to server", () => {
      clientModes.forEach((data) => {
        it(`${data.title} ${
          data.shouldThrow ? "should throw" : "should not throw"
        }`, async () => {
          const compiler = webpack(config);

          const server = new Server(
            {
              client: data.client,
              port,
            },
            compiler
          );

          let thrownError;

          try {
            await server.start();
          } catch (error) {
            thrownError = error;
          }

          if (data.shouldThrow) {
            expect(thrownError.message).toMatch(
              /client\.webSocketTransport must be a string/
            );
          }

          await server.stop();
        });
      });
    });
  });
});
<commit_msg>ci: fix (#3999)<commit_after>"use strict";

const webpack = require("webpack");
const Server = require("../../lib/Server");
const config = require("../fixtures/simple-config-other/webpack.config");
const runBrowser = require("../helpers/run-browser");
const port = require("../ports-map")["client-option"];

describe("client option", () => {
  describe("default behaviour", () => {
    let compiler;
    let server;
    let page;
    let browser;
    let pageErrors;
    let consoleMessages;

    beforeEach(async () => {
      compiler = webpack(config);

      server = new Server(
        {
          client: {
            webSocketTransport: "sockjs",
          },
          webSocketServer: "sockjs",
          port,
        },
        compiler
      );

      await server.start();

      ({ page, browser } = await runBrowser());

      pageErrors = [];
      consoleMessages = [];
    });

    afterEach(async () => {
      await browser.close();
      await server.stop();
    });

    it("responds with a 200 status code for /ws path", async () => {
      page
        .on("console", (message) => {
          consoleMessages.push(message);
        })
        .on("pageerror", (error) => {
          pageErrors.push(error);
        });

      const response = await page.goto(`http://127.0.0.1:${port}/ws`, {
        waitUntil: "networkidle0",
      });

      // overlay should be true by default
      expect(server.options.client.overlay).toBe(true);

      expect(response.status()).toMatchSnapshot("response status");

      expect(consoleMessages.map((message) => message.text())).toMatchSnapshot(
        "console messages"
      );

      expect(pageErrors).toMatchSnapshot("page errors");
    });
  });

  describe("should respect path option", () => {
    let compiler;
    let server;
    let page;
    let browser;
    let pageErrors;
    let consoleMessages;

    beforeEach(async () => {
      compiler = webpack(config);

      server = new Server(
        {
          client: {
            webSocketTransport: "sockjs",
          },
          webSocketServer: {
            type: "sockjs",
            options: {
              host: "localhost",
              port,
              path: "/foo/test/bar",
            },
          },
          port,
        },
        compiler
      );

      await server.start();

      ({ page, browser } = await runBrowser());

      pageErrors = [];
      consoleMessages = [];
    });

    afterEach(async () => {
      await browser.close();
      await server.stop();
    });

    it("responds with a 200 status code for /foo/test/bar path", async () => {
      page
        .on("console", (message) => {
          consoleMessages.push(message);
        })
        .on("pageerror", (error) => {
          pageErrors.push(error);
        });

      const response = await page.goto(
        `http://127.0.0.1:${port}/foo/test/bar`,
        {
          waitUntil: "networkidle0",
        }
      );

      expect(response.status()).toMatchSnapshot("response status");

      expect(consoleMessages.map((message) => message.text())).toMatchSnapshot(
        "console messages"
      );

      expect(pageErrors).toMatchSnapshot("page errors");
    });
  });

  describe("configure client entry", () => {
    let compiler;
    let server;
    let page;
    let browser;
    let pageErrors;
    let consoleMessages;

    beforeEach(async () => {
      compiler = webpack(config);

      server = new Server(
        {
          client: false,
          port,
        },
        compiler
      );

      await server.start();

      ({ page, browser } = await runBrowser());

      pageErrors = [];
      consoleMessages = [];
    });

    afterEach(async () => {
      await browser.close();
      await server.stop();
    });

    it("should disable client entry", async () => {
      page
        .on("console", (message) => {
          consoleMessages.push(message);
        })
        .on("pageerror", (error) => {
          pageErrors.push(error);
        });

      const response = await page.goto(`http://127.0.0.1:${port}/main.js`, {
        waitUntil: "networkidle0",
      });

      expect(response.status()).toMatchSnapshot("response status");

      expect(await response.text()).not.toMatch(/client\/index\.js/);

      expect(consoleMessages.map((message) => message.text())).toMatchSnapshot(
        "console messages"
      );

      expect(pageErrors).toMatchSnapshot("page errors");
    });
  });

  describe("webSocketTransport", () => {
    const clientModes = [
      {
        title: 'as a string ("sockjs")',
        client: {
          webSocketTransport: "sockjs",
        },
        webSocketServer: "sockjs",
        shouldThrow: false,
      },
      {
        title: 'as a string ("ws")',
        client: {
          webSocketTransport: "ws",
        },
        webSocketServer: "ws",
        shouldThrow: false,
      },
      {
        title: 'as a path ("sockjs")',
        client: {
          webSocketTransport: require.resolve(
            "../../client-src/clients/SockJSClient"
          ),
        },
        webSocketServer: "sockjs",
        shouldThrow: false,
      },
      {
        title: 'as a path ("ws")',
        client: {
          webSocketTransport: require.resolve(
            "../../client-src/clients/WebSocketClient"
          ),
        },
        webSocketServer: "ws",
        shouldThrow: false,
      },
      {
        title: "as a nonexistent path (sockjs)",
        client: {
          webSocketTransport: "/bad/path/to/implementation",
        },
        webSocketServer: "sockjs",
        shouldThrow: true,
      },
      {
        title: "as a nonexistent path (ws)",
        client: {
          webSocketTransport: "/bad/path/to/implementation",
        },
        webSocketServer: "ws",
        shouldThrow: true,
      },
    ];

    describe("passed to server", () => {
      clientModes.forEach((data) => {
        it(`${data.title} ${
          data.shouldThrow ? "should throw" : "should not throw"
        }`, async () => {
          const compiler = webpack(config);

          const server = new Server(
            {
              client: data.client,
              port,
            },
            compiler
          );

          let thrownError;

          try {
            await server.start();
          } catch (error) {
            thrownError = error;
          }

          if (data.shouldThrow) {
            expect(thrownError.message).toMatch(
              /client\.webSocketTransport must be a string/
            );
          }

          await server.stop();
        });
      });
    });
  });
});
<|endoftext|>