<commit_before>/**
 * Range.js
 *
 * Copyright 2009, Moxiecode Systems AB
 * Released under LGPL License.
 *
 * License: http://tinymce.moxiecode.com/license
 * Contributing: http://tinymce.moxiecode.com/contributing
 */

(function(tinymce) {
	tinymce.dom.RangeUtils = function(dom) {
		var INVISIBLE_CHAR = '\uFEFF';

		/**
		 * Walks the specified range like object and executes the callback for each sibling collection it finds.
		 *
		 * @param {Object} rng Range like object.
		 * @param {function} callback Callback function to execute for each sibling collection.
		 */
		this.walk = function(rng, callback) {
			var startContainer = rng.startContainer,
				startOffset = rng.startOffset,
				endContainer = rng.endContainer,
				endOffset = rng.endOffset,
				ancestor, startPoint,
				endPoint, node, parent, siblings, nodes;

			// Handle table cell selection the table plugin enables
			// you to fake select table cells and perform formatting actions on them
			nodes = dom.select('td.mceSelected,th.mceSelected');
			if (nodes.length > 0) {
				tinymce.each(nodes, function(node) {
					callback([node]);
				});

				return;
			}

			/**
			 * Collects siblings
			 *
			 * @private
			 * @param {Node} node Node to collect siblings from.
			 * @param {String} name Name of the sibling to check for.
			 * @return {Array} Array of collected siblings.
			 */
			function collectSiblings(node, name, end_node) {
				var siblings = [];

				for (; node && node != end_node; node = node[name])
					siblings.push(node);

				return siblings;
			};

			/**
			 * Find an end point this is the node just before the common ancestor root.
			 *
			 * @private
			 * @param {Node} node Node to start at.
			 * @param {Node} root Root/ancestor element to stop just before.
			 * @return {Node} Node just before the root element.
			 */
			function findEndPoint(node, root) {
				do {
					if (node.parentNode == root)
						return node;

					node = node.parentNode;
				} while(node);
			};

			function walkBoundary(start_node, end_node, next) {
				var siblingName = next ? 'nextSibling' : 'previousSibling';

				for (node = start_node, parent = node.parentNode; node && node != end_node; node = parent) {
					parent = node.parentNode;
					siblings = collectSiblings(node == start_node ? node : node[siblingName], siblingName);

					if (siblings.length) {
						if (!next)
							siblings.reverse();

						callback(siblings);
					}
				}
			};

			// If index based start position then resolve it
			if (startContainer.nodeType == 1 && startContainer.hasChildNodes())
				startContainer = startContainer.childNodes[startOffset];

			// If index based end position then resolve it
			if (endContainer.nodeType == 1 && endContainer.hasChildNodes())
				endContainer = endContainer.childNodes[Math.min(endOffset - 1, endContainer.childNodes.length - 1)];

			// Find common ancestor and end points
			ancestor = dom.findCommonAncestor(startContainer, endContainer);

			// Same container
			if (startContainer == endContainer)
				return callback([startContainer]);

			// Process left side
			for (node = startContainer; node; node = node.parentNode) {
				if (node == endContainer)
					return walkBoundary(startContainer, ancestor, true);

				if (node == ancestor)
					break;
			}

			// Process right side
			for (node = endContainer; node; node = node.parentNode) {
				if (node == startContainer)
					return walkBoundary(endContainer, ancestor);

				if (node == ancestor)
					break;
			}

			// Find start/end point
			startPoint = findEndPoint(startContainer, ancestor) || startContainer;
			endPoint = findEndPoint(endContainer, ancestor) || endContainer;

			// Walk left leaf
			walkBoundary(startContainer, startPoint, true);

			// Walk the middle from start to end point
			siblings = collectSiblings(
				startPoint == startContainer ? startPoint : startPoint.nextSibling,
				'nextSibling',
				endPoint == endContainer ? endPoint.nextSibling : endPoint
			);

			if (siblings.length)
				callback(siblings);

			// Walk right leaf
			walkBoundary(endContainer, endPoint);
		};

		/**
		 * Splits the specified range at it's start/end points.
		 *
		 * @param {Range/RangeObject} rng Range to split.
		 * @return {Object} Range position object.
		 */
/*		this.split = function(rng) {
			var startContainer = rng.startContainer,
				startOffset = rng.startOffset,
				endContainer = rng.endContainer,
				endOffset = rng.endOffset;

			function splitText(node, offset) {
				if (offset == node.nodeValue.length)
					node.appendData(INVISIBLE_CHAR);

				node = node.splitText(offset);

				if (node.nodeValue === INVISIBLE_CHAR)
					node.nodeValue = '';

				return node;
			};

			// Handle single text node
			if (startContainer == endContainer) {
				if (startContainer.nodeType == 3) {
					if (startOffset != 0)
						startContainer = endContainer = splitText(startContainer, startOffset);

					if (endOffset - startOffset != startContainer.nodeValue.length)
						splitText(startContainer, endOffset - startOffset);
				}
			} else {
				// Split startContainer text node if needed
				if (startContainer.nodeType == 3 && startOffset != 0) {
					startContainer = splitText(startContainer, startOffset);
					startOffset = 0;
				}

				// Split endContainer text node if needed
				if (endContainer.nodeType == 3 && endOffset != endContainer.nodeValue.length) {
					endContainer = splitText(endContainer, endOffset).previousSibling;
					endOffset = endContainer.nodeValue.length;
				}
			}

			return {
				startContainer : startContainer,
				startOffset : startOffset,
				endContainer : endContainer,
				endOffset : endOffset
			};
		};
*/
	};

	/**
	 * Compares two ranges and checks if they are equal.
	 *
	 * @static
	 * @param {DOMRange} rng1 First range to compare.
	 * @param {DOMRange} rng2 First range to compare.
	 * @return {Boolean} true/false if the ranges are equal.
	 */
	tinymce.dom.RangeUtils.compareRanges = function(rng1, rng2) {
		if (rng1 && rng2) {
			// Compare native IE ranges
			if (rng1.item || rng1.duplicate) {
				// Both are control ranges and the selected element matches
				if (rng1.item && rng2.item && rng1.item(0) === rng2.item(0))
					return true;

				// Both are text ranges and the range matches
				if (rng1.isEqual && rng2.isEqual && rng2.isEqual(rng1))
					return true;
			} else {
				// Compare w3c ranges
				return rng1.startContainer == rng2.startContainer && rng1.startOffset == rng2.startOffset;
			}
		}

		return false;
	};
})(tinymce);
<commit_msg>Reintroduced split method to RangeUtils.js.<commit_after>/**
 * Range.js
 *
 * Copyright 2009, Moxiecode Systems AB
 * Released under LGPL License.
 *
 * License: http://tinymce.moxiecode.com/license
 * Contributing: http://tinymce.moxiecode.com/contributing
 */

(function(tinymce) {
	tinymce.dom.RangeUtils = function(dom) {
		var INVISIBLE_CHAR = '\uFEFF';

		/**
		 * Walks the specified range like object and executes the callback for each sibling collection it finds.
		 *
		 * @param {Object} rng Range like object.
		 * @param {function} callback Callback function to execute for each sibling collection.
		 */
		this.walk = function(rng, callback) {
			var startContainer = rng.startContainer,
				startOffset = rng.startOffset,
				endContainer = rng.endContainer,
				endOffset = rng.endOffset,
				ancestor, startPoint,
				endPoint, node, parent, siblings, nodes;

			// Handle table cell selection the table plugin enables
			// you to fake select table cells and perform formatting actions on them
			nodes = dom.select('td.mceSelected,th.mceSelected');
			if (nodes.length > 0) {
				tinymce.each(nodes, function(node) {
					callback([node]);
				});

				return;
			}

			/**
			 * Collects siblings
			 *
			 * @private
			 * @param {Node} node Node to collect siblings from.
			 * @param {String} name Name of the sibling to check for.
			 * @return {Array} Array of collected siblings.
			 */
			function collectSiblings(node, name, end_node) {
				var siblings = [];

				for (; node && node != end_node; node = node[name])
					siblings.push(node);

				return siblings;
			};

			/**
			 * Find an end point this is the node just before the common ancestor root.
			 *
			 * @private
			 * @param {Node} node Node to start at.
			 * @param {Node} root Root/ancestor element to stop just before.
			 * @return {Node} Node just before the root element.
			 */
			function findEndPoint(node, root) {
				do {
					if (node.parentNode == root)
						return node;

					node = node.parentNode;
				} while(node);
			};

			function walkBoundary(start_node, end_node, next) {
				var siblingName = next ? 'nextSibling' : 'previousSibling';

				for (node = start_node, parent = node.parentNode; node && node != end_node; node = parent) {
					parent = node.parentNode;
					siblings = collectSiblings(node == start_node ? node : node[siblingName], siblingName);

					if (siblings.length) {
						if (!next)
							siblings.reverse();

						callback(siblings);
					}
				}
			};

			// If index based start position then resolve it
			if (startContainer.nodeType == 1 && startContainer.hasChildNodes())
				startContainer = startContainer.childNodes[startOffset];

			// If index based end position then resolve it
			if (endContainer.nodeType == 1 && endContainer.hasChildNodes())
				endContainer = endContainer.childNodes[Math.min(endOffset - 1, endContainer.childNodes.length - 1)];

			// Find common ancestor and end points
			ancestor = dom.findCommonAncestor(startContainer, endContainer);

			// Same container
			if (startContainer == endContainer)
				return callback([startContainer]);

			// Process left side
			for (node = startContainer; node; node = node.parentNode) {
				if (node == endContainer)
					return walkBoundary(startContainer, ancestor, true);

				if (node == ancestor)
					break;
			}

			// Process right side
			for (node = endContainer; node; node = node.parentNode) {
				if (node == startContainer)
					return walkBoundary(endContainer, ancestor);

				if (node == ancestor)
					break;
			}

			// Find start/end point
			startPoint = findEndPoint(startContainer, ancestor) || startContainer;
			endPoint = findEndPoint(endContainer, ancestor) || endContainer;

			// Walk left leaf
			walkBoundary(startContainer, startPoint, true);

			// Walk the middle from start to end point
			siblings = collectSiblings(
				startPoint == startContainer ? startPoint : startPoint.nextSibling,
				'nextSibling',
				endPoint == endContainer ? endPoint.nextSibling : endPoint
			);

			if (siblings.length)
				callback(siblings);

			// Walk right leaf
			walkBoundary(endContainer, endPoint);
		};

		/**
		 * Splits the specified range at it's start/end points.
		 *
		 * @param {Range/RangeObject} rng Range to split.
		 * @return {Object} Range position object.
		 */
		this.split = function(rng) {
			var startContainer = rng.startContainer,
				startOffset = rng.startOffset,
				endContainer = rng.endContainer,
				endOffset = rng.endOffset;

			function splitText(node, offset) {
				return node.splitText(offset);
			};

			// Handle single text node
			if (startContainer == endContainer && startContainer.nodeType == 3) {
				if (startOffset > 0) {
					endContainer = splitText(startContainer, startOffset);
					startContainer = endContainer.previousSibling;
				}

				if (endOffset > startOffset) {
					endOffset = endOffset - startOffset;
					startContainer = endContainer = splitText(endContainer, endOffset).previousSibling;
					endOffset = endContainer.nodeValue.length;
					startOffset = 0;
				} else {
					endOffset = 0;
				}
			} else {
				// Split startContainer text node if needed
				if (startContainer.nodeType == 3 && startOffset > 0) {
					startContainer = splitText(startContainer, startOffset);
					startOffset = 0;
				}

				// Split endContainer text node if needed
				if (endContainer.nodeType == 3 && endOffset < endContainer.nodeValue.length) {
					endContainer = splitText(endContainer, endOffset).previousSibling;
					endOffset = 0;
				}
			}

			return {
				startContainer : startContainer,
				startOffset : startOffset,
				endContainer : endContainer,
				endOffset : endOffset
			};
		};

	};

	/**
	 * Compares two ranges and checks if they are equal.
	 *
	 * @static
	 * @param {DOMRange} rng1 First range to compare.
	 * @param {DOMRange} rng2 First range to compare.
	 * @return {Boolean} true/false if the ranges are equal.
	 */
	tinymce.dom.RangeUtils.compareRanges = function(rng1, rng2) {
		if (rng1 && rng2) {
			// Compare native IE ranges
			if (rng1.item || rng1.duplicate) {
				// Both are control ranges and the selected element matches
				if (rng1.item && rng2.item && rng1.item(0) === rng2.item(0))
					return true;

				// Both are text ranges and the range matches
				if (rng1.isEqual && rng2.isEqual && rng2.isEqual(rng1))
					return true;
			} else {
				// Compare w3c ranges
				return rng1.startContainer == rng2.startContainer && rng1.startOffset == rng2.startOffset;
			}
		}

		return false;
	};
})(tinymce);
<|endoftext|>


<commit_before>import React from 'react';
import assert from 'assert';
import { shallow } from 'enzyme';
import CustomiseProfile from './profile';

const resources = {
  avatar: {
    src: '//zooniverse.org/images/avatar.jpg',
    delete() {}
  },
  profile_header: {
    src: '//zooniverse.org/images/header.jpg',
    delete() {}
  }
};

const user = {
  get(type) {
    return Promise.resolve([resources[type]]);
  }
};

describe('CustomiseProfile', () => {
  let wrapper;

  before(() => {
    wrapper = shallow(<CustomiseProfile user={user} />);
  });

  beforeEach(() => wrapper.update());

  it('renders the user avatar', () => {
    const avatar = wrapper.find('ImageSelector[src="//zooniverse.org/images/avatar.jpg"]');
    assert.equal(avatar.length, 1);
  });

  it('renders the user background', () => {
    const avatar = wrapper.find('ImageSelector[src="//zooniverse.org/images/header.jpg"]');
    assert.equal(avatar.length, 1);
  });

  it('deletes the avatar when Clear Avatar is pressed', () => {
    wrapper.find('button').first().simulate('click');
    setTimeout(() => assert.equal(wrapper.update().state().avatar, {}));
  });

  it('deletes the profile header when Clear Header is pressed', () => {
    wrapper.find('button').last().simulate('click');
    setTimeout(() => assert.equal(wrapper.update().state().profile_header, {}));
  });
});
<commit_msg>Fix evergreen user profile tests Add sinon. Test that the clear media buttons call the clear handler with the correct arguments.<commit_after>import React from 'react';
import assert from 'assert';
import sinon from 'sinon';
import { shallow } from 'enzyme';
import CustomiseProfile from './profile';

const resources = {
  avatar: {
    src: '//zooniverse.org/images/avatar.jpg',
    delete() {}
  },
  profile_header: {
    src: '//zooniverse.org/images/header.jpg',
    delete() {}
  }
};

const user = {
  get(type) {
    return Promise.resolve([resources[type]]);
  }
};

describe('CustomiseProfile', () => {
  let wrapper;
  let clearMediaSpy;

  before(() => {
    wrapper = shallow(<CustomiseProfile user={user} />);
    clearMediaSpy = sinon.spy(CustomiseProfile.prototype, 'handleMediaClear');
  });

  beforeEach(() => {
    wrapper.update();
    clearMediaSpy.reset();
  });

  it('renders the user avatar', () => {
    const avatar = wrapper.find('ImageSelector[src="//zooniverse.org/images/avatar.jpg"]');
    assert.equal(avatar.length, 1);
  });

  it('renders the user background', () => {
    const avatar = wrapper.find('ImageSelector[src="//zooniverse.org/images/header.jpg"]');
    assert.equal(avatar.length, 1);
  });

  it('deletes the avatar when Clear Avatar is pressed', () => {
    wrapper.find('button').first().simulate('click');
    sinon.assert.calledOnce(clearMediaSpy);
    sinon.assert.calledWith(clearMediaSpy, 'avatar');
  });

  it('deletes the profile header when Clear Header is pressed', () => {
    wrapper.find('button').last().simulate('click');
    sinon.assert.calledOnce(clearMediaSpy);
    sinon.assert.calledWith(clearMediaSpy, 'profile_header');
  });
});
<|endoftext|>


<commit_before>import {stream, merge$, isStream} from './streamy';
import {createElement, REMOVED, ADDED} from './streamy-dom';

/*
* wrap hyperscript elements in reactive streams dependent on their children streams
*/
export const h = (tag, props, ...children) => {
	let deleted$ = stream(false);
	let component;
	let version = -1;

	// let childrenWithDetacher = addStreamDetacher(flatten(children), deleted$);
	let mergedChildren$ = mergeChildren$(flatten(children));
	// jsx usually resolves known tags as strings and unknown tags as functions
	// if it is a sub component, resolve that component
	if (typeof tag === 'function') {
		component = tag(
			props,
			mergedChildren$,
			deleted$
		);
	} else {
		// add detachers to props
		props !== null && Object.keys(props).map((propName, index) => {
			if (isStream(props[propName])) {
				props[propName] = props[propName].until(deleted$);
			}
		});
		let state = {
			tag: '',
			props: {},
			children: [],
			version
		}
		component = {
			vdom$: merge$([
					wrapProps$(props, deleted$).distinct(),
					mergedChildren$.map(flatten)
				]).map(([props, children]) => {
					return {
						tag,
						props,
						children,
						version: ++version
				}})
		};
	}

	return component;
};

function addStreamDetacher(obj, deleted$) {
	if (obj === null || obj === undefined) return obj;
	if (Array.isArray(obj)) {
		return obj.map(item => {
			if (isStream(item)) {
				return item.until(deleted$);
			}
			return item;
		});
	}
	Object.keys(obj).map((propName, index) => {
		if (isStream(obj[propName])) {
			obj[propName] = obj[propName].until(deleted$);
		}
	});
	return obj;
}

// input has format [stream | {vdom$}]
function mergeChildren$(children) {
	if (!Array.isArray(children)) {
		children = [children];
	}
	children = flatten(children);
	let childrenVdom$arr = children.map(child => {
		if (isStream(child)) {
			return child
			.flatMap(mergeChildren$);
		}
		return child.vdom$ || child;
	})

	return mixedMerge$(childrenVdom$arr);
}

/*
* wrap all children in streams and merge those
* we make sure that all children streams are flat arrays to make processing uniform
* output: stream([stream([])])
*/
function getChildrenVdom$arr(childrenArr, deleted$) {
	// flatten children arr
	// needed to make react style hyperscript (children as arguments) working parallel to preact style hyperscript (children as array)
	childrenArr = [].concat(...childrenArr);
	// only handle vdom for now
	let children$Arr = childrenArr.map(component => {
		// TODO
		// if (component.IS_STREAM) {
		// 	return
		// }
		// if there is no vdom$ it is a string or number
		if (component.vdom$ === undefined) {
			return stream(component);
		}
		return component.vdom$
	});

	return children$Arr
		// unsubscribe on the child when deleted
		.map(vdom$ => vdom$.until(deleted$))
		// make sure children are arrays and not nest
		.map(_ => makeArray(_)
			.map(flatten))
		// so we can easily merge them
		.map(vdom$ => vdom$.flatMap(vdomArr =>
				mixedMerge$(vdomArr)));
}

// make sure all children are handled as streams
// so we can later easily merge them
function makeStreams(childrenArr) {
	return childrenArr.map(child => {
		if (child === null || !isStream(child)) {
			return stream(child);
		}
		return child;
	});
}

// converts an input into an array
function makeArray(stream) {
	return stream.map(value => {
		if (value == null) {
			return [];
		}
		if (!Array.isArray(value)) {
			return [value];
		}
		return value;
	})
}

// flattens an array
export function flatten(arr) {
	while (arr.some(value => Array.isArray(value))) {
		arr = [].concat(...arr);
	}
	return arr;
}

/*
* Wrap props into one stream
*/
function wrapProps$(props, deleted$) {
	if (props === null) return stream({});
	if (isStream(props)) {
		return props.until(deleted$);
	}

	let nestedStreams = extractNestedStreams(props);
	let updateStreams = nestedStreams.map(({parent, key, stream}) =>
		stream
		.until(deleted$)
		.map(value => parent[key] = value)
	);
	return merge$(updateStreams).map(_ => props);
}

export function mixedMerge$(potentialStreamsArr) {
	let values = potentialStreamsArr.map(parent$ => parent$.IS_STREAM ? parent$.value : parent$);
	let actualStreams = potentialStreamsArr.reduce((streams, potentialStream, index) => {
		if (potentialStream.IS_STREAM) {
			streams.push({
				stream: potentialStream,
				index
			})
		}
		return streams;
	}, []);
	let newStream = stream(values.indexOf(undefined) === -1 ? values : undefined);
	actualStreams.forEach(function triggerMergedStreamUpdate({stream, index}) {
		stream.listeners.push(function updateMergedStream(value) {
			values[index] = value;
			newStream(values.indexOf(undefined) === -1 ? values : undefined);
		});
	});
	return newStream;
}

function extractNestedStreams(obj) {
	return flatten(Object.keys(obj).map(key => {
		if (typeof obj[key] === 'object') {
			return extractNestedStreams(obj[key]);
		}
		if (isStream(obj[key])) {
			return [{
				parent: obj,
				key,
				stream: obj[key]
			}];
		}
		return [];
	}))
}<commit_msg>added comments<commit_after>import {stream, merge$, isStream} from './streamy';
import {createElement, REMOVED, ADDED} from './streamy-dom';

/*
* wrap hyperscript elements in reactive streams dependent on their children streams
*/
export const h = (tag, props, ...children) => {
	let deleted$ = stream(false);
	let component;
	let version = -1;

	// let childrenWithDetacher = addStreamDetacher(flatten(children), deleted$);
	let mergedChildren$ = mergeChildren$(flatten(children));
	// jsx usually resolves known tags as strings and unknown tags as functions
	// if it is a sub component, resolve that component
	if (typeof tag === 'function') {
		component = tag(
			props,
			mergedChildren$,
			deleted$
		);
	} else {
		// add detachers to props
		props !== null && Object.keys(props).map((propName, index) => {
			if (isStream(props[propName])) {
				props[propName] = props[propName].until(deleted$);
			}
		});
		let state = {
			tag: '',
			props: {},
			children: [],
			version
		}
		component = {
			vdom$: merge$([
					wrapProps$(props, deleted$).distinct(),
					mergedChildren$.map(flatten)
				]).map(([props, children]) => {
					return {
						tag,
						props,
						children,
						version: ++version
				}})
		};
	}

	return component;
};

function addStreamDetacher(obj, deleted$) {
	if (obj === null || obj === undefined) return obj;
	if (Array.isArray(obj)) {
		return obj.map(item => {
			if (isStream(item)) {
				return item.until(deleted$);
			}
			return item;
		});
	}
	Object.keys(obj).map((propName, index) => {
		if (isStream(obj[propName])) {
			obj[propName] = obj[propName].until(deleted$);
		}
	});
	return obj;
}

// input has format [stream | {vdom$}]
function mergeChildren$(children) {
	if (!Array.isArray(children)) {
		children = [children];
	}
	children = flatten(children);
	let childrenVdom$arr = children.map(child => {
		if (isStream(child)) {
			return child
			.flatMap(mergeChildren$);
		}
		return child.vdom$ || child;
	})

	return mixedMerge$(childrenVdom$arr);
}

/*
* wrap all children in streams and merge those
* we make sure that all children streams are flat arrays to make processing uniform
* output: stream([stream([])])
*/
function getChildrenVdom$arr(childrenArr, deleted$) {
	// flatten children arr
	// needed to make react style hyperscript (children as arguments) working parallel to preact style hyperscript (children as array)
	childrenArr = [].concat(...childrenArr);
	// only handle vdom for now
	let children$Arr = childrenArr.map(component => {
		// TODO
		// if (component.IS_STREAM) {
		// 	return
		// }
		// if there is no vdom$ it is a string or number
		if (component.vdom$ === undefined) {
			return stream(component);
		}
		return component.vdom$
	});

	return children$Arr
		// unsubscribe on the child when deleted
		.map(vdom$ => vdom$.until(deleted$))
		// make sure children are arrays and not nest
		.map(_ => makeArray(_)
			.map(flatten))
		// so we can easily merge them
		.map(vdom$ => vdom$.flatMap(vdomArr =>
				mixedMerge$(vdomArr)));
}

// make sure all children are handled as streams
// so we can later easily merge them
function makeStreams(childrenArr) {
	return childrenArr.map(child => {
		if (child === null || !isStream(child)) {
			return stream(child);
		}
		return child;
	});
}

// converts an input into an array
function makeArray(stream) {
	return stream.map(value => {
		if (value == null) {
			return [];
		}
		if (!Array.isArray(value)) {
			return [value];
		}
		return value;
	})
}

// flattens an array
export function flatten(arr) {
	while (arr.some(value => Array.isArray(value))) {
		arr = [].concat(...arr);
	}
	return arr;
}

/*
* Wrap props into one stream
*/
function wrapProps$(props, deleted$) {
	if (props === null) return stream({});
	if (isStream(props)) {
		return props.until(deleted$);
	}

	let nestedStreams = extractNestedStreams(props);
	let updateStreams = nestedStreams.map(function makeNestedStreamUpdateProps({parent, key, stream}) {
		return stream
		.until(deleted$)
		.map(value => parent[key] = value)
	});
	return merge$(updateStreams).map(_ => props);
}

export function mixedMerge$(potentialStreamsArr) {
	let values = potentialStreamsArr.map(parent$ => parent$.IS_STREAM ? parent$.value : parent$);
	let actualStreams = potentialStreamsArr.reduce((streams, potentialStream, index) => {
		if (potentialStream.IS_STREAM) {
			streams.push({
				stream: potentialStream,
				index
			})
		}
		return streams;
	}, []);
	let newStream = stream(values.indexOf(undefined) === -1 ? values : undefined);
	actualStreams.forEach(function triggerMergedStreamUpdate({stream, index}) {
		stream.listeners.push(function updateMergedStream(value) {
			values[index] = value;
			newStream(values.indexOf(undefined) === -1 ? values : undefined);
		});
	});
	return newStream;
}

// to react to nested streams in an object, we extract the streams and a reference to their position
// returns [{parentObject, propertyName, stream}]
function extractNestedStreams(obj) {
	return flatten(Object.keys(obj).map(key => {
		if (typeof obj[key] === 'object') {
			return extractNestedStreams(obj[key]);
		}
		if (isStream(obj[key])) {
			return [{
				parent: obj,
				key,
				stream: obj[key]
			}];
		}
		return [];
	}))
}<|endoftext|>


<commit_before>/**
 * Validate if a property is a valid CSS one.
 *
 * @param {string} prop
 * @return {boolean} Whether or not the property is valid (true = valid)
 */

const RE_VALID_CSS_PROPERTY = /^[a-z-]+$/

export default function (prop) {
  return RE_VALID_CSS_PROPERTY.test(prop)
}
<commit_msg>Validate CSS props by checking if its not a SCSS/LESS variable<commit_after>/**
 * Validate if a property is a valid CSS one.
 *
 * @param {string} prop
 * @return {boolean} Whether or not the property is valid (true = valid)
 */

export default function (prop) {
  // The validation is done by checking if the property
  // is not a SCSS/LESS variable
  return prop[0] !== "$" && prop[0] !== "@"
}
<|endoftext|>


<commit_before>/* global angular Firebase */
(function() {
  'use strict';
  angular.module('beautyMark')
    .controller('AddNailsController', function($http, FIREBASE_URL) {
      var ref = new Firebase(FIREBASE_URL);
      var user = ref.getAuth();
      $http.get(FIREBASE_URL + user.uid + '/nails.json')
      });
})();
<commit_msg>working with scope and firebaseArray to add nails<commit_after>/* global angular Firebase */
(function() {
  'use strict';
  angular.module('beautyMark')
    .controller('AddNailsController', function($scope, $firebaseArray, FIREBASE_URL) {
      var ref = new Firebase(FIREBASE_URL);
      $scope.nails = $firebaseArray(ref);
      $scope.submitNail = function() {
        $scope.nails.$add({
          Brand: $scope.newNailsBrand,
          Name: $scope.newNailsName,
          Family: $scope.newNailsCFamily,
          Tone: $scope.newNailsCTone,
          Finish: $scope.newNailsCFinish,
          Rating: $scope.newNailsRating
        });
      }
      // var user = ref.getAuth();
      // $http.get(FIREBASE_URL + user.uid + '/nails.json')
      });
})();
<|endoftext|>


<commit_before>/**
 * RankingOrderController
 *
 * @return RankingOrderController
 * @author Erik E. Lorenz <erik.e.lorenz@gmail.com>
 * @license MIT License
 * @see LICENSE
 */
define(['lib/extend', 'core/controller', 'core/type'], function(extend,
    Controller, Type) {
  /**
   * Constructor
   *
   * @param view
   *          a valid RankingOrderView instance
   */
  function RankingOrderController(view) {
    var controller;

    RankingOrderController.superconstructor.call(this, view);

    controller = this;

    this.view.$view.find("button.move-left").click(function() {
      controller.moveleft();
    });

    this.view.$view.find("button.move-right").click(function() {
      controller.moveright();
    });

    this.view.$view.find("button.move-down").click(function() {
      controller.movedown();
    });

    this.view.$view.find("button.move-up").click(function() {
      controller.moveup();
    });
  }
  extend(RankingOrderController, Controller);

  RankingOrderController.prototype.getSelectedValues = function() {
    var value = this.view.$selectedList.val();

    if (value === null) {
      return [];
    }

    if (Type.isArray(value)) {
      return value;
    }
    return [value];
  };

  RankingOrderController.prototype.getSelectedIndex = function() {
    return this.view.$selectedList[0].selectedIndex;
  };

  RankingOrderController.prototype.resetAvailableSelection = function(value) {
    if (value) {
      this.view.$availableList.val(value);
    } else {
      this.view.$availableList[0].selectedIndex = -1;
    }
  };

  RankingOrderController.prototype.setSelectedIndex = function(index) {
    this.view.$selectedList[0].selectedIndex = index;
  };

  RankingOrderController.prototype.getAvailableValues = function() {
    var value = this.view.$availableList.val();

    if (value === null) {
      return [];
    }

    if (Type.isArray(value)) {
      return value;
    }
    return [value];
  };

  RankingOrderController.prototype.moveleft = function() {
    this.getAvailableValues().forEach(function(availableComponent) {
      this.model.push(availableComponent);
      this.resetAvailableSelection();
    }, this);
  };

  RankingOrderController.prototype.moveright = function() {
    this.getSelectedValues().forEach(function(selectedComponent) {
      this.model.erase(selectedComponent);
      this.resetAvailableSelection(selectedComponent);
    }, this);
  };

  RankingOrderController.prototype.moveup = function() {
    var index, value;

    index = this.getSelectedIndex();
    if (index === -1 || index === 0) {
      return;
    }

    value = this.model.get(index);

    this.model.remove(index);
    this.model.insert(index - 1, value);
    this.setSelectedIndex(index - 1);
  };

  RankingOrderController.prototype.movedown = function() {
    var index, value;

    index = this.getSelectedIndex();
    if (index === -1 || index === this.model.length - 1) {
      return;
    }

    value = this.model.get(index);

    this.model.remove(index);
    this.model.insert(index + 1, value);
    this.setSelectedIndex(index + 1);
  };

  return RankingOrderController;
});
<commit_msg>RankingOrderController: Enter and Delete keys work<commit_after>/**
 * RankingOrderController
 *
 * @return RankingOrderController
 * @author Erik E. Lorenz <erik.e.lorenz@gmail.com>
 * @license MIT License
 * @see LICENSE
 */
define(['lib/extend', 'core/controller', 'core/type'], function(extend,
    Controller, Type) {
  /**
   * Constructor
   *
   * @param view
   *          a valid RankingOrderView instance
   */
  function RankingOrderController(view) {
    var controller;

    RankingOrderController.superconstructor.call(this, view);

    controller = this;

    this.view.$view.find("button.move-left").click(function() {
      controller.moveleft();
    });

    this.view.$view.find("button.move-right").click(function() {
      controller.moveright();
    });

    this.view.$view.find("button.move-down").click(function() {
      controller.movedown();
    });

    this.view.$view.find("button.move-up").click(function() {
      controller.moveup();
    });

    this.view.$selectedList.keyup(function(e) {
      if (e.keyCode === 46 || e.keyCode === 8 || e.keyCode === 127) {
        controller.moveright();
        controller.setSelectedIndex(0);
      }
    });

    this.view.$availableList.keyup(function(e) {
      var value;
      if (e.keyCode === 13) {
        value = controller.getAvailableValues();
        controller.moveleft();
        controller.resetAvailableSelection(value[0]);
      }
    });
  }
  extend(RankingOrderController, Controller);

  RankingOrderController.prototype.getSelectedValues = function() {
    var value = this.view.$selectedList.val();

    if (value === null) {
      return [];
    }

    if (Type.isArray(value)) {
      return value;
    }
    return [value];
  };

  RankingOrderController.prototype.getSelectedIndex = function() {
    return this.view.$selectedList[0].selectedIndex;
  };

  RankingOrderController.prototype.resetAvailableSelection = function(value) {
    if (value) {
      this.view.$availableList.val(value);
    } else {
      this.view.$availableList[0].selectedIndex = -1;
    }
  };

  RankingOrderController.prototype.setSelectedIndex = function(index) {
    this.view.$selectedList[0].selectedIndex = index;
  };

  RankingOrderController.prototype.getAvailableValues = function() {
    var value = this.view.$availableList.val();

    if (value === null) {
      return [];
    }

    if (Type.isArray(value)) {
      return value;
    }
    return [value];
  };

  RankingOrderController.prototype.moveleft = function() {
    this.getAvailableValues().forEach(function(availableComponent) {
      this.model.push(availableComponent);
      this.resetAvailableSelection();
    }, this);
  };

  RankingOrderController.prototype.moveright = function() {
    this.getSelectedValues().forEach(function(selectedComponent) {
      this.model.erase(selectedComponent);
      this.resetAvailableSelection(selectedComponent);
    }, this);
  };

  RankingOrderController.prototype.moveup = function() {
    var index, value;

    index = this.getSelectedIndex();
    if (index === -1 || index === 0) {
      return;
    }

    value = this.model.get(index);

    this.model.remove(index);
    this.model.insert(index - 1, value);
    this.setSelectedIndex(index - 1);
  };

  RankingOrderController.prototype.movedown = function() {
    var index, value;

    index = this.getSelectedIndex();
    if (index === -1 || index === this.model.length - 1) {
      return;
    }

    value = this.model.get(index);

    this.model.remove(index);
    this.model.insert(index + 1, value);
    this.setSelectedIndex(index + 1);
  };

  return RankingOrderController;
});
<|endoftext|>


<commit_before>
var assert = require('assert'),
	GetResponse = require('../lib/GetResponse');

module.exports = function(serverOptions, _getFile) {

	var pathExpGetResponse = './test/expected/get-response';

	// GET call
	it('response from GET /product/{productCode}', function() {
		var response,
			data,
			expected;

		response = new GetResponse({
			path: serverOptions.restPath + '/products/#{productCode}',
			method: 'get',
			expected: 'success'
		}, serverOptions);
		expected = _getFile(pathExpGetResponse + '/01.json');
		data = response.get();
		assert.equal(JSON.stringify(data), expected);
	});

	// POST call
	it('response from POST /product/{productCode}', function() {
		var response,
			data,
			expected;

		response = new GetResponse({
			path: serverOptions.restPath + '/products/#{productCode}',
			method: 'post',
			expected: 'success'
		}, serverOptions);
		expected = _getFile(pathExpGetResponse + '/02.json');
		data = response.get();
		assert.equal(JSON.stringify(data), expected);
	});

	// FAKER call
	it('response from GET /product/{productCode} - with faker', function() {
		var response,
			data;

		response = new GetResponse({
			path: serverOptions.restPath + '/products/#{productCode}',
			method: 'get',
			expected: 'faker'
		}, serverOptions);
		data = response.get();

		assert.equal(typeof data.price, 'object');
		assert.equal(typeof data.card, 'object');
		assert.equal(typeof data.email, 'string');
	});

	// FUNCTIONS call
	it('response from GET /product/{productCode} - with functions', function() {
		var response,
			data;

		response = new GetResponse({
			path: serverOptions.restPath + '/products/#{productCode}',
			method: 'get',
			expected: 'func'
		}, serverOptions);
		data = response.get();

		assert.equal(typeof data.image, 'object');
		assert.equal(typeof data.image.url, 'string');
		assert.equal(typeof data.image.alt, 'string');
	});

	// REQUEST DATA call
	it('response from GET /product/{productCode} - with request data', function() {
		var response,
			data;

		response = new GetResponse({
			path: serverOptions.restPath + '/products/#{productCode}',
			method: 'get',
			expected: 'request-data'
		}, serverOptions);
		data = response.get();

		assert.equal(data.currentPage, 3);
	});

};<commit_msg>[test] #9: add test for dynamic path in ejs object<commit_after>
var assert = require('assert'),
	GetResponse = require('../lib/GetResponse');

module.exports = function(serverOptions, _getFile) {

	var pathExpGetResponse = './test/expected/get-response';

	// GET call
	it('response from GET /product/{productCode}', function() {
		var response,
			data,
			expected;

		response = new GetResponse({
			path: serverOptions.restPath + '/products/#{productCode}',
			method: 'get',
			expected: 'success'
		}, serverOptions);
		expected = _getFile(pathExpGetResponse + '/01.json');
		data = response.get();
		assert.equal(JSON.stringify(data), expected);
	});

	// POST call
	it('response from POST /product/{productCode}', function() {
		var response,
			data,
			expected;

		response = new GetResponse({
			path: serverOptions.restPath + '/products/#{productCode}',
			method: 'post',
			expected: 'success'
		}, serverOptions);
		expected = _getFile(pathExpGetResponse + '/02.json');
		data = response.get();
		assert.equal(JSON.stringify(data), expected);
	});

	// FAKER call
	it('response from GET /product/{productCode} - with faker', function() {
		var response,
			data;

		response = new GetResponse({
			path: serverOptions.restPath + '/products/#{productCode}',
			method: 'get',
			expected: 'faker'
		}, serverOptions);
		data = response.get();

		assert.equal(typeof data.price, 'object');
		assert.equal(typeof data.card, 'object');
		assert.equal(typeof data.email, 'string');
	});

	// FUNCTIONS call
	it('response from GET /product/{productCode} - with functions', function() {
		var response,
			data;

		response = new GetResponse({
			path: serverOptions.restPath + '/products/#{productCode}',
			method: 'get',
			expected: 'func'
		}, serverOptions);
		data = response.get();

		assert.equal(typeof data.image, 'object');
		assert.equal(typeof data.image.url, 'string');
		assert.equal(typeof data.image.alt, 'string');
	});

	// REQUEST DATA call
	it('response from GET /product/{productCode} - with request data', function() {
		var response,
			data;

		response = new GetResponse({
			path: serverOptions.restPath + '/products/#{productCode}',
			method: 'get',
			expected: 'request-data'
		}, serverOptions);
		data = response.get();

		assert.equal(data.currentPage, 3);
	});

	// REQUEST DATA call
	it('response from GET /product/{productCode} - with request data from path', function() {
		var response,
			data;

		response = new GetResponse({
			path: serverOptions.restPath + '/products/test',
			method: 'get',
			expected: 'request-data',
			queryParams: {
				currentPage: 12
			}
		}, serverOptions);
		data = response.get();

		assert.equal(data.productCode, 'test');
	});

};<|endoftext|>


<commit_before>'use strict';

angular.module('wbwcpNgApp')
  .controller('MatchesCtrl', function ($scope, $http, User, Auth, $filter) {
    $scope.errors = {};

    // Set up data for the /matches page
    $scope.activeTab = 'group';

    // get all matches from the back-end
    $http.get('/api/matches').success(function(matches) {
      $scope.firstround = matches.slice(0, 48);
      $scope.finals = matches.slice(48);
    });

    // get all users from the back-end
    $http.get('/api/users').success(function(users) {
      $scope.users = users;
    });

    // get all teams
    $http.get('/api/teams').success(function(teams) {
      $scope.teams = teams;
    });

    // get picks for the currently displayed user
    $scope.currentUser = User.get({}, function() {
      if ($scope.currentUser._id) {
        $http.get('/api/picks/' + $scope.currentUser._id).success(function(picks) {
          // array[pick.match] = pick.choice
          var rePicks = [];
          var rePoints = [];
          for (var pick in picks) {
            rePicks[picks[pick].match] = picks[pick].choice;
            rePoints[picks[pick].match] = picks[pick].points;
          }
          $scope.currentPicks = rePicks;
          $scope.currentPoints = rePoints;
          $scope.pickCount = picks.length;
        });
      }
    });

    $scope.changeUser = function() {
      User.get({ _id: $scope.currentUser._id }, function() {
        if ($scope.currentUser._id) {
          $http.get('/api/picks/' + $scope.currentUser._id).success(function(picks) {
            // array[pick.match] = pick.choice
            var rePicks = [];
            var rePoints = [];
            for (var pick in picks) {
              rePicks[picks[pick].match] = picks[pick].choice;
              rePoints[picks[pick].match] = picks[pick].points;
            }
            // send picks to the front-end
            $scope.currentPicks = rePicks;
            $scope.currentPoints = rePoints;
            $scope.pickCount = picks.length;
          });
        }
      });
    };

    $scope.savePick = function(userId, matchId, choice) {
      $scope.submitted = true;
      // PUT to /api/picks/userId
      $http.put('/api/picks/' + userId, { user: userId, match: matchId, choice: choice });
      // update $scope.currentPicks
      $http.get('/api/picks/' + $scope.currentUser._id).success(function(picks) {
        // array[pick.match] = pick.choice
        var rePicks = [];
        for (var pick in picks) {
          rePicks[picks[pick].match] = picks[pick].choice;
        }
        // send picks to the front-end
        $scope.currentPicks = rePicks;
        $scope.pickCount = picks.length;

        // find the new Team data to shove into $scope.finals
        var newTeam = $filter('filter')($scope.teams, {code: choice}, true);
        //console.log(newTeam[0]);
        // based on match._id, update $scope.finals with new team info above
        var thisMatch = $filter('filter')($scope.finals, {_id: matchId}, true);
        //console.log(thisMatch[0]);
        //console.log($scope.finals);
        switch(thisMatch[0].matchNumber) {
          case 49:
            // update match #57, team1
            $scope.finals[8].team1 = newTeam[0];
            break;
          case 50:
            // update match #57, team2
            $scope.finals[8].team2 = newTeam[0];
            break;
          case 51:
            // update match #59, team1
            $scope.finals[10].team1 = newTeam[0];
            break;
          case 52:
            // update match #59, team2
            $scope.finals[10].team2 = newTeam[0];
            break;
          case 53:
            // update match #58, team1
            $scope.finals[9].team1 = newTeam[0];
            break;
          case 54:
            // update match #58, team2
            $scope.finals[9].team2 = newTeam[0];
            break;
          case 55:
            // update match #60, team1
            $scope.finals[11].team1 = newTeam[0];
            break;
          case 56:
            // update match #60, team2
            $scope.finals[11].team2 = newTeam[0];
            break;
          case 57:
            // update match #61, team1
            $scope.finals[12].team1 = newTeam[0];
            break;
          case 58:
            // update match #61, team2
            $scope.finals[12].team2 = newTeam[0];
            break;
          case 59:
            // update match #62, team1
            $scope.finals[13].team1 = newTeam[0];
            break;
          case 60:
            // update match #62, team2
            $scope.finals[13].team2 = newTeam[0];
            break;
          case 61:
            // update match #64, team1
            $scope.finals[15].team1 = newTeam[0];
            //TODO: put loser into 3rd place game
            break;
          case 62:
            // update match #64, team2
            $scope.finals[15].team2 = newTeam[0];
            //TODO: put loser into 3rd place game
            break;
        }
        //console.log($scope.finals);
      });
    };

    // Determine if a given match should be "enabled" so that users can submit picks.
    $scope.enableKOpicks = function() {
      // Array of KO stage matches to be either enabled or disabled.
      $scope.KOpicksEnabled = [];

      // For the round of 16, we enable if both teams are not the generic 'TBD' placeholder.
      for (var i = 49; i < 57; i++) {
        // @todo: replace finals[i] with the actual match record.
        //$scope.KOpicksEnabled[i] = finals[i].team1.name != 'TBD' && finals[i].team2.name != 'TBD' ? true : false;
      }

      // For all other matches, we enable if the user has picked results for the two matches that feed into this one.
      for (var i = 49; i < 57; i++) {
        // If a choice record exists for this user for match XX and YY...
      }
    };

    // Do some time checks to determine if first/KO round picks can be submitted?
    //@todo: Instead of hard-coding the appropriate times here, we should move them to a config file.
    $scope.beginFirstMatch = 1402603200000;
    $scope.endLastFirstroundMatch = 1403820000000;
    $scope.beginFirstKOroundMatch = 1403971200000;
    $scope.beforeFirstroundCutoff = Date.now() < $scope.beginFirstMatch ? true : false; // Before match 1.
    $scope.afterKOroundOpen = Date.now() > $scope.endLastFirstroundMatch ? true : false; // After match 48 + 2 hours.
    $scope.beforeKOroundCutoff = Date.now() < $scope.beginFirstKOroundMatch ? true : false; // Before match 49.

    // Identify admin users.
    $scope.isAdmin = (Auth.isLoggedIn() && Auth.isAdmin()) ? true : false;
  });
<commit_msg>more KO round picks work<commit_after>'use strict';

angular.module('wbwcpNgApp')
  .controller('MatchesCtrl', function ($scope, $http, User, Auth, $filter) {
    $scope.errors = {};

    // Set up data for the /matches page
    $scope.activeTab = 'group';

    // get all matches from the back-end
    $http.get('/api/matches').success(function(matches) {
      $scope.firstround = matches.slice(0, 48);
      $scope.finals = matches.slice(48);
    });

    // get all users from the back-end
    $http.get('/api/users').success(function(users) {
      $scope.users = users;
    });

    // get all teams
    $http.get('/api/teams').success(function(teams) {
      $scope.teams = teams;
    });

    // get picks for the currently displayed user
    $scope.currentUser = User.get({}, function() {
      if ($scope.currentUser._id) {
        $http.get('/api/picks/' + $scope.currentUser._id).success(function(picks) {
          // array[pick.match] = pick.choice
          var rePicks = [];
          var rePoints = [];
          for (var pick in picks) {
            rePicks[picks[pick].match] = picks[pick].choice;
            rePoints[picks[pick].match] = picks[pick].points;
          }
          $scope.currentPicks = rePicks;
          $scope.currentPoints = rePoints;
          $scope.pickCount = picks.length;
        });
      }
    });

    $scope.changeUser = function() {
      User.get({ _id: $scope.currentUser._id }, function() {
        if ($scope.currentUser._id) {
          $http.get('/api/picks/' + $scope.currentUser._id).success(function(picks) {
            // array[pick.match] = pick.choice
            var rePicks = [];
            var rePoints = [];
            for (var pick in picks) {
              rePicks[picks[pick].match] = picks[pick].choice;
              rePoints[picks[pick].match] = picks[pick].points;
            }
            // send picks to the front-end
            $scope.currentPicks = rePicks;
            $scope.currentPoints = rePoints;
            $scope.pickCount = picks.length;
          });
        }
      });
    };

    $scope.updateKOPick = function(matchNumber, team) {
      switch(matchNumber) {
        case 49:
          // update match #57, team1
          $scope.finals[8].team1 = team;
          break;
        case 50:
          // update match #57, team2
          $scope.finals[8].team2 = team;
          break;
        case 51:
          // update match #59, team1
          $scope.finals[10].team1 = team;
          break;
        case 52:
          // update match #59, team2
          $scope.finals[10].team2 = team;
          break;
        case 53:
          // update match #58, team1
          $scope.finals[9].team1 = team;
          break;
        case 54:
          // update match #58, team2
          $scope.finals[9].team2 = team;
          break;
        case 55:
          // update match #60, team1
          $scope.finals[11].team1 = team;
          break;
        case 56:
          // update match #60, team2
          $scope.finals[11].team2 = team;
          break;
        case 57:
          // update match #61, team1
          $scope.finals[12].team1 = team;
          break;
        case 58:
          // update match #61, team2
          $scope.finals[12].team2 = team;
          break;
        case 59:
          // update match #62, team1
          $scope.finals[13].team1 = team;
          break;
        case 60:
          // update match #62, team2
          $scope.finals[13].team2 = team;
          break;
        case 61:
          // update match #64, team1
          $scope.finals[15].team1 = team;
          // put loser into 3rd place game, match #63
          if (team.code === $scope.finals[12].team1.code) {
            // team 1 selected, put team 2 in 3rd place game
            $scope.finals[14].team1 = $scope.finals[12].team2;
          } else {
            // team 1 selected, put team 2 in 3rd place game
            $scope.finals[14].team1 = $scope.finals[12].team1;
          }
          break;
        case 62:
          // update match #64, team2
          $scope.finals[15].team2 = team;
          // put loser into 3rd place game, match #63
          if (team.code === $scope.finals[13].team1.code) {
            // team 1 selected, put team 2 in 3rd place game
            $scope.finals[14].team2 = $scope.finals[13].team2;
          } else {
            // team 1 selected, put team 2 in 3rd place game
            $scope.finals[14].team2 = $scope.finals[13].team1;
          }
          break;
      }
    };

    $scope.savePick = function(userId, matchId, choice) {
      $scope.submitted = true;
      // PUT to /api/picks/userId
      $http.put('/api/picks/' + userId, { user: userId, match: matchId, choice: choice });
      // update $scope.currentPicks
      $http.get('/api/picks/' + $scope.currentUser._id).success(function(picks) {
        // array[pick.match] = pick.choice
        var rePicks = [];
        for (var pick in picks) {
          rePicks[picks[pick].match] = picks[pick].choice;
        }
        // send picks to the front-end
        $scope.currentPicks = rePicks;
        $scope.pickCount = picks.length;

        // find the new Team data to shove into $scope.finals
        var newTeam = $filter('filter')($scope.teams, {code: choice}, true);
        //console.log(newTeam[0]);
        // based on match._id, update $scope.finals with new team info above
        var thisMatch = $filter('filter')($scope.finals, {_id: matchId}, true);
        //console.log(thisMatch[0]);
        //console.log($scope.finals);
        $scope.updateKOPick(thisMatch[0].matchNumber, newTeam[0]);
        //console.log($scope.finals);
      });
    };

    // Determine if a given match should be "enabled" so that users can submit picks.
    $scope.enableKOpicks = function() {
      // Array of KO stage matches to be either enabled or disabled.
      $scope.KOpicksEnabled = [];

      // For the round of 16, we enable if both teams are not the generic 'TBD' placeholder.
      for (var i = 49; i < 57; i++) {
        // @todo: replace finals[i] with the actual match record.
        //$scope.KOpicksEnabled[i] = finals[i].team1.name != 'TBD' && finals[i].team2.name != 'TBD' ? true : false;
      }

      // For all other matches, we enable if the user has picked results for the two matches that feed into this one.
      for (var i = 49; i < 57; i++) {
        // If a choice record exists for this user for match XX and YY...
      }
    };

    // Do some time checks to determine if first/KO round picks can be submitted?
    //@todo: Instead of hard-coding the appropriate times here, we should move them to a config file.
    $scope.beginFirstMatch = 1402603200000;
    $scope.endLastFirstroundMatch = 1403820000000;
    $scope.beginFirstKOroundMatch = 1403971200000;
    $scope.beforeFirstroundCutoff = Date.now() < $scope.beginFirstMatch ? true : false; // Before match 1.
    $scope.afterKOroundOpen = Date.now() > $scope.endLastFirstroundMatch ? true : false; // After match 48 + 2 hours.
    $scope.beforeKOroundCutoff = Date.now() < $scope.beginFirstKOroundMatch ? true : false; // Before match 49.

    // Identify admin users.
    $scope.isAdmin = (Auth.isLoggedIn() && Auth.isAdmin()) ? true : false;
  });
<|endoftext|>


<commit_before>import Ember from "ember-metal/core"; // Ember.assert, Ember.deprecate
import { get } from "ember-metal/property_get";
import EmberObject from "ember-runtime/system/object";
import { Mixin } from "ember-metal/mixin";
import { computed } from "ember-metal/computed";
import ActionHandler from "ember-runtime/mixins/action_handler";
import ControllerContentModelAliasDeprecation from "ember-runtime/mixins/controller_content_model_alias_deprecation";

/**
  `Ember.ControllerMixin` provides a standard interface for all classes that
  compose Ember's controller layer: `Ember.Controller`,
  `Ember.ArrayController`, and `Ember.ObjectController`.

  @class ControllerMixin
  @namespace Ember
  @uses Ember.ActionHandler
*/
export default Mixin.create(ActionHandler, ControllerContentModelAliasDeprecation, {
  /* ducktype as a controller */
  isController: true,

  /**
    The object to which actions from the view should be sent.

    For example, when a Handlebars template uses the `{{action}}` helper,
    it will attempt to send the action to the view's controller's `target`.

    By default, the value of the target property is set to the router, and
    is injected when a controller is instantiated. This injection is defined
    in Ember.Application#buildContainer, and is applied as part of the
    applications initialization process. It can also be set after a controller
    has been instantiated, for instance when using the render helper in a
    template, or when a controller is used as an `itemController`. In most
    cases the `target` property will automatically be set to the logical
    consumer of actions for the controller.

    @property target
    @default null
  */
  target: null,

  container: null,

  parentController: null,

  store: null,

  model: null,
  content: computed.alias('model')

});

<commit_msg>Add controller model property to documentation.<commit_after>import Ember from "ember-metal/core"; // Ember.assert, Ember.deprecate
import { get } from "ember-metal/property_get";
import EmberObject from "ember-runtime/system/object";
import { Mixin } from "ember-metal/mixin";
import { computed } from "ember-metal/computed";
import ActionHandler from "ember-runtime/mixins/action_handler";
import ControllerContentModelAliasDeprecation from "ember-runtime/mixins/controller_content_model_alias_deprecation";

/**
  `Ember.ControllerMixin` provides a standard interface for all classes that
  compose Ember's controller layer: `Ember.Controller`,
  `Ember.ArrayController`, and `Ember.ObjectController`.

  @class ControllerMixin
  @namespace Ember
  @uses Ember.ActionHandler
*/
export default Mixin.create(ActionHandler, ControllerContentModelAliasDeprecation, {
  /* ducktype as a controller */
  isController: true,

  /**
    The object to which actions from the view should be sent.

    For example, when a Handlebars template uses the `{{action}}` helper,
    it will attempt to send the action to the view's controller's `target`.

    By default, the value of the target property is set to the router, and
    is injected when a controller is instantiated. This injection is defined
    in Ember.Application#buildContainer, and is applied as part of the
    applications initialization process. It can also be set after a controller
    has been instantiated, for instance when using the render helper in a
    template, or when a controller is used as an `itemController`. In most
    cases the `target` property will automatically be set to the logical
    consumer of actions for the controller.

    @property target
    @default null
  */
  target: null,

  container: null,

  parentController: null,

  store: null,

  /**
    The controller's current model. When retrieving or modifying a controller's
    model, this property should be used instead of the `content` property.

    @property model
    @public
   */
  model: null,

  /**
    @private
   */
  content: computed.alias('model')

});

<|endoftext|>


<commit_before>module('Placed Symbol');

test('placedSymbol bounds', function() {
	var path = new Path.Circle([50, 50], 50);
	path.strokeColor = 'black';
	path.strokeWidth = 1;
	path.strokeCap = 'round';
	path.strokeJoin = 'round';
	compareRectangles(path.strokeBounds,
		{ x: -0.5, y: -0.5, width: 101, height: 101 },
		'Path initial bounds.');
	var symbol = new Symbol(path);
	var placedSymbol = new PlacedSymbol(symbol);

	compareRectangles(placedSymbol.bounds,
		new Rectangle(-50.5, -50.5, 101, 101),
		'PlacedSymbol initial bounds.');

	placedSymbol.scale(1, 0.5);
	compareRectangles(placedSymbol.bounds,
		{ x: -50.5, y: -25.25, width: 101, height: 50.5 },
		'Bounds after scale.');

	placedSymbol.rotate(40);
	compareRectangles(placedSymbol.bounds,
		{ x: -42.04736, y: -37.91846, width: 84.09473, height: 75.83691 },
		'Bounds after rotation.');
});
<commit_msg>Add failing Symbol test.<commit_after>module('Placed Symbol');

test('placedSymbol bounds', function() {
	var path = new Path.Circle([50, 50], 50);
	path.strokeColor = 'black';
	path.strokeWidth = 1;
	path.strokeCap = 'round';
	path.strokeJoin = 'round';
	compareRectangles(path.strokeBounds,
		{ x: -0.5, y: -0.5, width: 101, height: 101 },
		'Path initial bounds.');
	var symbol = new Symbol(path);
	var placedSymbol = new PlacedSymbol(symbol);

	compareRectangles(placedSymbol.bounds,
		new Rectangle(-50.5, -50.5, 101, 101),
		'PlacedSymbol initial bounds.');

	placedSymbol.scale(1, 0.5);
	compareRectangles(placedSymbol.bounds,
		{ x: -50.5, y: -25.25, width: 101, height: 50.5 },
		'Bounds after scale.');

	placedSymbol.rotate(40);
	compareRectangles(placedSymbol.bounds,
		{ x: -42.04736, y: -37.91846, width: 84.09473, height: 75.83691 },
		'Bounds after rotation.');
});

test('Symbol definition selection', function() {
	var path = new Path.Circle([50, 50], 50);
	path.selected = true;
	var symbol = new Symbol(path);
	equals(function() {
		return symbol.definition.selected = false;
	}, true);
});<|endoftext|>


<commit_before>var request = require('../requests');

module.exports = function () {
    var self = this,
        makeUrl = function () {
            return 'https://api.bitbucket.org/2.0/repositories/' + (self.configuration.teamname || self.configuration.username) + '/' + self.configuration.slug + '/pipelines/?sort=-created_on&pagelen=1';
        },
        makeBasicAuthToken = function() {
            return Buffer.from(self.configuration.username + ':' + self.configuration.apiKey).toString('base64');
        },
        makeRequest = function (url, callback) {
          request.makeRequest({
            url: url,
            headers: {Authorization: 'Basic ' + makeBasicAuthToken()}
          }, callback);
        },
        parseDate = function (dateAsString) {
            return dateAsString ? new Date(dateAsString) : null;
        },
        forEachResult = function (body, callback) {
            for (var i = 0; i < body.values.length; i++) {
                callback(body.values[i]);
            }
        },
        getStatus = function (statusText, resultText, stageType) {
            if (statusText === "IN_PROGRESS" && stageType === "pipeline_state_in_progress_paused") return "Gray";
            if (statusText === "COMPLETED" && resultText === "SUCCESSFUL") return "Green";
            if (statusText === "COMPLETED" && resultText === "FAILED") return "Red";
            if (statusText === "COMPLETED" && resultText === "STOPPED") return "Gray";
            if (statusText === "PENDING") return "'#FFA500'";
            if (statusText === "IN_PROGRESS") return "Blue";
        },
        getStatusText = function (statusText, resultText, stageType) {
          if (statusText === "IN_PROGRESS" && stageType === "pipeline_state_in_progress_paused") return "Paused";
          if (statusText === "COMPLETED" && resultText === "SUCCESSFUL") return "Succeeded";
          if (statusText === "COMPLETED" && resultText === "FAILED") return "Failed";
          if (statusText === "COMPLETED" && resultText === "STOPPED") return "Stopped";
          if (statusText === "PENDING") return "Pending";
          if (statusText === "IN_PROGRESS") return "In Progress";

          return statusText;
        },
        simplifyBuild = function (res) {
          console.dir(res)
            return {
                id: res.uuid,
                project: res.repository.name,
                number: res.build_number,
                isRunning: !res.completed_on,
                startedAt: parseDate(res.created_on),
                finishedAt: parseDate(res.completed_on),
                requestedFor: (res.creator || {}).display_name,
                statusText: getStatusText(res.state.name, (res.state.result || {}).name, (res.state.stage || {}).type),
                status: getStatus(res.state.name, (res.state.result || {}).name, (res.state.stage || {}).type),
                url: res.repository.links.self.href
            };
        },
        queryBuilds = function (callback) {
            makeRequest(makeUrl(), function (error, body) {
                if (error || body.type === 'error') {
                  callback(error || body.error);
                  return;
                }

                var builds = [];

                forEachResult(body, function (res) {
                    builds.push(simplifyBuild(res));
                });

                callback(error, builds);
            });
        };

    self.configure = function (config) {
        self.configuration = config;
    };

    self.check = function (callback) {
        queryBuilds(callback);
    };
};
<commit_msg>chore: remove obsolete console.dir<commit_after>var request = require('../requests');

module.exports = function () {
    var self = this,
        makeUrl = function () {
            return 'https://api.bitbucket.org/2.0/repositories/' + (self.configuration.teamname || self.configuration.username) + '/' + self.configuration.slug + '/pipelines/?sort=-created_on&pagelen=1';
        },
        makeBasicAuthToken = function() {
            return Buffer.from(self.configuration.username + ':' + self.configuration.apiKey).toString('base64');
        },
        makeRequest = function (url, callback) {
          request.makeRequest({
            url: url,
            headers: {Authorization: 'Basic ' + makeBasicAuthToken()}
          }, callback);
        },
        parseDate = function (dateAsString) {
            return dateAsString ? new Date(dateAsString) : null;
        },
        forEachResult = function (body, callback) {
            for (var i = 0; i < body.values.length; i++) {
                callback(body.values[i]);
            }
        },
        getStatus = function (statusText, resultText, stageType) {
            if (statusText === "IN_PROGRESS" && stageType === "pipeline_state_in_progress_paused") return "Gray";
            if (statusText === "COMPLETED" && resultText === "SUCCESSFUL") return "Green";
            if (statusText === "COMPLETED" && resultText === "FAILED") return "Red";
            if (statusText === "COMPLETED" && resultText === "STOPPED") return "Gray";
            if (statusText === "PENDING") return "'#FFA500'";
            if (statusText === "IN_PROGRESS") return "Blue";
        },
        getStatusText = function (statusText, resultText, stageType) {
          if (statusText === "IN_PROGRESS" && stageType === "pipeline_state_in_progress_paused") return "Paused";
          if (statusText === "COMPLETED" && resultText === "SUCCESSFUL") return "Succeeded";
          if (statusText === "COMPLETED" && resultText === "FAILED") return "Failed";
          if (statusText === "COMPLETED" && resultText === "STOPPED") return "Stopped";
          if (statusText === "PENDING") return "Pending";
          if (statusText === "IN_PROGRESS") return "In Progress";

          return statusText;
        },
        simplifyBuild = function (res) {
            return {
                id: res.uuid,
                project: res.repository.name,
                number: res.build_number,
                isRunning: !res.completed_on,
                startedAt: parseDate(res.created_on),
                finishedAt: parseDate(res.completed_on),
                requestedFor: (res.creator || {}).display_name,
                statusText: getStatusText(res.state.name, (res.state.result || {}).name, (res.state.stage || {}).type),
                status: getStatus(res.state.name, (res.state.result || {}).name, (res.state.stage || {}).type),
                url: res.repository.links.self.href
            };
        },
        queryBuilds = function (callback) {
            makeRequest(makeUrl(), function (error, body) {
                if (error || body.type === 'error') {
                  callback(error || body.error);
                  return;
                }

                var builds = [];

                forEachResult(body, function (res) {
                    builds.push(simplifyBuild(res));
                });

                callback(error, builds);
            });
        };

    self.configure = function (config) {
        self.configuration = config;
    };

    self.check = function (callback) {
        queryBuilds(callback);
    };
};
<|endoftext|>


<commit_before>define(['app', 'underscore'], function (app, _) { 'use strict';

	app.factory('appConfigService',  ["$location", function($location) {
		var realmConfigurations = [
			//Production
			{
				'host': 'absch.cbd.int',
				'realm': 'ABS',
				'roles': [{
						'User': 'User'
						}, {
							'Administrator': 'Administrator'
						}, {
							'AbsAdministrator': 'AbsAdministrator'
						}, {
							'AbsPublishingAuthorities': 'AbsPublishingAuthorities'
						}, {
							'abschiac': 'abschiac'
						}, {
							'AbsNationalAuthorizedUser': 'AbsNationalAuthorizedUser'
						}, {
							'AbsNationalFocalPoint': 'AbsNationalFocalPoint'
						}]
			},

			//Development
			{
				'host': 'localhost',
				'realm': 'ABS-DEV',
				'roles': [{
					'User': 'User'
				}, {
					'Administrator': 'Administrator'
				}, {
					'AbsAdministrator': 'AbsAdministrator-dev'
				}, {
					'AbsPublishingAuthorities': 'AbsPublishingAuthorities-dev'
				}, {
					'abschiac': 'abschiac-dev'
				}, {
					'AbsNationalAuthorizedUser': 'AbsNationalAuthorizedUser-dev'
				}, {
					'AbsNationalFocalPoint': 'AbsNationalFocalPoint-dev'
				}]
			}, {
				'host': 'absch.cbddev.xyz',
				'realm': 'ABS-DEV',
				'roles': [{
					'User': 'User'
				}, {
					'Administrator': 'Administrator'
				}, {
					'AbsAdministrator': 'AbsAdministrator-dev'
				}, {
					'AbsPublishingAuthorities': 'AbsPublishingAuthorities-dev'
				}, {
					'abschiac': 'abschiac-dev'
				}, {
					'AbsNationalAuthorizedUser': 'AbsNationalAuthorizedUser-dev'
				}, {
					'AbsNationalFocalPoint': 'AbsNationalFocalPoint-dev'
				}]
			},
			//staginh
                        {
				'host': 'absch.staging.cbd.int',
				'realm': 'ABS-DEV',
				'roles': [{
					'User': 'User'
				}, {
					'Administrator': 'Administrator'
				}, {
					'AbsAdministrator': 'AbsAdministrator-dev'
				}, {
					'AbsPublishingAuthorities': 'AbsPublishingAuthorities-dev'
				}, {
					'abschiac': 'abschiac-dev'
				}, {
					'AbsNationalAuthorizedUser': 'AbsNationalAuthorizedUser-dev'
				}, {
					'AbsNationalFocalPoint': 'AbsNationalFocalPoint-dev'
				}]
			},
			//Training
			{
				'host': 'training-absch.cbd.int',
				'realm': 'ABS-TRG',
				'roles': [{
					'User': 'ABSRegisteredUser-trg'
				}, {
					'Administrator': 'Administrator'
				}, {
					'AbsAdministrator': 'AbsAdministrator-trg'
				}, {
					'AbsPublishingAuthorities': 'AbsPublishingAuthorities-trg'
				}, {
					'abschiac': 'abschiac-trg'
				}, {
					'AbsNationalAuthorizedUser': 'AbsNationalAuthorizedUser-trg'
				}, {
					'AbsNationalFocalPoint': 'AbsNationalFocalPoint-trg'
				}]
			},

		]

        var nationalSchemas 	= [ "absPermit", "absCheckpoint", "absCheckpointCommunique", "authority", "measure", "database", "focalPoint", "absNationalReport", "contact"];
        var referenceSchemas 	= [ "resource", "modelContractualClause", "communityProtocol", "capacityBuildingInitiative", "capacityBuildingResource"];
		var scbdSchemas			= [ "meeting", "notification", "pressRelease", "statement", "news", "new" ];

        var realmConfig 		= _.find(realmConfigurations,{host:$location.$$host});
        var currentRealm 		= realmConfig.realm;

        function setCurrentRealm(newRealm){
			if(_.find(realmConfigurations,{realm : newRealm})){
				realmConfig = _.find(realmConfigurations,{realm : newRealm});
				currentRealm = newRealm;
			}
			else{
				throw 'Realm not found, please contact ABSCH team';
			}

        }

        function getRoles(){
            return realmConfig.roles;
        }

		function getRoleName(roleName) {
            if (roleName) {

                if (realmConfig) {
                    var role = _.find(realmConfig.roles, function(key) {
                        return _.keys(key)[0] == roleName;
                    });
                    // console.log(realmConfig, role)
                    if (role)
                        return _.values(role)[0];
                    else
						throw roleName + ' role is not configured for realm ' + realmConfig.realm + ', please update realm-configuration.js';
                } else
                    throw 'Realm not configured, please update realm-configuration.js';
            }
        }
		function nationalRoles(){

		   return _.without(
					   _.flatten(
					       _.map(getRoles(), function(role) {
					           return _.values(role);
				       	   })
			   			),
				 'User');
		}

		function getSiteMapUrls(){
			return {
				register: {
		            dashboard	: "/register/dashboard",
		            requests	: "/register/requests"
		        },

		        errors: {
		            notFound: "/help/404",
		            notAuthorized: "/help/403"
		        },

		        user: {
		            signIn: "/signin"
		        }
			};
		}

		return {
			nationalSchemas     :   nationalSchemas,
			referenceSchemas    :   referenceSchemas,
			scbdSchemas			:	scbdSchemas,

			currentRealm        :   currentRealm,
			setCurrentRealm  	:   setCurrentRealm,

			getRoles            :   getRoles,
			nationalRoles		:	nationalRoles,
			getRoleName			:	getRoleName,

			getSiteMapUrls		:	getSiteMapUrls
	   };

    }]);
});
<commit_msg>absch.local realm config<commit_after>define(['app', 'underscore'], function (app, _) { 'use strict';

	app.factory('appConfigService',  ["$location", function($location) {
		var realmConfigurations = [
			//Production
			{
				'host': 'absch.cbd.int',
				'realm': 'ABS',
				'roles': [{
						'User': 'User'
						}, {
							'Administrator': 'Administrator'
						}, {
							'AbsAdministrator': 'AbsAdministrator'
						}, {
							'AbsPublishingAuthorities': 'AbsPublishingAuthorities'
						}, {
							'abschiac': 'abschiac'
						}, {
							'AbsNationalAuthorizedUser': 'AbsNationalAuthorizedUser'
						}, {
							'AbsNationalFocalPoint': 'AbsNationalFocalPoint'
						}]
			},

			//Development
			{
				'host': 'localhost',
				'realm': 'ABS-DEV',
				'roles': [{
					'User': 'User'
				}, {
					'Administrator': 'Administrator'
				}, {
					'AbsAdministrator': 'AbsAdministrator-dev'
				}, {
					'AbsPublishingAuthorities': 'AbsPublishingAuthorities-dev'
				}, {
					'abschiac': 'abschiac-dev'
				}, {
					'AbsNationalAuthorizedUser': 'AbsNationalAuthorizedUser-dev'
				}, {
					'AbsNationalFocalPoint': 'AbsNationalFocalPoint-dev'
				}]
			},
			{
				'host': 'absch.local',
				'realm': 'ABS-DEV',
				'roles': [{
					'User': 'User'
				}, {
					'Administrator': 'Administrator'
				}, {
					'AbsAdministrator': 'AbsAdministrator-dev'
				}, {
					'AbsPublishingAuthorities': 'AbsPublishingAuthorities-dev'
				}, {
					'abschiac': 'abschiac-dev'
				}, {
					'AbsNationalAuthorizedUser': 'AbsNationalAuthorizedUser-dev'
				}, {
					'AbsNationalFocalPoint': 'AbsNationalFocalPoint-dev'
				}]
			}, {
				'host': 'absch.cbddev.xyz',
				'realm': 'ABS-DEV',
				'roles': [{
					'User': 'User'
				}, {
					'Administrator': 'Administrator'
				}, {
					'AbsAdministrator': 'AbsAdministrator-dev'
				}, {
					'AbsPublishingAuthorities': 'AbsPublishingAuthorities-dev'
				}, {
					'abschiac': 'abschiac-dev'
				}, {
					'AbsNationalAuthorizedUser': 'AbsNationalAuthorizedUser-dev'
				}, {
					'AbsNationalFocalPoint': 'AbsNationalFocalPoint-dev'
				}]
			},
			//staginh
                        {
				'host': 'absch.staging.cbd.int',
				'realm': 'ABS-DEV',
				'roles': [{
					'User': 'User'
				}, {
					'Administrator': 'Administrator'
				}, {
					'AbsAdministrator': 'AbsAdministrator-dev'
				}, {
					'AbsPublishingAuthorities': 'AbsPublishingAuthorities-dev'
				}, {
					'abschiac': 'abschiac-dev'
				}, {
					'AbsNationalAuthorizedUser': 'AbsNationalAuthorizedUser-dev'
				}, {
					'AbsNationalFocalPoint': 'AbsNationalFocalPoint-dev'
				}]
			},
			//Training
			{
				'host': 'training-absch.cbd.int',
				'realm': 'ABS-TRG',
				'roles': [{
					'User': 'ABSRegisteredUser-trg'
				}, {
					'Administrator': 'Administrator'
				}, {
					'AbsAdministrator': 'AbsAdministrator-trg'
				}, {
					'AbsPublishingAuthorities': 'AbsPublishingAuthorities-trg'
				}, {
					'abschiac': 'abschiac-trg'
				}, {
					'AbsNationalAuthorizedUser': 'AbsNationalAuthorizedUser-trg'
				}, {
					'AbsNationalFocalPoint': 'AbsNationalFocalPoint-trg'
				}]
			},

		]

        var nationalSchemas 	= [ "absPermit", "absCheckpoint", "absCheckpointCommunique", "authority", "measure", "database", "focalPoint", "absNationalReport", "contact"];
        var referenceSchemas 	= [ "resource", "modelContractualClause", "communityProtocol", "capacityBuildingInitiative", "capacityBuildingResource"];
		var scbdSchemas			= [ "meeting", "notification", "pressRelease", "statement", "news", "new" ];

        var realmConfig 		= _.find(realmConfigurations,{host:$location.$$host});
        var currentRealm 		= realmConfig.realm;

        function setCurrentRealm(newRealm){
			if(_.find(realmConfigurations,{realm : newRealm})){
				realmConfig = _.find(realmConfigurations,{realm : newRealm});
				currentRealm = newRealm;
			}
			else{
				throw 'Realm not found, please contact ABSCH team';
			}

        }

        function getRoles(){
            return realmConfig.roles;
        }

		function getRoleName(roleName) {
            if (roleName) {

                if (realmConfig) {
                    var role = _.find(realmConfig.roles, function(key) {
                        return _.keys(key)[0] == roleName;
                    });
                    // console.log(realmConfig, role)
                    if (role)
                        return _.values(role)[0];
                    else
						throw roleName + ' role is not configured for realm ' + realmConfig.realm + ', please update realm-configuration.js';
                } else
                    throw 'Realm not configured, please update realm-configuration.js';
            }
        }
		function nationalRoles(){

		   return _.without(
					   _.flatten(
					       _.map(getRoles(), function(role) {
					           return _.values(role);
				       	   })
			   			),
				 'User');
		}

		function getSiteMapUrls(){
			return {
				register: {
		            dashboard	: "/register/dashboard",
		            requests	: "/register/requests"
		        },

		        errors: {
		            notFound: "/help/404",
		            notAuthorized: "/help/403"
		        },

		        user: {
		            signIn: "/signin"
		        }
			};
		}

		return {
			nationalSchemas     :   nationalSchemas,
			referenceSchemas    :   referenceSchemas,
			scbdSchemas			:	scbdSchemas,

			currentRealm        :   currentRealm,
			setCurrentRealm  	:   setCurrentRealm,

			getRoles            :   getRoles,
			nationalRoles		:	nationalRoles,
			getRoleName			:	getRoleName,

			getSiteMapUrls		:	getSiteMapUrls
	   };

    }]);
});
<|endoftext|>


<commit_before>angular.module('mewpipe')
       .factory('errorsInterceptor', errorsInterceptor);

errorsInterceptor.$inject = ['$location','$q','Config'];

function errorsInterceptor($location,$q,Config){
	return {

		'responseError' : function(rejection){

			switch(rejection.status){

				case 401 :
					$location.path('/login');
					break;

				default :
					$location.path('/error/' + rejection.status);
					break;

			}

			return {};
		}

	}
}<commit_msg>Edit errors interceptor<commit_after>angular.module('mewpipe')
       .factory('errorsInterceptor', errorsInterceptor);

errorsInterceptor.$inject = ['$location','$q','Config'];

function errorsInterceptor($location,$q,Config){
	return {

		'responseError' : function(rejection){

			switch(rejection.status){

				case 401 :
					$location.path('/login');
					break;
				case 404 :
					$location.path('/error/404');
					break;

			}

			return $q.reject(rejection);
		}

	}
}<|endoftext|>


<commit_before>// $.pjax fallback tests should run on both pushState and
// non-pushState compatible browsers.
$.each([true, false], function() {

var disabled = this == false
var s = disabled ? " (disabled)" : ""

module("$.pjax fallback"+s, {
  setup: function() {
    var self = this
    stop()
    this.loaded = function(frame) {
      self.frame  = frame
      self.loaded = $.noop
      start()
    }
    window.iframeLoad = function(frame) {
      setTimeout(function() {
        if (disabled && frame.$ && frame.$.pjax) frame.$.pjax.disable()
        self.loaded(frame)
      }, 0)
    }
    $("#qunit-fixture").append("<iframe src='home.html'>")
  },
  teardown: function() {
    delete window.iframeLoad
  }
})

asyncTest("sets new url"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/hello.html")
    start()
  }

  frame.$.pjax({
    url: "hello.html",
    container: "#main"
  })
})

asyncTest("sets new url for function"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/hello.html")
    start()
  }

  frame.$.pjax({
    url: function() { return "hello.html" },
    container: "#main"
  })
})

asyncTest("updates container html"+s, function() {
  var frame = this.frame

  this.loaded = function(frame) {
    equal(frame.$("#main p").html(), "Hello!")
    start()
  }

  frame.$.pjax({
    url: "/hello.html",
    container: "#main"
  })
})

asyncTest("sets title to response <title>"+s, function() {
  var frame = this.frame

  this.loaded = function(frame) {
    equal(frame.document.title, "Hello")
    start()
  }

  frame.$.pjax({
    url: "/hello.html",
    container: "#main"
  })
})

asyncTest("sends correct HTTP referer"+s, function() {
  var frame = this.frame

  this.loaded = function(frame) {
    var referer = frame.document.getElementById("referer").textContent
    ok(referer.match("/home.html"), referer)
    start()
  }

  frame.$.pjax({
    url: "/referer.html",
    container: "#main"
  })
})

asyncTest("adds entry to browser history"+s, function() {
  var frame = this.frame
  var count = 0

  this.loaded = function() {
    count++

    if (count == 1) {
      equal(frame.location.pathname, "/hello.html")
      ok(frame.history.length > 1)
      frame.history.back()
    } else if (count == 2) {
      equal(frame.location.pathname, "/home.html")
      frame.history.forward()
      start()
    }
  }

  frame.$.pjax({
    url: "hello.html",
    container: "#main"
  })
})

asyncTest("scrolls to top of the page"+s, function() {
  var frame = this.frame

  frame.window.scrollTo(0, 100)
  equal(frame.window.scrollY, 100)

  this.loaded = function(frame) {
    equal(frame.window.scrollY, 0)
    start()
  }

  frame.$.pjax({
    url: "/long.html",
    container: "#main"
  })
})

asyncTest("scrolls to anchor at top page"+s, function() {
  var frame = this.frame

  equal(frame.window.scrollY, 0)

  this.loaded = function(frame) {
    setTimeout(function() {
      equal(frame.window.scrollY, 8)
      start()
    }, 10)
  }

  frame.$.pjax({
    url: "/anchor.html#top",
    container: "#main"
  })
})

asyncTest("empty anchor doesn't scroll page"+s, function() {
  var frame = this.frame

  equal(frame.window.scrollY, 0)

  this.loaded = function(frame) {
    setTimeout(function() {
      equal(frame.window.scrollY, 0)
      start()
    }, 10)
  }

  frame.$.pjax({
    url: "/anchor.html#",
    container: "#main"
  })
})

asyncTest("scrolls to anchor at bottom page"+s, function() {
  var frame = this.frame

  equal(frame.window.scrollY, 0)

  this.loaded = function(frame) {
    setTimeout(function() {
      equal(frame.window.scrollY, 10008)
      start()
    }, 10)
  }

  frame.$.pjax({
    url: "/anchor.html#bottom",
    container: "#main"
  })
})

asyncTest("sets GET method"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/env.html")
    var env = JSON.parse(frame.$("#env").text())
    equal(env['REQUEST_METHOD'], "GET")
    start()
  }

  frame.$.pjax({
    type: 'GET',
    url: "env.html",
    container: "#main"
  })
})

asyncTest("sets POST method"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/env.html")
    var env = JSON.parse(frame.$("#env").text())
    equal(env['REQUEST_METHOD'], "POST")
    start()
  }

  frame.$.pjax({
    type: 'POST',
    url: "env.html",
    container: "#main"
  })
})

asyncTest("sets PUT method"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/env.html")
    var env = JSON.parse(frame.$("#env").text())
    equal(env['REQUEST_METHOD'], "PUT")
    start()
  }

  frame.$.pjax({
    type: 'PUT',
    url: "env.html",
    container: "#main"
  })
})

asyncTest("sets DELETE method"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/env.html")
    var env = JSON.parse(frame.$("#env").text())
    equal(env['REQUEST_METHOD'], "DELETE")
    start()
  }

  frame.$.pjax({
    type: 'DELETE',
    url: "env.html",
    container: "#main"
  })
})

asyncTest("GET with data object"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/env.html")
    equal(frame.location.search, "?foo=bar")

    var env = JSON.parse(frame.$("#env").text())
    equal(env['REQUEST_METHOD'], "GET")
    equal(env['rack.request.query_hash']['foo'], 'bar')

    start()
  }

  frame.$.pjax({
    type: 'GET',
    url: "env.html",
    data: {foo: 'bar'},
    container: "#main"
  })
})

asyncTest("POST with data object"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/env.html")
    equal(frame.location.search, "")

    var env = JSON.parse(frame.$("#env").text())
    equal(env['REQUEST_METHOD'], "POST")
    equal(env['rack.request.form_hash']['foo'], 'bar')

    start()
  }

  frame.$.pjax({
    type: 'POST',
    url: "env.html",
    data: {foo: 'bar'},
    container: "#main"
  })
})

asyncTest("GET with data string"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/env.html")
    equal(frame.location.search, "?foo=bar")

    var env = JSON.parse(frame.$("#env").text())
    equal(env['REQUEST_METHOD'], "GET")
    equal(env['rack.request.query_hash']['foo'], 'bar')

    start()
  }

  frame.$.pjax({
    type: 'GET',
    url: "env.html",
    data: "foo=bar",
    container: "#main"
  })
})

asyncTest("POST with data string"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/env.html")
    equal(frame.location.search, "")

    var env = JSON.parse(frame.$("#env").text())
    equal(env['REQUEST_METHOD'], "POST")
    equal(env['rack.request.form_hash']['foo'], 'bar')

    start()
  }

  frame.$.pjax({
    type: 'POST',
    url: "env.html",
    data: "foo=bar",
    container: "#main"
  })
})

})
<commit_msg>Fix popstate frame calling test<commit_after>// $.pjax fallback tests should run on both pushState and
// non-pushState compatible browsers.
$.each([true, false], function() {

var disabled = this == false
var s = disabled ? " (disabled)" : ""

module("$.pjax fallback"+s, {
  setup: function() {
    var self = this
    stop()
    this.loaded = function(frame) {
      self.frame  = frame
      self.loaded = $.noop
      start()
    }
    window.iframeLoad = function(frame) {
      setTimeout(function() {
        if (disabled && frame.$ && frame.$.pjax) frame.$.pjax.disable()
        self.loaded(frame)
      }, 0)
    }
    $("#qunit-fixture").append("<iframe src='home.html'>")
  },
  teardown: function() {
    delete window.iframeLoad
  }
})

asyncTest("sets new url"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/hello.html")
    start()
  }

  frame.$.pjax({
    url: "hello.html",
    container: "#main"
  })
})

asyncTest("sets new url for function"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/hello.html")
    start()
  }

  frame.$.pjax({
    url: function() { return "hello.html" },
    container: "#main"
  })
})

asyncTest("updates container html"+s, function() {
  var frame = this.frame

  this.loaded = function(frame) {
    equal(frame.$("#main p").html(), "Hello!")
    start()
  }

  frame.$.pjax({
    url: "/hello.html",
    container: "#main"
  })
})

asyncTest("sets title to response <title>"+s, function() {
  var frame = this.frame

  this.loaded = function(frame) {
    equal(frame.document.title, "Hello")
    start()
  }

  frame.$.pjax({
    url: "/hello.html",
    container: "#main"
  })
})

asyncTest("sends correct HTTP referer"+s, function() {
  var frame = this.frame

  this.loaded = function(frame) {
    var referer = frame.document.getElementById("referer").textContent
    ok(referer.match("/home.html"), referer)
    start()
  }

  frame.$.pjax({
    url: "/referer.html",
    container: "#main"
  })
})

asyncTest("adds entry to browser history"+s, function() {
  var frame = this.frame
  var count = 0

  frame.onpopstate = function() {
    window.iframeLoad(frame)
  }

  this.loaded = function() {
    count++

    if (count == 1) {
      equal(frame.location.pathname, "/hello.html")
      ok(frame.history.length > 1)
      frame.history.back()
    } else if (count == 2) {
      equal(frame.location.pathname, "/home.html")
      frame.history.forward()
      start()
    }
  }

  frame.$.pjax({
    url: "hello.html",
    container: "#main"
  })
})

asyncTest("scrolls to top of the page"+s, function() {
  var frame = this.frame

  frame.window.scrollTo(0, 100)
  equal(frame.window.scrollY, 100)

  this.loaded = function(frame) {
    equal(frame.window.scrollY, 0)
    start()
  }

  frame.$.pjax({
    url: "/long.html",
    container: "#main"
  })
})

asyncTest("scrolls to anchor at top page"+s, function() {
  var frame = this.frame

  equal(frame.window.scrollY, 0)

  this.loaded = function(frame) {
    setTimeout(function() {
      equal(frame.window.scrollY, 8)
      start()
    }, 10)
  }

  frame.$.pjax({
    url: "/anchor.html#top",
    container: "#main"
  })
})

asyncTest("empty anchor doesn't scroll page"+s, function() {
  var frame = this.frame

  equal(frame.window.scrollY, 0)

  this.loaded = function(frame) {
    setTimeout(function() {
      equal(frame.window.scrollY, 0)
      start()
    }, 10)
  }

  frame.$.pjax({
    url: "/anchor.html#",
    container: "#main"
  })
})

asyncTest("scrolls to anchor at bottom page"+s, function() {
  var frame = this.frame

  equal(frame.window.scrollY, 0)

  this.loaded = function(frame) {
    setTimeout(function() {
      equal(frame.window.scrollY, 10008)
      start()
    }, 10)
  }

  frame.$.pjax({
    url: "/anchor.html#bottom",
    container: "#main"
  })
})

asyncTest("sets GET method"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/env.html")
    var env = JSON.parse(frame.$("#env").text())
    equal(env['REQUEST_METHOD'], "GET")
    start()
  }

  frame.$.pjax({
    type: 'GET',
    url: "env.html",
    container: "#main"
  })
})

asyncTest("sets POST method"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/env.html")
    var env = JSON.parse(frame.$("#env").text())
    equal(env['REQUEST_METHOD'], "POST")
    start()
  }

  frame.$.pjax({
    type: 'POST',
    url: "env.html",
    container: "#main"
  })
})

asyncTest("sets PUT method"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/env.html")
    var env = JSON.parse(frame.$("#env").text())
    equal(env['REQUEST_METHOD'], "PUT")
    start()
  }

  frame.$.pjax({
    type: 'PUT',
    url: "env.html",
    container: "#main"
  })
})

asyncTest("sets DELETE method"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/env.html")
    var env = JSON.parse(frame.$("#env").text())
    equal(env['REQUEST_METHOD'], "DELETE")
    start()
  }

  frame.$.pjax({
    type: 'DELETE',
    url: "env.html",
    container: "#main"
  })
})

asyncTest("GET with data object"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/env.html")
    equal(frame.location.search, "?foo=bar")

    var env = JSON.parse(frame.$("#env").text())
    equal(env['REQUEST_METHOD'], "GET")
    equal(env['rack.request.query_hash']['foo'], 'bar')

    start()
  }

  frame.$.pjax({
    type: 'GET',
    url: "env.html",
    data: {foo: 'bar'},
    container: "#main"
  })
})

asyncTest("POST with data object"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/env.html")
    equal(frame.location.search, "")

    var env = JSON.parse(frame.$("#env").text())
    equal(env['REQUEST_METHOD'], "POST")
    equal(env['rack.request.form_hash']['foo'], 'bar')

    start()
  }

  frame.$.pjax({
    type: 'POST',
    url: "env.html",
    data: {foo: 'bar'},
    container: "#main"
  })
})

asyncTest("GET with data string"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/env.html")
    equal(frame.location.search, "?foo=bar")

    var env = JSON.parse(frame.$("#env").text())
    equal(env['REQUEST_METHOD'], "GET")
    equal(env['rack.request.query_hash']['foo'], 'bar')

    start()
  }

  frame.$.pjax({
    type: 'GET',
    url: "env.html",
    data: "foo=bar",
    container: "#main"
  })
})

asyncTest("POST with data string"+s, function() {
  var frame = this.frame

  this.loaded = function() {
    equal(frame.location.pathname, "/env.html")
    equal(frame.location.search, "")

    var env = JSON.parse(frame.$("#env").text())
    equal(env['REQUEST_METHOD'], "POST")
    equal(env['rack.request.form_hash']['foo'], 'bar')

    start()
  }

  frame.$.pjax({
    type: 'POST',
    url: "env.html",
    data: "foo=bar",
    container: "#main"
  })
})

})
<|endoftext|>