<commit_before>import React from 'react';
import { storiesOf } from '@storybook/react';
import { iconCheckmarkSolid } from 'carbon-icons';
import Icon from '../Icon';
import {
  StructuredListWrapper,
  StructuredListHead,
  StructuredListBody,
  StructuredListRow,
  StructuredListInput,
  StructuredListCell,
} from '../StructuredList';
import StructuredListSkeleton from '../StructuredList/StructuredList.Skeleton';

storiesOf('StructuredList', module)
  .add('Simple', () => (
    <StructuredListWrapper>
      <StructuredListHead>
        <StructuredListRow head>
          <StructuredListCell head>ColumnA</StructuredListCell>
          <StructuredListCell head>ColumnB</StructuredListCell>
          <StructuredListCell head>ColumnC</StructuredListCell>
        </StructuredListRow>
      </StructuredListHead>
      <StructuredListBody>
        <StructuredListRow>
          <StructuredListCell noWrap>Row 1</StructuredListCell>
          <StructuredListCell>Row 1</StructuredListCell>
          <StructuredListCell>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc dui
            magna, finibus id tortor sed, aliquet bibendum augue. Aenean posuere
            sem vel euismod dignissim. Nulla ut cursus dolor. Pellentesque
            vulputate nisl a porttitor interdum.
          </StructuredListCell>
        </StructuredListRow>
        <StructuredListRow>
          <StructuredListCell noWrap>Row 2</StructuredListCell>
          <StructuredListCell>Row 2</StructuredListCell>
          <StructuredListCell>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc dui
            magna, finibus id tortor sed, aliquet bibendum augue. Aenean posuere
            sem vel euismod dignissim. Nulla ut cursus dolor. Pellentesque
            vulputate nisl a porttitor interdum.
          </StructuredListCell>
        </StructuredListRow>
      </StructuredListBody>
    </StructuredListWrapper>
  ))
  .add('Selection', () => (
    <StructuredListWrapper selection border>
      <StructuredListHead>
        <StructuredListRow head>
          <StructuredListCell head>{''}</StructuredListCell>
          <StructuredListCell head>ColumnA</StructuredListCell>
          <StructuredListCell head>ColumnB</StructuredListCell>
          <StructuredListCell head>ColumnC</StructuredListCell>
        </StructuredListRow>
      </StructuredListHead>
      <StructuredListBody>
        <StructuredListRow label htmlFor="row-1">
          <StructuredListInput
            id="row-1"
            value="row-1"
            title="row-1"
            name="row-1"
            defaultChecked
          />
          <StructuredListCell>
            <Icon
              className="bx--structured-list-svg"
              icon={iconCheckmarkSolid}
              description="select an option"
            />
          </StructuredListCell>
          <StructuredListCell>Row 1</StructuredListCell>
          <StructuredListCell>Row 1</StructuredListCell>
          <StructuredListCell>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc dui
            magna, finibus id tortor sed, aliquet bibendum augue. Aenean posuere
            sem vel euismod dignissim. Nulla ut cursus dolor. Pellentesque
            vulputate nisl a porttitor interdum.
          </StructuredListCell>
        </StructuredListRow>
        <StructuredListRow label htmlFor="row-2">
          <StructuredListInput
            id="row-2"
            value="row-2"
            title="row-2"
            name="row-1"
          />
          <StructuredListCell>
            <Icon
              className="bx--structured-list-svg"
              icon={iconCheckmarkSolid}
              description="select an option"
            />
          </StructuredListCell>
          <StructuredListCell>Row 2</StructuredListCell>
          <StructuredListCell>Row 2</StructuredListCell>
          <StructuredListCell>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc dui
            magna, finibus id tortor sed, aliquet bibendum augue. Aenean posuere
            sem vel euismod dignissim. Nulla ut cursus dolor. Pellentesque
            vulputate nisl a porttitor interdum.
          </StructuredListCell>
        </StructuredListRow>
      </StructuredListBody>
    </StructuredListWrapper>
  ))
  .add('skeleton', () => (

      <StructuredListSkeleton />
      <StructuredListSkeleton border />

  ));
<commit_msg>docs(structured-list): add storybook addon-info (#1230)<commit_after>import React from 'react';
import { storiesOf } from '@storybook/react';
import { withInfo } from '@storybook/addon-info';
import { iconCheckmarkSolid } from 'carbon-icons';
import Icon from '../Icon';
import {
  StructuredListWrapper,
  StructuredListHead,
  StructuredListBody,
  StructuredListRow,
  StructuredListInput,
  StructuredListCell,
} from '../StructuredList';
import StructuredListSkeleton from '../StructuredList/StructuredList.Skeleton';

storiesOf('StructuredList', module)
  .add(
    'Simple',
    withInfo({
      text: `
        Structured Lists group content that is similar or related, such as terms or definitions.
      `,
    })(() => (
      <StructuredListWrapper>
        <StructuredListHead>
          <StructuredListRow head>
            <StructuredListCell head>ColumnA</StructuredListCell>
            <StructuredListCell head>ColumnB</StructuredListCell>
            <StructuredListCell head>ColumnC</StructuredListCell>
          </StructuredListRow>
        </StructuredListHead>
        <StructuredListBody>
          <StructuredListRow>
            <StructuredListCell noWrap>Row 1</StructuredListCell>
            <StructuredListCell>Row 1</StructuredListCell>
            <StructuredListCell>
              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc dui
              magna, finibus id tortor sed, aliquet bibendum augue. Aenean
              posuere sem vel euismod dignissim. Nulla ut cursus dolor.
              Pellentesque vulputate nisl a porttitor interdum.
            </StructuredListCell>
          </StructuredListRow>
          <StructuredListRow>
            <StructuredListCell noWrap>Row 2</StructuredListCell>
            <StructuredListCell>Row 2</StructuredListCell>
            <StructuredListCell>
              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc dui
              magna, finibus id tortor sed, aliquet bibendum augue. Aenean
              posuere sem vel euismod dignissim. Nulla ut cursus dolor.
              Pellentesque vulputate nisl a porttitor interdum.
            </StructuredListCell>
          </StructuredListRow>
        </StructuredListBody>
      </StructuredListWrapper>
    ))
  )
  .add(
    'Selection',
    withInfo({
      text: `
        Structured Lists with selection allow a row of list content to be selected.
      `,
    })(() => (
      <StructuredListWrapper selection border>
        <StructuredListHead>
          <StructuredListRow head>
            <StructuredListCell head>{''}</StructuredListCell>
            <StructuredListCell head>ColumnA</StructuredListCell>
            <StructuredListCell head>ColumnB</StructuredListCell>
            <StructuredListCell head>ColumnC</StructuredListCell>
          </StructuredListRow>
        </StructuredListHead>
        <StructuredListBody>
          <StructuredListRow label htmlFor="row-1">
            <StructuredListInput
              id="row-1"
              value="row-1"
              title="row-1"
              name="row-1"
              defaultChecked
            />
            <StructuredListCell>
              <Icon
                className="bx--structured-list-svg"
                icon={iconCheckmarkSolid}
                description="select an option"
              />
            </StructuredListCell>
            <StructuredListCell>Row 1</StructuredListCell>
            <StructuredListCell>Row 1</StructuredListCell>
            <StructuredListCell>
              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc dui
              magna, finibus id tortor sed, aliquet bibendum augue. Aenean
              posuere sem vel euismod dignissim. Nulla ut cursus dolor.
              Pellentesque vulputate nisl a porttitor interdum.
            </StructuredListCell>
          </StructuredListRow>
          <StructuredListRow label htmlFor="row-2">
            <StructuredListInput
              id="row-2"
              value="row-2"
              title="row-2"
              name="row-1"
            />
            <StructuredListCell>
              <Icon
                className="bx--structured-list-svg"
                icon={iconCheckmarkSolid}
                description="select an option"
              />
            </StructuredListCell>
            <StructuredListCell>Row 2</StructuredListCell>
            <StructuredListCell>Row 2</StructuredListCell>
            <StructuredListCell>
              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc dui
              magna, finibus id tortor sed, aliquet bibendum augue. Aenean
              posuere sem vel euismod dignissim. Nulla ut cursus dolor.
              Pellentesque vulputate nisl a porttitor interdum.
            </StructuredListCell>
          </StructuredListRow>
        </StructuredListBody>
      </StructuredListWrapper>
    ))
  )
  .add(
    'skeleton',
    withInfo({
      text: `
        Placeholder skeleton state to use when content is loading.
      `,
    })(() => (

        <StructuredListSkeleton />
        <StructuredListSkeleton border />

    ))
  );
<|endoftext|>


<commit_before>
app.constant("SIGNIN_ENDPOINT", "php/api/signin/");
app.service("SigninService", function($http, signin_ENDPOINT) {
	function getUrl() {
		return(signin_ENDPOINT);
	}
	this.signin = function(signin) {
		return($http.post(getUrl(), signin));
	};
});<commit_msg>still trying to get signin to work https://app.asana.com/0/117435667927162/118836678397143<commit_after>
app.constant("SIGNIN_ENDPOINT", "php/apis/signin/");
app.service("SigninService", function($http, signin_ENDPOINT) {
	function getUrl() {
		return(signin_ENDPOINT);
	}
	this.signin = function(signin) {
		return($http.post(getUrl(), signin));
	};
});<|endoftext|>


<commit_before>var _config = {
	fixture: null,
	Test: [],
	stats: {
		all: 0,
		bad: 0
	},
	queue: [],
	blocking: true,
	timeout: null,
	expected: null,
	currentModule: null,
	asyncTimeout: 2 // seconds for async timeout
};

$(function() {
	$('#userAgent').html(navigator.userAgent);
	if($.browser.safari)
		$("h1").append(" - Slowed down for Safari to prevent crashes");
	runTest();
});

function synchronize(callback) {
	_config.queue[_config.queue.length] = callback;
	if(!_config.blocking) {
		process();
	}
}

function process() {
	while(_config.queue.length && !_config.blocking) {
		var call = _config.queue[0];
		_config.queue = _config.queue.slice(1);
		call();
	}
}

function stop(allowFailure) {
	_config.blocking = true;
	var handler = allowFailure ? start : function() {
		ok( false, "Test timed out" );
		start();
	};
	_config.timeout = setTimeout(handler, _config.asyncTimeout * 1000);
}
function start() {
	if(_config.timeout)
		clearTimeout(_config.timeout);
	_config.blocking = false;
	process();
}

function runTest() {
	_config.blocking = false;
	var time = new Date();
	_config.fixture = document.getElementById('main').innerHTML;
	synchronize(function() {
		time = new Date() - time;
		$("
").html(['
Tests completed in ',
			time, ' milliseconds.
',
			_config.stats.bad, ' tests of ', _config.stats.all, ' failed.
']
			.join(''))
			.appendTo("body");
		$("#banner").addClass(_config.stats.bad ? "fail" : "pass");
	});
}

function test(name, callback, nowait) {
	// safari seems to have some memory problems, so we need to slow it down
	if($.browser.safari && !nowait) {
		test("", function() {
			stop();
			setTimeout(start, 250);
		}, true);
	}

	if(_config.currentModule)
		name = _config.currentModule + " module: " + name;

	synchronize(function() {
		_config.Test = [];
		try {
			callback();
		} catch(e) {
			if( typeof console != "undefined" && console.error && console.warn ) {
				console.error("Test " + name + " died, exception and test follows");
				console.error(e);
				console.warn(callback.toString());
			}
			_config.Test.push( [ false, "Died on test #" + (_config.Test.length+1) + ": " + e ] );
		}
	});
	synchronize(function() {
		reset();

		// don't output pause tests
		if(nowait) return;

		if(_config.expected && _config.expected != _config.Test.length) {
			_config.Test.push( [ false, "Expected " + _config.expected + " assertions, but " + _config.Test.length + " were run" ] );
		}
		_config.expected = null;

		var good = 0, bad = 0;
		var ol = document.createElement("ol");
		ol.style.display = "none";
		var li = "", state = "pass";
		for ( var i = 0; i < _config.Test.length; i++ ) {
			var li = document.createElement("li");
			li.className = _config.Test[i][0] ? "pass" : "fail";
			li.innerHTML = _config.Test[i][1];
			ol.appendChild( li );

			_config.stats.all++;
			if ( !_config.Test[i][0] ) {
				state = "fail";
				bad++;
				_config.stats.bad++;
			} else good++;
		}

		var li = document.createElement("li");
		li.className = state;

		var b = document.createElement("b");
		b.innerHTML = name + " (" + bad + ", " + good + ", " + _config.Test.length + ")";
		b.onclick = function(){
			var n = this.nextSibling;
			if ( jQuery.css( n, "display" ) == "none" )
				n.style.display = "block";
			else
				n.style.display = "none";
		};
		li.appendChild( b );
		li.appendChild( ol );

		document.getElementById("tests").appendChild( li );
	});
}

// call on start of module test to prepend name to all tests
function module(moduleName) {
	_config.currentModule = moduleName;
}

/**
 * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
 */
function expect(asserts) {
	_config.expected = asserts;
}

/**
 * Resets the test setup. Useful for tests that modify the DOM.
 */
function reset() {
	document.getElementById('main').innerHTML = _config.fixture;
}

/**
 * Asserts true.
 * @example ok( $("a").size() > 5, "There must be at least 5 anchors" );
 */
function ok(a, msg) {
	_config.Test.push( [ !!a, msg ] );
}

/**
 * Asserts that two arrays are the same
 */
function isSet(a, b, msg) {
	var ret = true;
	if ( a && b && a.length == b.length ) {
		for ( var i in a )
			if ( a[i] != b[i] )
				ret = false;
	} else
		ret = false;
	if ( !ret )
		_config.Test.push( [ ret, msg + " expected: " + b + " result: " + a ] );
	else
		_config.Test.push( [ ret, msg ] );
}

/**
 * Returns an array of elements with the given IDs, eg.
 * @example q("main", "foo", "bar")
 * @result [
, , <input id="bar">]
 */
function q() {
	var r = [];
	for ( var i = 0; i < arguments.length; i++ )
		r.push( document.getElementById( arguments[i] ) );
	return r;
}

/**
 * Asserts that a select matches the given IDs
 * @example t("Check for something", "//[a]", ["foo", "baar"]);
 * @result returns true if "//[a]" return two elements with the IDs 'foo' and 'baar'
 */
function t(a,b,c) {
	var f = jQuery.find(b);
	var s = "";
	for ( var i = 0; i < f.length; i++ )
		s += (s && ",") + '"' + f[i].id + '"';
	isSet(f, q.apply(q,c), a + " (" + b + ")");
}

/**
 * Add random number to url to stop IE from caching
 *
 * @example url("data/test.html")
 * @result "data/test.html?10538358428943"
 *
 * @example url("data/test.php?foo=bar")
 * @result "data/test.php?foo=bar&10538358345554"
 */
function url(value) {
	return value + (/\?/.test(value) ? "&" : "?") + new Date().getTime() + "" + parseInt(Math.random()*100000);
}

/**
 * Checks that the first two arguments are equal, with an optional message.
 * Prints out both expected and actual values on failure.
 *
 * Prefered to ok( expected == actual, message )
 *
 * @example equals( "Expected 2 characters.", v.formatMessage("Expected {0} characters.", 2) );
 *
 * @param Object expected
 * @param Object actual
 * @param String message (optional)
 */
function equals(expected, actual, message) {
	var result = expected == actual;
	message = message || result ? "okay" : "failed";
	_config.Test.push( [ result, result ? message + ": " + expected : message + " expected: " + expected + " actual: " + actual ] );
}
<commit_msg>Disabled the test suite in Safari.<commit_after>var _config = {
	fixture: null,
	Test: [],
	stats: {
		all: 0,
		bad: 0
	},
	queue: [],
	blocking: true,
	timeout: null,
	expected: null,
	currentModule: null,
	asyncTimeout: 2 // seconds for async timeout
};

$(function() {
	$('#userAgent').html(navigator.userAgent);
	if($.browser.safari)
		$("h1").append(" - Disabled for Safari");
	else
		runTest();
});

function synchronize(callback) {
	_config.queue[_config.queue.length] = callback;
	if(!_config.blocking) {
		process();
	}
}

function process() {
	while(_config.queue.length && !_config.blocking) {
		var call = _config.queue[0];
		_config.queue = _config.queue.slice(1);
		call();
	}
}

function stop(allowFailure) {
	_config.blocking = true;
	var handler = allowFailure ? start : function() {
		ok( false, "Test timed out" );
		start();
	};
	_config.timeout = setTimeout(handler, _config.asyncTimeout * 1000);
}
function start() {
	if(_config.timeout)
		clearTimeout(_config.timeout);
	_config.blocking = false;
	process();
}

function runTest() {
	_config.blocking = false;
	var time = new Date();
	_config.fixture = document.getElementById('main').innerHTML;
	synchronize(function() {
		time = new Date() - time;
		$("
").html(['
Tests completed in ',
			time, ' milliseconds.
',
			_config.stats.bad, ' tests of ', _config.stats.all, ' failed.
']
			.join(''))
			.appendTo("body");
		$("#banner").addClass(_config.stats.bad ? "fail" : "pass");
	});
}

function test(name, callback, nowait) {
	// safari seems to have some memory problems, so we need to slow it down
	if($.browser.safari && !nowait) {
		test("", function() {
			stop();
			setTimeout(start, 250);
		}, true);
	}

	if(_config.currentModule)
		name = _config.currentModule + " module: " + name;

	synchronize(function() {
		_config.Test = [];
		try {
			callback();
		} catch(e) {
			if( typeof console != "undefined" && console.error && console.warn ) {
				console.error("Test " + name + " died, exception and test follows");
				console.error(e);
				console.warn(callback.toString());
			}
			_config.Test.push( [ false, "Died on test #" + (_config.Test.length+1) + ": " + e ] );
		}
	});
	synchronize(function() {
		reset();

		// don't output pause tests
		if(nowait) return;

		if(_config.expected && _config.expected != _config.Test.length) {
			_config.Test.push( [ false, "Expected " + _config.expected + " assertions, but " + _config.Test.length + " were run" ] );
		}
		_config.expected = null;

		var good = 0, bad = 0;
		var ol = document.createElement("ol");
		ol.style.display = "none";
		var li = "", state = "pass";
		for ( var i = 0; i < _config.Test.length; i++ ) {
			var li = document.createElement("li");
			li.className = _config.Test[i][0] ? "pass" : "fail";
			li.innerHTML = _config.Test[i][1];
			ol.appendChild( li );

			_config.stats.all++;
			if ( !_config.Test[i][0] ) {
				state = "fail";
				bad++;
				_config.stats.bad++;
			} else good++;
		}

		var li = document.createElement("li");
		li.className = state;

		var b = document.createElement("b");
		b.innerHTML = name + " (" + bad + ", " + good + ", " + _config.Test.length + ")";
		b.onclick = function(){
			var n = this.nextSibling;
			if ( jQuery.css( n, "display" ) == "none" )
				n.style.display = "block";
			else
				n.style.display = "none";
		};
		li.appendChild( b );
		li.appendChild( ol );

		document.getElementById("tests").appendChild( li );
	});
}

// call on start of module test to prepend name to all tests
function module(moduleName) {
	_config.currentModule = moduleName;
}

/**
 * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
 */
function expect(asserts) {
	_config.expected = asserts;
}

/**
 * Resets the test setup. Useful for tests that modify the DOM.
 */
function reset() {
	document.getElementById('main').innerHTML = _config.fixture;
}

/**
 * Asserts true.
 * @example ok( $("a").size() > 5, "There must be at least 5 anchors" );
 */
function ok(a, msg) {
	_config.Test.push( [ !!a, msg ] );
}

/**
 * Asserts that two arrays are the same
 */
function isSet(a, b, msg) {
	var ret = true;
	if ( a && b && a.length == b.length ) {
		for ( var i in a )
			if ( a[i] != b[i] )
				ret = false;
	} else
		ret = false;
	if ( !ret )
		_config.Test.push( [ ret, msg + " expected: " + b + " result: " + a ] );
	else
		_config.Test.push( [ ret, msg ] );
}

/**
 * Returns an array of elements with the given IDs, eg.
 * @example q("main", "foo", "bar")
 * @result [
, , <input id="bar">]
 */
function q() {
	var r = [];
	for ( var i = 0; i < arguments.length; i++ )
		r.push( document.getElementById( arguments[i] ) );
	return r;
}

/**
 * Asserts that a select matches the given IDs
 * @example t("Check for something", "//[a]", ["foo", "baar"]);
 * @result returns true if "//[a]" return two elements with the IDs 'foo' and 'baar'
 */
function t(a,b,c) {
	var f = jQuery.find(b);
	var s = "";
	for ( var i = 0; i < f.length; i++ )
		s += (s && ",") + '"' + f[i].id + '"';
	isSet(f, q.apply(q,c), a + " (" + b + ")");
}

/**
 * Add random number to url to stop IE from caching
 *
 * @example url("data/test.html")
 * @result "data/test.html?10538358428943"
 *
 * @example url("data/test.php?foo=bar")
 * @result "data/test.php?foo=bar&10538358345554"
 */
function url(value) {
	return value + (/\?/.test(value) ? "&" : "?") + new Date().getTime() + "" + parseInt(Math.random()*100000);
}

/**
 * Checks that the first two arguments are equal, with an optional message.
 * Prints out both expected and actual values on failure.
 *
 * Prefered to ok( expected == actual, message )
 *
 * @example equals( "Expected 2 characters.", v.formatMessage("Expected {0} characters.", 2) );
 *
 * @param Object expected
 * @param Object actual
 * @param String message (optional)
 */
function equals(expected, actual, message) {
	var result = expected == actual;
	message = message || result ? "okay" : "failed";
	_config.Test.push( [ result, result ? message + ": " + expected : message + " expected: " + expected + " actual: " + actual ] );
}
<|endoftext|>


<commit_before>// A ScrollBehaviorTest runs a set of ScrollBehaviorTestCases. The only
// ScrollBehaviorTest method that should be called by external code is run().

// Creates a ScrollBehaviorTest with arguments:
// scrollElement - Element being scrolled.
// scrollEventTarget - Target for scroll events for |scrollElement|.
// testsCases - Array of ScrollBehaviorTestCases.
// getEndPosition - Callback that takes a test case and start position, and
//                  returns the corresponding end position (where positions
//                  are dictionaries with x and y fields).
// jsScroll - Callback that takes a test case and executes the corresponding
//            js-driven scroll (e.g. by setting scrollLeft/scrollTop or by
//            calling scroll, scrollTo, or scrollBy). This should assume that
//            scrollElement's scroll-behavior CSS property has already been
//            set appropriately.
function ScrollBehaviorTest(scrollElement,
                            scrollEventTarget,
                            testCases,
                            getEndPosition,
                            jsScroll) {
    this.scrollElement = scrollElement;
    this.scrollEventTarget = scrollEventTarget;
    this.testCases = testCases;
    this.currentTestCase = 0;
    this.getEndPosition = getEndPosition;
    this.jsScroll = jsScroll;
}

ScrollBehaviorTest.prototype.scrollListener = function(testCase) {
    if (testCase.waitForEnd) {
        if (this.scrollElement.scrollLeft == testCase.endX && this.scrollElement.scrollTop == testCase.endY)
            this.testCaseComplete();
        return;
    }

    // Wait for an intermediate frame, then instant-scroll to the end state.
    if ((this.scrollElement.scrollLeft != testCase.startX || this.scrollElement.scrollTop != this.scrollElement.startY) &&
        (this.scrollElement.scrollLeft != testCase.endX || this.scrollElement.scrollTop != this.scrollElement.endY)) {
        this.scrollElement.scrollLeft = {x: testCase.endX, behavior: "instant"};
        this.scrollElement.scrollTop = {y: testCase.endY, behavior: "instant"};
        this.testCaseComplete();
    }
};

ScrollBehaviorTest.prototype.startNextTestCase = function() {
    if (this.currentTestCase >= this.testCases.length) {
        this.allTestCasesComplete();
        return;
    }

    var testCase = this.testCases[this.currentTestCase];
    var isSmoothTest = (testCase.js == "smooth" || (testCase.css == "smooth" && testCase.js != "instant"));

    this.asyncTest = async_test("Scroll x:" + testCase.x + ", y:" + testCase.y + ", smooth:" + isSmoothTest);

    var currentPosition = {};
    currentPosition.x = this.scrollElement.scrollLeft;
    currentPosition.y = this.scrollElement.scrollTop;
    var endPosition = this.getEndPosition(testCase, currentPosition);
    testCase.setStartPosition(currentPosition);
    testCase.setEndPosition(endPosition);

    this.scrollElement.style.scrollBehavior = testCase.css;
    this.jsScroll(testCase);

    var scrollElement = this.scrollElement;
    if (isSmoothTest) {
        this.asyncTest.step(function() {
            assert_equals(scrollElement.scrollLeft + ", " + scrollElement.scrollTop, testCase.startX + ", " + testCase.startY);
        });
        testCase.scrollListener = this.scrollListener.bind(this, testCase);
        this.scrollEventTarget.addEventListener("scroll", testCase.scrollListener);
    } else {
        this.asyncTest.step(function() {
            assert_equals(scrollElement.scrollLeft + ", " + scrollElement.scrollTop, testCase.endX + ", " + testCase.endY);
        });
        this.testCaseComplete();
    }
}

ScrollBehaviorTest.prototype.testCaseComplete = function() {
    var currentScrollListener = this.testCases[this.currentTestCase].scrollListener;
    if (currentScrollListener) {
        this.scrollEventTarget.removeEventListener("scroll", currentScrollListener);
    }
    this.asyncTest.done();

    this.currentTestCase++;
    this.startNextTestCase();
}

ScrollBehaviorTest.prototype.run = function() {
    setup({explicit_done: true});
    this.startNextTestCase();
}

ScrollBehaviorTest.prototype.allTestCasesComplete = function() {
    done();
}

// A ScrollBehaviorTestCase represents a single scroll.
//
// Creates a ScrollBehaviorTestCase. |testData| is a dictionary with fields:
// css - Value of scroll-behavior CSS property.
// js - (optional) Value of scroll behavior used in javascript.
// x, y - Coordinates to be used when carrying out the scroll.
// waitForEnd - (must be provided for smooth scrolls) Whether the test runner should
//              wait until the scroll is complete, rather than only waiting until
//              the scroll is underway.
function ScrollBehaviorTestCase(testData) {
    this.js = testData.js;
    this.css = testData.css;
    this.waitForEnd = testData.waitForEnd;
    this.x = testData.x;
    this.y = testData.y;
}

ScrollBehaviorTestCase.prototype.setStartPosition = function(startPosition) {
    this.startX = startPosition.x;
    this.startY = startPosition.y;
}

ScrollBehaviorTestCase.prototype.setEndPosition = function(endPosition) {
    this.endX = endPosition.x;
    this.endY = endPosition.y;
}
<commit_msg>Fix use of wrong variable in ScrollBehaviorTest<commit_after>// A ScrollBehaviorTest runs a set of ScrollBehaviorTestCases. The only
// ScrollBehaviorTest method that should be called by external code is run().

// Creates a ScrollBehaviorTest with arguments:
// scrollElement - Element being scrolled.
// scrollEventTarget - Target for scroll events for |scrollElement|.
// testsCases - Array of ScrollBehaviorTestCases.
// getEndPosition - Callback that takes a test case and start position, and
//                  returns the corresponding end position (where positions
//                  are dictionaries with x and y fields).
// jsScroll - Callback that takes a test case and executes the corresponding
//            js-driven scroll (e.g. by setting scrollLeft/scrollTop or by
//            calling scroll, scrollTo, or scrollBy). This should assume that
//            scrollElement's scroll-behavior CSS property has already been
//            set appropriately.
function ScrollBehaviorTest(scrollElement,
                            scrollEventTarget,
                            testCases,
                            getEndPosition,
                            jsScroll) {
    this.scrollElement = scrollElement;
    this.scrollEventTarget = scrollEventTarget;
    this.testCases = testCases;
    this.currentTestCase = 0;
    this.getEndPosition = getEndPosition;
    this.jsScroll = jsScroll;
}

ScrollBehaviorTest.prototype.scrollListener = function(testCase) {
    if (testCase.waitForEnd) {
        if (this.scrollElement.scrollLeft == testCase.endX && this.scrollElement.scrollTop == testCase.endY)
            this.testCaseComplete();
        return;
    }

    // Wait for an intermediate frame, then instant-scroll to the end state.
    if ((this.scrollElement.scrollLeft != testCase.startX || this.scrollElement.scrollTop != testCase.startY) &&
        (this.scrollElement.scrollLeft != testCase.endX || this.scrollElement.scrollTop != testCase.endY)) {
        this.scrollElement.scrollLeft = {x: testCase.endX, behavior: "instant"};
        this.scrollElement.scrollTop = {y: testCase.endY, behavior: "instant"};
        this.testCaseComplete();
    }
};

ScrollBehaviorTest.prototype.startNextTestCase = function() {
    if (this.currentTestCase >= this.testCases.length) {
        this.allTestCasesComplete();
        return;
    }

    var testCase = this.testCases[this.currentTestCase];
    var isSmoothTest = (testCase.js == "smooth" || (testCase.css == "smooth" && testCase.js != "instant"));

    this.asyncTest = async_test("Scroll x:" + testCase.x + ", y:" + testCase.y + ", smooth:" + isSmoothTest);

    var currentPosition = {};
    currentPosition.x = this.scrollElement.scrollLeft;
    currentPosition.y = this.scrollElement.scrollTop;
    var endPosition = this.getEndPosition(testCase, currentPosition);
    testCase.setStartPosition(currentPosition);
    testCase.setEndPosition(endPosition);

    this.scrollElement.style.scrollBehavior = testCase.css;
    this.jsScroll(testCase);

    var scrollElement = this.scrollElement;
    if (isSmoothTest) {
        this.asyncTest.step(function() {
            assert_equals(scrollElement.scrollLeft + ", " + scrollElement.scrollTop, testCase.startX + ", " + testCase.startY);
        });
        if (scrollElement.scrollLeft == testCase.endX && scrollElement.scrollTop == testCase.endY) {
            // We've instant-scrolled. This means we've already failed the assert above, and will never
            // reach an intermediate frame. End the test case now to avoid hanging while waiting for an
            // intermediate frame.
            this.testCaseComplete();
        } else {
            testCase.scrollListener = this.scrollListener.bind(this, testCase);
            this.scrollEventTarget.addEventListener("scroll", testCase.scrollListener);
        }
    } else {
        this.asyncTest.step(function() {
            assert_equals(scrollElement.scrollLeft + ", " + scrollElement.scrollTop, testCase.endX + ", " + testCase.endY);
        });
        this.testCaseComplete();
    }
}

ScrollBehaviorTest.prototype.testCaseComplete = function() {
    var currentScrollListener = this.testCases[this.currentTestCase].scrollListener;
    if (currentScrollListener) {
        this.scrollEventTarget.removeEventListener("scroll", currentScrollListener);
    }
    this.asyncTest.done();

    this.currentTestCase++;
    this.startNextTestCase();
}

ScrollBehaviorTest.prototype.run = function() {
    setup({explicit_done: true});
    this.startNextTestCase();
}

ScrollBehaviorTest.prototype.allTestCasesComplete = function() {
    done();
}

// A ScrollBehaviorTestCase represents a single scroll.
//
// Creates a ScrollBehaviorTestCase. |testData| is a dictionary with fields:
// css - Value of scroll-behavior CSS property.
// js - (optional) Value of scroll behavior used in javascript.
// x, y - Coordinates to be used when carrying out the scroll.
// waitForEnd - (must be provided for smooth scrolls) Whether the test runner should
//              wait until the scroll is complete, rather than only waiting until
//              the scroll is underway.
function ScrollBehaviorTestCase(testData) {
    this.js = testData.js;
    this.css = testData.css;
    this.waitForEnd = testData.waitForEnd;
    this.x = testData.x;
    this.y = testData.y;
}

ScrollBehaviorTestCase.prototype.setStartPosition = function(startPosition) {
    this.startX = startPosition.x;
    this.startY = startPosition.y;
}

ScrollBehaviorTestCase.prototype.setEndPosition = function(endPosition) {
    this.endX = endPosition.x;
    this.endY = endPosition.y;
}
<|endoftext|>


<commit_before>/**
 * This class offers an API-compatible replacement window.API for SCORM modules
 * to be used when apps are run in sandbox mode.
 *
 * For more information, see:
 * https://scorm.com/scorm-explained/technical-scorm/run-time/run-time-reference/
 */
import BaseShim from './baseShim';

const logger = console; //eslint-disable-line no-console

const TRUE = 'true';

const NO_ERROR = 0;

// Keys for which '_child' property is defined
// For simplicity, we just list the entire path here
// and the desired return value.
const childKeys = {
  'cmi.core._children':
    'student_id,student_name,lesson_location,credit,lesson_status,entry,score,total_time,lesson_mode,exit,session_time',
  'cmi.core.score._children': 'raw,min,max',
  'cmi.objectives._children': 'id,score,status',
  'cmi.student_data._children': '',
  'cmi.student_preference._children': 'language',
  'cmi.interactions._children':
    'id,objectives,time,type,correct_responses,weighting,student_response,result,latency',
};

// Keys for which '_count' property is defined
const countKeys = {
  correct_responses: 'correct_responses',
  interactions: 'interactions',
  objectives: 'objectives',
};

// Values which we will just return an empty value from
const emptyKeys = {
  'cmi.comments_from_lms': 'cmi.comments_from_lms',
  'cmi.launch_data': 'cmi.launch_data',
};

// Vendored and modified from
// https://github.com/dfahlander/Dexie.js/blob/2337c0fcb093219c07723f81363b806d203f5c8b/src/functions/utils.ts#L118

export function getByKeyPath(obj, keyPath) {
  // http://www.w3.org/TR/IndexedDB/#steps-for-extracting-a-key-from-a-value-using-a-key-path
  if (obj.hasOwnProperty(keyPath)) {
    return obj[keyPath]; // This line is moved from last to first for optimization purpose.
  }
  if (!keyPath) {
    return obj;
  }
  if (typeof keyPath !== 'string') {
    const rv = [];
    for (let i = 0, l = keyPath.length; i < l; ++i) {
      rv.push(getByKeyPath(obj, keyPath[i]));
    }
    return rv;
  }
  const period = keyPath.indexOf('.');
  if (period !== -1) {
    const leadingKeyPath = keyPath.substr(0, period);
    const innerObj = obj[leadingKeyPath];
    const innerKeyPath = keyPath.substr(period + 1);
    if (innerKeyPath === '_count' && countKeys[leadingKeyPath] && Array.isArray(obj)) {
      return obj.length;
    }
    return innerObj === undefined ? undefined : getByKeyPath(innerObj, innerKeyPath);
  }
  return undefined;
}

export function setByKeyPath(obj, keyPath, value) {
  if (!obj || keyPath === undefined) {
    return;
  }
  if ('isFrozen' in Object && Object.isFrozen(obj)) {
    return;
  }
  if (typeof keyPath !== 'string' && 'length' in keyPath) {
    for (let i = 0, l = keyPath.length; i < l; ++i) {
      setByKeyPath(obj, keyPath[i], value[i]);
    }
  } else {
    const period = keyPath.indexOf('.');
    if (period !== -1) {
      const currentKeyPath = keyPath.substr(0, period);
      const remainingKeyPath = keyPath.substr(period + 1);
      if (remainingKeyPath === '') {
        if (value === undefined) {
          if (Array.isArray(obj) && !isNaN(parseInt(currentKeyPath))) {
            obj.splice(currentKeyPath, 1);
          } else {
            delete obj[currentKeyPath];
          }
        } else {
          obj[currentKeyPath] = value;
        }
      } else {
        obj[currentKeyPath] = obj[currentKeyPath] || {};
        setByKeyPath(obj[currentKeyPath], remainingKeyPath, value);
      }
    } else {
      if (value === undefined) {
        if (Array.isArray(obj) && !isNaN(parseInt(keyPath))) {
          obj.splice(keyPath, 1);
        } else {
          delete obj[keyPath];
        }
      } else {
        obj[keyPath] = value;
      }
    }
  }
}

const userDataMap = {
  'cmi.core.student_id': function(userData) {
    return userData.userId || '';
  },
  'cmi.core.student_name': function(userData) {
    return userData.userFullName || '';
  },
  'cmi.core.entry': function(userData) {
    if (userData.progress) {
      return userData.progress < 1 ? 'resume' : '';
    }
    return 'ab-initio';
  },
  'cmi.core.lesson_mode': function(userData) {
    if (userData.userId) {
      return userData.complete ? 'review' : 'normal';
    }
    return 'browse';
  },
  'cmi.core.credit': function(userData) {
    return userData.userId ? 'credit' : 'no-credit';
  },
  'cmi.student_preference.language': function(userData) {
    return userData.language ? userData.language : '';
  },
  'cmi.core.total_time': function(userData) {
    return userData.timeSpent ? userData.timeSpent : 0;
  },
};

export default class SCORM extends BaseShim {
  constructor(mediator) {
    super(mediator);
    this.data = {};
    this.userData = {};
    this.nameSpace = 'SCORM';
    this.__setData = this.__setData.bind(this);
    this.__setUserData = this.__setUserData.bind(this);
    this.on(this.events.STATEUPDATE, this.__setData);
    this.on(this.events.USERDATAUPDATE, this.__setUserData);
  }

  __setData(data = {}) {
    this.data = data;
  }

  __setUserData(userData = {}) {
    this.userData = userData;
  }

  iframeInitialize() {
    this.__setShimInterface();
    // window.parent is our own shim, so we use regular assignment
    // here to play nicely with the Proxy we are using.
    try {
      window.parent.API = this.shim;
    } catch (e) {
      if (e instanceof DOMException) {
        // If this is a result of trying to touch a secure property
        // this will be a DOMException error. Catch and just return nothing.
        logger.warn(
          'Tried to setup the SCORM API in a sandboxed environment, it will not be enabled'
        );
        return;
      }
      throw e;
    }
  }

  __setShimInterface() {
    const self = this;

    class Shim {
      LMSInitialize() {
        logger.log('LMS Initialize called');
        return TRUE;
      }

      LMSFinish() {
        logger.log('LMS Finish called');
        return TRUE;
      }
      LMSSetValue(CMIElement, value) {
        setByKeyPath(self.data, CMIElement, value);
        logger.log(`LMSSetValue called with path: ${CMIElement} and value ${value}`);
        self.stateUpdated();
      }

      LMSGetValue(CMIElement) {
        logger.log(`LMSGetValue called with path: ${CMIElement}`);
        if (childKeys[CMIElement]) {
          return childKeys[CMIElement];
        }
        if (emptyKeys[CMIElement]) {
          return '';
        }
        return getByKeyPath(self.data, CMIElement);
      }

      LMSCommit() {
        logger.log('LMS Commit called');
      }

      LMSGetLastError() {
        return NO_ERROR;
      }

      LMSGetErrorString(errorCode) {
        logger.log(`LMS Get Error String called with code ${errorCode}`);
        return '';
      }

      LMSGetDiagnostic(errorCode) {
        logger.log(`LMS Get Diagnostic called with code ${errorCode}`);
        return '';
      }
    }
    this.shim = new Shim();

    return this.shim;
  }
}
<commit_msg>Implement SCORM more fully to spec in Hashi.<commit_after>/**
 * This class offers an API-compatible replacement window.API for SCORM modules
 * to be used when apps are run in sandbox mode.
 *
 * For more information, see:
 * https://scorm.com/scorm-explained/technical-scorm/run-time/run-time-reference/
 */
import BaseShim from './baseShim';

const logger = console; //eslint-disable-line no-console

const TRUE = 'true';

const FALSE = 'false';

const BLANK = '';

const ERRORS = {
  NO_ERROR: 0,
  GENERAL_EXCEPTION: 101,
  INVALID_ARGUMENT_ERROR: 201,
  ELEMENT_CANNOT_HAVE_CHILDREN: 202,
  ELEMENT_NOT_AN_ARRAY: 203,
  NOT_INITIALIZED: 301,
  NOT_IMPLEMENTED_ERROR: 401,
  ELEMENT_IS_KEYWORD: 402,
  ELEMENT_IS_READ_ONLY: 403,
  ELEMENT_IS_WRITE_ONLY: 404,
  INCORRECT_DATA_TYPE: 405,
};

const READ_WRITE = {
  // For reverse lookup purposes, these constants must match
  RO: 'RO',
  RW: 'RW',
  WO: 'WO',
};

const CMIDecimal = {
  validate(value) {
    return !isNaN(value);
  },
};

// Not clear whether the hours and minutes are optional, but setting them as so for safety.
/* eslint-disable max-len */
const timeSpanRegex = /(?:([0-9]{4}|[0-9]{2}):)?(?:([0-5][0-9]):)?([0-5][0-9](?:\.[0-9]{1,2})?)/;
/* eslint-enable */

const CMITimeSpan = {
  validate(value) {
    return timeSpanRegex.test(value);
  },
  convertFromSeconds(seconds) {
    const format = value => (value < 10 ? '0' + value : value);
    // Round seconds to two decimal places
    const s = Math.round((seconds % 60) * 100) / 100;
    const m = Math.floor((seconds % 3600) / 60);
    const h = Math.floor(seconds / 3600);
    // CMITimeSpan has a limit of 4 digits for hours, so return ''
    // here for safety if the number is too large
    if (h >= 10000) {
      return '';
    }
    return `${format(h)}:${format(m)}:${format(s)}`;
  },
};

// This is a 24 hour clock time, so requires all digits.
/* eslint-disable max-len */
const timeRegex = /((?:[0-1][0-9]|2[0-3])):([0-5][0-9]):([0-5][0-9](?:\.[0-9]{1,2})?)/;
/* eslint-enable */

const CMITime = {
  validate(value) {
    return timeRegex.test(value);
  },
};

const alphaNumeric = /[0-9a-z]/;

function singleAlphaNumeric(s) {
  return s.length === 1 && alphaNumeric.test(s);
}

const trueFalse = /[01tf]/;

const CMIFeedback = {
  validate(value, obj) {
    if (value === BLANK) {
      return true;
    } else if (!value) {
      return false;
    }
    // Coerce the value to a string for validation
    value = String(value);
    if (obj.type === 'true-false') {
      return trueFalse.test(value) && value.length === 1;
    }
    if (obj.type === 'choice') {
      if (value[0] === '{') {
        if (value[value.length - 1] === '}') {
          value = value.substring(1, value.length - 1);
        } else {
          return false;
        }
      }
      return value.split(',').every(singleAlphaNumeric);
    }
    if (obj.type === 'fill-in' || obj.type === 'performance') {
      if (value.length <= 255) {
        return true;
      }
      return false;
    }
    if (obj.type === 'numeric') {
      return CMIDecimal.validate(value);
    }
    if (obj.type === 'likert') {
      return alphaNumeric.test(String(value)) && value.length === 1;
    }
    if (obj.type === 'matching') {
      if (value[0] === '{') {
        if (value[value.length - 1] === '}') {
          value = value.substring(1, value.length - 1);
        } else {
          return false;
        }
      }
      return value.split(',').every(s => {
        return s.length === 3 && s.split('.').every(singleAlphaNumeric);
      });
    }
    if (obj.type === 'sequencing') {
      return value.split(',').every(singleAlphaNumeric);
    }
  },
};

const SCORE_SCHEMA = {
  hasChildren: true,
  raw: {
    type: CMIDecimal,
    readWrite: READ_WRITE.RW,
  },
  min: {
    type: CMIDecimal,
    readWrite: READ_WRITE.RW,
  },
  max: {
    type: CMIDecimal,
    readWrite: READ_WRITE.RW,
  },
};

const STATUS_SCHEMA = {
  readWrite: READ_WRITE.RW,
  values: {
    passed: 'passed',
    completed: 'completed',
    failed: 'failed',
    incomplete: 'incomplete',
    browsed: 'browsed',
    'not attempted': 'not attempted',
    '': '',
  },
};

const SCHEMA = {
  cmi: {
    hasChildren: true,
    core: {
      hasChildren: true,
      student_id: {
        fromUserData(userData) {
          return userData.userId || '';
        },
        readWrite: READ_WRITE.RO,
      },
      student_name: {
        fromUserData(userData) {
          return userData.userFullName || '';
        },
        readWrite: READ_WRITE.RO,
      },
      lesson_location: {
        readWrite: READ_WRITE.RW,
      },
      credit: {
        fromUserData(userData) {
          return userData.userId ? 'credit' : 'no-credit';
        },
        readWrite: READ_WRITE.RO,
      },
      lesson_status: STATUS_SCHEMA,
      entry: {
        fromUserData(userData) {
          if (userData.progress) {
            return userData.progress < 1 ? 'resume' : '';
          }
          return 'ab-initio';
        },
        readWrite: READ_WRITE.RO,
      },
      score: SCORE_SCHEMA,
      total_time: {
        type: CMITimeSpan,
        fromUserData(userData) {
          return CMITimeSpan.convertFromSeconds(userData.timeSpent ? userData.timeSpent : 0);
        },
        readWrite: READ_WRITE.RO,
      },
      lesson_mode: {
        fromUserData(userData) {
          if (userData.userId) {
            return userData.complete ? 'review' : 'normal';
          }
          return 'browse';
        },
        readWrite: READ_WRITE.RO,
      },
      exit: {
        readWrite: READ_WRITE.WO,
        values: {
          'time-out': 'time-out',
          suspend: 'suspend',
          logout: 'logout',
          '': '',
        },
      },
      session_time: {
        type: CMITimeSpan,
        readWrite: READ_WRITE.WO,
      },
    },
    launch_data: {
      readWrite: READ_WRITE.RO,
    },
    comments: {
      readWrite: READ_WRITE.RW,
    },
    comments_from_lms: {
      readWrite: READ_WRITE.RO,
    },
    objectives: {
      hasChildren: true,
      arraySchema: {
        id: {
          readWrite: READ_WRITE.RW,
        },
        score: SCORE_SCHEMA,
        status: STATUS_SCHEMA,
      },
    },
    // We don't currently support any of the student_data subkeys
    student_data: {
      hasChildren: true,
      mastery_score: {
        notImplemented: true,
        readWrite: READ_WRITE.RO,
      },
      max_time_allowed: {
        notImplemented: true,
        readWrite: READ_WRITE.RO,
      },
      time_limit_action: {
        notImplemented: true,
        readWrite: READ_WRITE.RO,
      },
    },
    student_preference: {
      hasChildren: true,
      language: {
        fromUserData(userData) {
          return userData.language ? userData.language : '';
        },
        readWrite: READ_WRITE.RW,
      },
      audio: {
        notImplemented: true,
        readWrite: READ_WRITE.RW,
      },
      speed: {
        notImplemented: true,
        readWrite: READ_WRITE.RW,
      },
      text: {
        notImplemented: true,
        readWrite: READ_WRITE.RW,
      },
    },
    interactions: {
      hasChildren: true,
      arraySchema: {
        id: {
          readWrite: READ_WRITE.RW,
        },
        objectives: {
          arraySchema: {
            id: {
              readWrite: READ_WRITE.WO,
            },
          },
        },
        time: {
          type: CMITime,
          readWrite: READ_WRITE.WO,
        },
        type: {
          readWrite: READ_WRITE.WO,
          values: {
            'true-false': 'true-false',
            choice: 'choice',
            'fill-in': 'fill-in',
            matching: 'matching',
            performance: 'performance',
            sequencing: 'sequencing',
            likert: 'likert',
            numeric: 'numeric',
            '': '',
          },
        },
        correct_responses: {
          arraySchema: {
            pattern: {
              readWrite: READ_WRITE.WO,
            },
          },
        },
        weighting: {
          type: CMIDecimal,
          readWrite: READ_WRITE.WO,
        },
        student_response: {
          type: CMIFeedback,
          readWrite: READ_WRITE.WO,
        },
        result: {
          readWrite: READ_WRITE.WO,
          validate(value) {
            const values = {
              correct: 'correct',
              wrong: 'wrong',
              unanticipated: 'unanticipated',
              neutral: 'neutral',
              '': '',
            };
            return CMIDecimal.validate(value) || values[value];
          },
        },
        latency: {
          readWrite: READ_WRITE.WO,
          type: CMITimeSpan,
        },
      },
    },
  },
};

const SCORM_ERROR_NAME = 'SCORMError';

function throwError(errorCode) {
  const error = TypeError(errorCode);
  error.name = SCORM_ERROR_NAME;
  throw error;
}

// Vendored and modified from
// https://github.com/dfahlander/Dexie.js/blob/2337c0fcb093219c07723f81363b806d203f5c8b/src/functions/utils.ts#L118

export function getByKeyPath(obj, keyPath, localSchema, userData) {
  // If a keyPath is empty, if no schema exists for it, or if it is not a string
  // throw an invalid argument error.
  if (!keyPath || !localSchema || typeof keyPath !== 'string') {
    throwError(ERRORS.INVALID_ARGUMENT_ERROR);
  }
  // If we are trying to read from a write only property, throw an error
  if (localSchema[keyPath] && localSchema[keyPath].readWrite === READ_WRITE.WO) {
    throwError(ERRORS.ELEMENT_IS_WRITE_ONLY);
  }
  // If we have defined how this is derived from user data that is fed in from
  // Kolibri, then return this value instead of looking for it in our data object.
  if (localSchema[keyPath] && localSchema[keyPath].fromUserData) {
    return localSchema[keyPath].fromUserData(userData);
  }
  // http://www.w3.org/TR/IndexedDB/#steps-for-extracting-a-key-from-a-value-using-a-key-path
  // This works for getting values from Objects by key and from Arrays by index
  if (obj && obj.hasOwnProperty(keyPath)) {
    return obj[keyPath];
  }
  const period = keyPath.indexOf('.');
  // If there is a separator still in the keyPath
  if (period !== -1) {
    const leadingKeyPath = keyPath.substr(0, period);
    const innerObj = obj ? obj[leadingKeyPath] : obj;
    const innerKeyPath = keyPath.substr(period + 1);
    let innerSchema = localSchema[leadingKeyPath];
    if (innerSchema && innerSchema.arraySchema) {
      // If the inner schema is for an array, pass
      // the arraySchema instead
      innerSchema = innerSchema.arraySchema;
    } else if (!isNaN(leadingKeyPath)) {
      // If the path is indexing into an array,
      // we keep the array schema from the parent
      innerSchema = localSchema;
    }
    if (innerKeyPath === '_count') {
      // If the inner key is requesting a count, we check that we have a valid schema
      // for the keyPath up until this point, and check that this is for an array in the schema
      if (localSchema[leadingKeyPath] && localSchema[leadingKeyPath].arraySchema) {
        // It is, so first we check if the data object has an array
        if (Array.isArray(innerObj)) {
          // If so, return this array's length
          return innerObj.length;
        } else {
          // If not, it is effectively a zero length array
          return 0;
        }
      } else {
        // Otherwise, they tried to get the length of an element that is not an array in the
        // schema - throw the appropriate error.
        throwError(ERRORS.ELEMENT_NOT_AN_ARRAY);
      }
    }
    if (innerKeyPath === '_children') {
      // If the inner key is requesting the children, check to see that we have a valid schema
      // for the keyPath up until this point, and check that this has children
      if (localSchema[leadingKeyPath] && localSchema[leadingKeyPath].hasChildren) {
        // If so, return the child keys of the appropriate inner schema (by using innerSchema
        // we can expose the children of array properties as well).
        return (
          Object.keys(innerSchema)
            // Filter out the `hasChildren` key which is our own special marker.
            // Also filter out keys that we have not implemented yet.
            .filter(key => key !== 'hasChildren' && !innerSchema[key].notImplemented)
            .join(',')
        );
      } else {
        // Otherwise, they tried to get the children of a property that does not allow it
        // throw the appropriate error.
        throwError(ERRORS.ELEMENT_CANNOT_HAVE_CHILDREN);
      }
    }
    // Recurse further to get the data we are after.
    return getByKeyPath(innerObj, innerKeyPath, innerSchema, userData);
  }
  // If we have got to this point, we do not a representation of the relevant
  // keyPath in the object, and we have finished recursing through the keyPath
  // Check if the remaining keyPath is in the schema at all and if we support it
  if (localSchema[keyPath] && !localSchema[keyPath].notImplemented) {
    // If so, just return a blank response, which is always valid.
    return BLANK;
  } else if (localSchema[keyPath] && localSchema[keyPath].notImplemented) {
    // If it is in the schema but not implemented, return the appropriate error
    throwError(ERRORS.NOT_IMPLEMENTED_ERROR);
  }
  // Otherwise, this is not a valid argument, so throw here.
  throwError(ERRORS.INVALID_ARGUMENT_ERROR);
}

export function setByKeyPath(obj, keyPath, value, localSchema) {
  // Can't set blank keyPaths on non-existent schemas that are not strings!
  if (!keyPath || !localSchema || typeof keyPath !== 'string') {
    throwError(ERRORS.INVALID_ARGUMENT_ERROR);
  }
  // Check to see if we still need to recurse the keyPath
  const period = keyPath.indexOf('.');
  if (period !== -1) {
    // If so, get the first part of the keyPath before the first separator
    const leadingKeyPath = keyPath.substr(0, period);
    // Get the remainder of the keyPath after the first separator
    const innerKeyPath = keyPath.substr(period + 1);
    // Try getting the relevant subsection of the schema for this subsection
    // of the keyPath
    let innerSchema = localSchema[leadingKeyPath];
    if (innerSchema && innerSchema.arraySchema) {
      // If the inner schema is for an array, pass
      // the arraySchema instead
      innerSchema = innerSchema.arraySchema;
      // Set the inner object to an Array here, to prevent it
      // being set to an object later:
      obj[leadingKeyPath] = obj[leadingKeyPath] || [];
    } else if (!isNaN(leadingKeyPath)) {
      // If the path is indexing into an array,
      // we keep the array schema from the parent
      innerSchema = localSchema;
    }
    // If the remaining key path we are after is either for a count or children
    // we can raise an error here, as we are not allowed to set these.
    if (innerKeyPath === '_count' || innerKeyPath === '_children') {
      throwError(ERRORS.ELEMENT_IS_KEYWORD);
    }
    // In case we have not set any data in this part of the object before,
    // initialize the key to a blank object if not already initialized.
    obj[leadingKeyPath] = obj[leadingKeyPath] || {};
    // Recurse the key path setting!
    setByKeyPath(obj[leadingKeyPath], innerKeyPath, value, innerSchema);
  } else {
    const innerSchema = localSchema[keyPath];
    // If we are trying to write to a read only property, throw an error
    if (innerSchema && innerSchema.readWrite === READ_WRITE.RO) {
      throwError(ERRORS.ELEMENT_IS_READ_ONLY);
    }
    // If we are trying to write to a property we have not implemented, throw an error
    if (innerSchema && innerSchema.notImplemented) {
      throwError(ERRORS.NOT_IMPLEMENTED_ERROR);
    }
    // If we are trying to write to a property that does not exist on the schema, throw an error
    if (!innerSchema) {
      throwError(ERRORS.INVALID_ARGUMENT_ERROR);
    }
    // Conduct validation based on the schema we have inferred.
    if (
      // First check if we have a defined type and run validation against it
      (innerSchema.type && !innerSchema.type.validate(value, obj)) ||
      // If there is a directly defined validation function on the schema,
      // check that
      (innerSchema.validate && !innerSchema.validate(value, obj)) ||
      // If the schema defines a set of allowed values, check that it is
      // included.
      (innerSchema.values && !innerSchema.values[value]) ||
      // Otherwise, if there is no defined type and nothing else is set for
      // validation, just check that the value is valid as a string.
      // Note: explicitly using double equals here instead of triple equals
      // to check that we have a coerceable type (so exclude undefined, null, and functions)
      (!innerSchema.type && String(value) == value)
    ) {
      throwError(ERRORS.INCORRECT_DATA_TYPE);
    }
    // If we've got this far, we can set the value!
    obj[keyPath] = value;
  }
}

export default class SCORM extends BaseShim {
  constructor(mediator) {
    super(mediator);
    this.data = {};
    this.userData = {};
    this.nameSpace = 'SCORM';
    this.__setData = this.__setData.bind(this);
    this.__setUserData = this.__setUserData.bind(this);
    this.on(this.events.STATEUPDATE, this.__setData);
    this.on(this.events.USERDATAUPDATE, this.__setUserData);
  }

  __setData(data = {}) {
    this.data = data;
  }

  __setUserData(userData = {}) {
    this.userData = userData;
  }

  iframeInitialize() {
    this.__setShimInterface();
    // window.parent is our own shim, so we use regular assignment
    // here to play nicely with the Proxy we are using.
    try {
      window.parent.API = this.shim;
    } catch (e) {
      if (e instanceof DOMException) {
        // If this is a result of trying to touch a secure property
        // this will be a DOMException error. Catch and just return nothing.
        logger.warn(
          'Tried to setup the SCORM API in a sandboxed environment, it will not be enabled'
        );
        return;
      }
      throw e;
    }
  }

  __setShimInterface() {
    const self = this;

    let error = ERRORS.NO_ERROR;

    class Shim {
      LMSInitialize() {
        logger.debug('LMS Initialize called');
        return TRUE;
      }

      LMSFinish() {
        logger.debug('LMS Finish called');
        return TRUE;
      }
      LMSSetValue(CMIElement, value) {
        error = ERRORS.NO_ERROR;
        logger.debug(`LMSSetValue called with path: ${CMIElement} and value ${value}`);
        try {
          setByKeyPath(self.data, CMIElement, value, SCHEMA);
        } catch (e) {
          if (e instanceof TypeError && e.name === SCORM_ERROR_NAME) {
            error = e.message;
            return FALSE;
          }
          throw e;
        }
        self.stateUpdated();
        return TRUE;
      }

      LMSGetValue(CMIElement) {
        error = ERRORS.NO_ERROR;
        logger.debug(`LMSGetValue called with path: ${CMIElement}`);
        try {
          return getByKeyPath(self.data, CMIElement, SCHEMA, self.userData);
        } catch (e) {
          if (e instanceof TypeError && e.name === SCORM_ERROR_NAME) {
            error = e.message;
            return '';
          }
          throw e;
        }
      }

      LMSCommit() {
        error = ERRORS.NO_ERROR;
        logger.debug('LMS Commit called');
      }

      LMSGetLastError() {
        return error;
      }

      LMSGetErrorString(errorCode) {
        logger.debug(`LMS Get Error String called with code ${errorCode}`);
        return '';
      }

      LMSGetDiagnostic(errorCode) {
        logger.debug(`LMS Get Diagnostic called with code ${errorCode}`);
        return '';
      }
    }
    this.shim = new Shim();

    return this.shim;
  }
}
<|endoftext|>


<commit_before>(function () {
    var partyCounts = [{"name": "KrF", "count": "16", "innlegg": "5356"}, {"name": "A", "count": "17", "innlegg": "10195"}, {"name": "Sp", "count": "7", "innlegg": "4218"}, {"name": "V", "count": "5", "innlegg": "3335"}, {"name": "SV", "count": "5", "innlegg": "4784"}, {"name": "FrP", "count": "9", "innlegg": "10322"}, {"name": "H", "count": "8", "innlegg": "9688"}, {"name": "MDG", "count": "0", "innlegg": "182"}];
    var repCounts = [{"name": "Jens Stoltenberg (A)", "count": "16", "innlegg": "907"}, {"name": "Knut Arild Hareide (KrF)", "count": "5", "innlegg": "433"}, {"name": "Torgeir Micaelsen (A)", "count": "2", "innlegg": "183"}, {"name": "Hans Olav Syversen (KrF)", "count": "6", "innlegg": "630"}, {"name": "Snorre Serigstad Valen (SV)", "count": "3", "innlegg": "318"}, {"name": "Dagfinn Høybråten (KrF)", "count": "3", "innlegg": "360"}, {"name": "Abid Q. Raja (V)", "count": "2", "innlegg": "241"}, {"name": "Per Olaf Lundteigen (Sp)", "count": "4", "innlegg": "636"}, {"name": "Jonas Gahr Støre (A)", "count": "4", "innlegg": "791"}];

    function cleanCounts(data) {
        data.forEach(function (d) {
            d.count = +d.count;
            d.innlegg = +d.innlegg;
            d.score = d.count / d.innlegg;
        });
    }

    cleanCounts(partyCounts);
    cleanCounts(repCounts);

    function drawTopList(selector, data) {
        var cols = [];

        cols.push(['x'].concat(data.map(function (d) { return d.name; })));
        cols.push(['Score'].concat(data.map(function (d) { return d.score; })));

        var chart = c3.generate({
            bindto: selector,
            data: {
                x: 'x',
                columns: cols,
                type: 'bar'
            },
            transition: { duration: 0 },
            axis: {
                x: { type: 'category', tick: { multiline: false } },
                rotated: true
            },
            color: { pattern: ["#e0c600"] }
        });
    }

    drawTopList('.om-munterhet-representative-chart', repCounts);
    drawTopList('.om-munterhet-party-chart', partyCounts);
}());<commit_msg>Change color.<commit_after>(function () {
    var partyCounts = [{"name": "KrF", "count": "16", "innlegg": "5356"}, {"name": "A", "count": "17", "innlegg": "10195"}, {"name": "Sp", "count": "7", "innlegg": "4218"}, {"name": "V", "count": "5", "innlegg": "3335"}, {"name": "SV", "count": "5", "innlegg": "4784"}, {"name": "FrP", "count": "9", "innlegg": "10322"}, {"name": "H", "count": "8", "innlegg": "9688"}, {"name": "MDG", "count": "0", "innlegg": "182"}];
    var repCounts = [{"name": "Jens Stoltenberg (A)", "count": "16", "innlegg": "907"}, {"name": "Knut Arild Hareide (KrF)", "count": "5", "innlegg": "433"}, {"name": "Torgeir Micaelsen (A)", "count": "2", "innlegg": "183"}, {"name": "Hans Olav Syversen (KrF)", "count": "6", "innlegg": "630"}, {"name": "Snorre Serigstad Valen (SV)", "count": "3", "innlegg": "318"}, {"name": "Dagfinn Høybråten (KrF)", "count": "3", "innlegg": "360"}, {"name": "Abid Q. Raja (V)", "count": "2", "innlegg": "241"}, {"name": "Per Olaf Lundteigen (Sp)", "count": "4", "innlegg": "636"}, {"name": "Jonas Gahr Støre (A)", "count": "4", "innlegg": "791"}];

    function cleanCounts(data) {
        data.forEach(function (d) {
            d.count = +d.count;
            d.innlegg = +d.innlegg;
            d.score = d.count / d.innlegg;
        });
    }

    cleanCounts(partyCounts);
    cleanCounts(repCounts);

    function drawTopList(selector, data) {
        var cols = [];

        cols.push(['x'].concat(data.map(function (d) { return d.name; })));
        cols.push(['Score'].concat(data.map(function (d) { return d.score; })));

        var chart = c3.generate({
            bindto: selector,
            data: {
                x: 'x',
                columns: cols,
                type: 'bar'
            },
            transition: { duration: 0 },
            axis: {
                x: { type: 'category', tick: { multiline: false } },
                rotated: true
            },
            color: { pattern: ["#606b82"] }
        });
    }

    drawTopList('.om-munterhet-representative-chart', repCounts);
    drawTopList('.om-munterhet-party-chart', partyCounts);
}());
<|endoftext|>


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

const jwt = require('jsonwebtoken');
const User = require('../models/User');
const { getConnection } = require('../db');

/** Checks if a role has the authorization capabilities as the requested role. */
function isRoleAuthorized(role, requestedRole) {
	if (role === User.role.ADMIN) {
		return true;
	} else {
		return role === requestedRole;
	}
}

/** Checks if a token (assumed to be verified) has the authorization capabilities as the requested role. */
async function isTokenAuthorized(token, requestedRole) {
	const payload = jwt.decode(token);
	const { data: id } = payload;
	const conn = getConnection();
	const { role } = await User.getByID(id, conn);
	return isRoleAuthorized(role, requestedRole);
}

/** Checks if a user is authorized. */
/**
 *
 * @param {User} user
 * @param requestedRole
 */
function isUserAuthorized(user, requestedRole) {
	return isRoleAuthorized(user.role, requestedRole);
}

module.exports = {
	isUserAuthorized,
	isTokenAuthorized
}<commit_msg>Promisify jwt#verify<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const jwt = require('jsonwebtoken');
const User = require('../models/User');
const promisify = require('es6-promisify');
const jwtVerify = promisify(jwt.verify);
const { getConnection } = require('../db');
const secretToken = require('../config').secretToken;

/** Checks if a role has the authorization capabilities as the requested role. */
function isRoleAuthorized(role, requestedRole) {
	if (role === User.role.ADMIN) {
		return true;
	} else {
		return role === requestedRole;
	}
}

/** Checks if a token (assumed to be verified) has the authorization capabilities as the requested role. */
async function isTokenAuthorized(token, requestedRole) {
	const payload = await jwtVerify(token, secretToken);
	const { data: id } = payload;
	const conn = getConnection();
	const { role } = await User.getByID(id, conn);
	return isRoleAuthorized(role, requestedRole);
}

/** Checks if a user is authorized. */
/**
 *
 * @param {User} user
 * @param requestedRole
 */
function isUserAuthorized(user, requestedRole) {
	return isRoleAuthorized(user.role, requestedRole);
}

module.exports = {
	isUserAuthorized,
	isTokenAuthorized
}<|endoftext|>


<commit_before>var creep_farMining = {

	/** @param {Creep} creep **/
	run: function(creep) {
		if (creep.memory.priority == 'farClaimer' || creep.memory.priority == 'farClaimerNearDeath') {
			if (creep.ticksToLive <= 20) {
				creep.memory.priority == 'farClaimerNearDeath';
				creep.room.visual.text("\u2620\u27A1\uD83D\uDEA9", creep.pos.x, creep.pos.y, {
					align: 'left',
					color: '#7DE3B5'
				});
			} else {
				creep.room.visual.text("\u27A1\uD83D\uDEA9", creep.pos.x, creep.pos.y, {
					align: 'left',
					color: '#7DE3B5'
				});
			}

			if (creep.room.name != creep.memory.destination) {
				creep.moveTo(new RoomPosition(25, 25, creep.memory.destination));
			} else {
				if (creep.room.controller.reservation && (creep.room.name == creep.memory.destination)) {
					if (creep.room.controller.reservation.ticksToEnd <= 1000) {
						Memory.FarClaimerNeeded[creep.room.name] = true;
					} else {
						Memory.FarClaimerNeeded[creep.room.name] = false;
					}
				} else if (creep.room.name == creep.memory.destination) {
					Memory.FarClaimerNeeded[creep.room.name] = true;
				}

				if (creep.reserveController(creep.room.controller) == ERR_NOT_IN_RANGE) {
					creep.moveTo(creep.room.controller, {
						reusePath: 25
					});
				}
			}
		} else if (creep.memory.priority == 'farMiner' || creep.memory.priority == 'farMinerNearDeath') {
			if (creep.ticksToLive <= 60) {
				creep.memory.priority == 'farMinerNearDeath';
				creep.room.visual.text("\u2620\u27A1\u26CF", creep.pos.x, creep.pos.y, {
					align: 'left',
					color: '#7DE3B5'
				});
			} else {
				creep.room.visual.text("\u27A1\u26CF", creep.pos.x, creep.pos.y, {
					align: 'left',
					color: '#7DE3B5'
				});
			}

			if (creep.room.name != creep.memory.destination) {
				creep.moveTo(new RoomPosition(25, 25, creep.memory.destination), {
					reusePath: 25
				});
			} else {
				if (creep.room.controller.reservation && (creep.room.name == creep.memory.destination)) {
					if (creep.room.controller.reservation.ticksToEnd <= 1000) {
						Memory.FarClaimerNeeded[creep.room.name] = true;
					} else {
						Memory.FarClaimerNeeded[creep.room.name] = false;
					}
				} else if (creep.room.name == creep.memory.destination) {
					Memory.FarClaimerNeeded[creep.room.name] = true;
				}

				var mineTarget = "";

				if (creep.memory.mineSource) {
					mineTarget = Game.getObjectById(creep.memory.mineSource);
					if (mineTarget && _.sum(creep.carry) <= 35) {
						if (creep.harvest(mineTarget) == ERR_NOT_IN_RANGE) {
							creep.moveTo(mineTarget, {
								reusePath: 25
							});
						}
					}
				} else {
					//Get the source ID while in the room
					var markedSources = [];
					if (Game.flags[creep.memory.targetFlag]) {
						markedSources = Game.flags[creep.memory.targetFlag].pos.lookFor(LOOK_SOURCES);
					}
					if (markedSources.length) {
						creep.memory.mineSource = markedSources[0].id;
					}
					mineTarget = Game.getObjectById(creep.memory.mineSource);
					if (mineTarget) {
						if (creep.harvest(mineTarget) == ERR_NOT_IN_RANGE) {
							creep.moveTo(mineTarget, {
								reusePath: 25
							});
						}
					}
				}

				if (creep.memory.storageUnit) {
					var thisUnit = Game.getObjectById(creep.memory.storageUnit);
					if (thisUnit) {
						if (thisUnit.hits < thisUnit.hitsMax) {
							creep.repair(thisUnit);
						} else {
							if (creep.transfer(thisUnit, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
								creep.moveTo(thisUnit, {
									reusePath: 25
								});
							}
						}
					}
				} else {
					if (mineTarget) {
						if (creep.pos.inRangeTo(mineTarget, 5)) {
							var containers = creep.pos.findInRange(FIND_STRUCTURES, 5, {
								filter: (structure) => structure.structureType == STRUCTURE_CONTAINER
							});
							if (containers.length) {
								if (creep.transfer(containers[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
									creep.moveTo(containers[0], {
										reusePath: 25
									});
								}
								creep.memory.storageUnit = containers[0].id;
							} else {
								var sites = creep.pos.findInRange(FIND_CONSTRUCTION_SITES, 5)
								if (sites.length) {
									if (creep.build(sites[0]) == ERR_NOT_IN_RANGE) {
										creep.moveTo(sites[0], {
											reusePath: 25
										});
									}
								} else {
									//Create new container
									if (creep.pos.isNearTo(mineTarget)) {
										creep.room.createConstructionSite(creep.pos, STRUCTURE_CONTAINER)
									}
								}
							}
						}
					}
				}
			}
		} else if (creep.memory.priority == 'farMule' || creep.memory.priority == 'farMuleNearDeath') {
			if (creep.ticksToLive <= 170) {
				creep.memory.priority = 'farMuleNearDeath';
				creep.room.visual.text("\u2620\u27A1\uD83D\uDC02", creep.pos.x, creep.pos.y, {
					align: 'left',
					color: '#7DE3B5'
				});
			} else {
				creep.room.visual.text("\u27A1\uD83D\uDC02", creep.pos.x, creep.pos.y, {
					align: 'left',
					color: '#7DE3B5'
				});
			}

			if (creep.room.name != creep.memory.destination && _.sum(creep.carry) <= 600) {
				var droppedSources = creep.pos.findInRange(FIND_DROPPED_ENERGY, 3);
				if (droppedSources.length) {
					//Pick up dropped energy from dead mules, etc.
					if (creep.pickup(droppedSources[0]) == ERR_NOT_IN_RANGE) {
						creep.moveTo(droppedSources[0], {
							reusePath: 25
						});
					}
				} else {
					creep.moveTo(new RoomPosition(25, 25, creep.memory.destination), {
						reusePath: 25
					});
				}
			} else if (creep.room.name != creep.memory.homeRoom && _.sum(creep.carry) > 600) {
				creep.moveTo(new RoomPosition(25, 25, creep.memory.homeRoom), {
					reusePath: 25
				});
			} else {
				if (creep.room.controller.reservation && (creep.room.name == creep.memory.destination)) {
					if (creep.room.controller.reservation.ticksToEnd <= 1000) {
						Memory.FarClaimerNeeded[creep.room.name] = true;
					} else {
						Memory.FarClaimerNeeded[creep.room.name] = false;
					}
				} else if (creep.room.name == creep.memory.destination) {
					Memory.FarClaimerNeeded[creep.room.name] = true;
				}

				if (_.sum(creep.carry) <= 600) {
					var droppedSources = creep.pos.findInRange(FIND_DROPPED_ENERGY, 10);
					if (droppedSources.length) {
						//Pick up dropped energy from dead mules, etc.
						if (creep.pickup(droppedSources[0]) == ERR_NOT_IN_RANGE) {
							creep.moveTo(droppedSources[0], {
								reusePath: 25
							});
						}
					} else {
						//in farRoom, pick up container contents
						if (creep.memory.containerTarget) {
							var thisContainer = Game.getObjectById(creep.memory.containerTarget);
							if (thisContainer) {
								if (thisContainer.store[RESOURCE_ENERGY] > 0) {
									if (creep.withdraw(thisContainer, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
										creep.moveTo(thisContainer, {
											reusePath: 25,
											ignoreRoads: true
										});
									}
								} else {
									//Wait by controller
									creep.moveTo(creep.room.controller);
								}

							}
						} else {
							//No container yet, move to be near source
							if (!creep.memory.mineSource) {
								var markedSources = [];
								if (Game.flags[creep.memory.targetFlag]) {
									markedSources = Game.flags[creep.memory.targetFlag].pos.lookFor(LOOK_SOURCES);
								}
								if (markedSources.length) {
									creep.memory.mineSource = markedSources[0].id;
								}
							}

							var thisSource = Game.getObjectById(creep.memory.mineSource);
							if (thisSource) {
								creep.moveTo(thisSource, {
									reusePath: 25,
									ignoreRoads: true
								});
								if (creep.pos.inRangeTo(thisSource, 5)) {
									//Search for container
									var containers = creep.pos.findInRange(FIND_STRUCTURES, 5, {
										filter: (structure) => structure.structureType == STRUCTURE_CONTAINER
									});
									if (containers.length) {
										creep.memory.containerTarget = containers[0].id;
										if (creep.withdraw(containers[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
											creep.moveTo(containers[0], {
												reusePath: 25,
												ignoreRoads: true
											});
										}
									}
								}
							}
						}
					}
				} else {
					//in home room, drop off energy
					var storageUnit = Game.getObjectById(creep.memory.storageSource)
					if (storageUnit) {
						if (creep.transfer(storageUnit, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
							creep.moveTo(storageUnit, {
								reusePath: 25,
								ignoreRoads: true
							});
						}
					}
				}
			}
		} else if (creep.memory.priority == 'farGuard' || creep.memory.priority == 'farGuardNearDeath') {
			creep.notifyWhenAttacked(false);
			if (creep.ticksToLive <= 70) {
				creep.memory.priority == 'farGuardNearDeath';
				creep.room.visual.text("\u2620\u27A1\u2694", creep.pos.x, creep.pos.y, {
					align: 'left',
					color: '#7DE3B5'
				});
			} else {
				creep.room.visual.text("\u27A1\u2694", creep.pos.x, creep.pos.y, {
					align: 'left',
					color: '#7DE3B5'
				});
			}

			if (creep.hits < creep.hitsMax) {
				creep.heal(creep);
			}

			if (creep.room.controller.reservation && (creep.room.name == creep.memory.destination)) {
				if (creep.room.controller.reservation.ticksToEnd <= 1000) {
					Memory.FarClaimerNeeded[creep.room.name] = true;
				} else {
					Memory.FarClaimerNeeded[creep.room.name] = false;
				}
			} else if (creep.room.name == creep.memory.destination) {
				Memory.FarClaimerNeeded[creep.room.name] = true;
			}

			var Foe = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS);

			if (creep.room.controller.owner && creep.room.controller.owner.username != "Montblanc" && creep.room.name != creep.memory.destination) {
				creep.moveTo(new RoomPosition(25, 25, creep.memory.destination), {
					reusePath: 25
				});
			} else if (Foe) {
				if (creep.pos.getRangeTo(Foe) > 3 || (Foe.getActiveBodyparts(ATTACK) == 0) || (creep.getActiveBodyparts(RANGED_ATTACK) == 0)) {
					creep.moveTo(Foe, {
							maxRooms = 1
						});
					creep.attack(Foe);
					creep.rangedAttack(Foe);
				} else {
					var foeDirection = creep.pos.getDirectionTo(Foe);
					var evadeDirection = TOP;
					switch (foeDirection) {
						case TOP:
							evadeDirection = BOTTOM;
							break;
						case TOP_RIGHT:
							evadeDirection = BOTTOM_LEFT;
							break;
						case RIGHT:
							evadeDirection = LEFT;
							break;
						case BOTTOM_RIGHT:
							evadeDirection = TOP_LEFT;
							break;
						case BOTTOM:
							evadeDirection = TOP;
							break;
						case BOTTOM_LEFT:
							evadeDirection = TOP_RIGHT;
							break;
						case LEFT:
							evadeDirection = RIGHT;
							break;
						case TOP_LEFT:
							evadeDirection = BOTTOM_RIGHT;
							break;
					}
					creep.move(evadeDirection);
					creep.attack(Foe);
					creep.rangedAttack(Foe);
				}
			} else if (creep.room.controller.owner && creep.room.controller.owner.username != "Montblanc") {
				var hSpawn = creep.pos.findClosestByRange(FIND_HOSTILE_SPAWNS);
				if (hSpawn) {
					creep.moveTo(hSpawn);
					creep.attack(hSpawn);
					creep.rangedAttack(hSpawn);
				} else {
					try {
						creep.moveTo(Game.flags[creep.memory.targetFlag].pos);
					} catch (e) {
						//Eat it
					}
				}
			} else if (creep.room.name != creep.memory.destination) {
				creep.moveTo(new RoomPosition(25, 25, creep.memory.destination), {
					reusePath: 25
				});
			} else if (Game.flags[creep.memory.targetFlag]) {
				if (creep.pos != Game.flags[creep.memory.targetFlag].pos) {
					creep.moveTo(Game.flags[creep.memory.targetFlag]);
				}
			}
		}
	}
};
module.exports = creep_farMining;<commit_msg>TYPOOOOOOOOOO<commit_after>var creep_farMining = {

	/** @param {Creep} creep **/
	run: function(creep) {
		if (creep.memory.priority == 'farClaimer' || creep.memory.priority == 'farClaimerNearDeath') {
			if (creep.ticksToLive <= 20) {
				creep.memory.priority == 'farClaimerNearDeath';
				creep.room.visual.text("\u2620\u27A1\uD83D\uDEA9", creep.pos.x, creep.pos.y, {
					align: 'left',
					color: '#7DE3B5'
				});
			} else {
				creep.room.visual.text("\u27A1\uD83D\uDEA9", creep.pos.x, creep.pos.y, {
					align: 'left',
					color: '#7DE3B5'
				});
			}

			if (creep.room.name != creep.memory.destination) {
				creep.moveTo(new RoomPosition(25, 25, creep.memory.destination));
			} else {
				if (creep.room.controller.reservation && (creep.room.name == creep.memory.destination)) {
					if (creep.room.controller.reservation.ticksToEnd <= 1000) {
						Memory.FarClaimerNeeded[creep.room.name] = true;
					} else {
						Memory.FarClaimerNeeded[creep.room.name] = false;
					}
				} else if (creep.room.name == creep.memory.destination) {
					Memory.FarClaimerNeeded[creep.room.name] = true;
				}

				if (creep.reserveController(creep.room.controller) == ERR_NOT_IN_RANGE) {
					creep.moveTo(creep.room.controller, {
						reusePath: 25
					});
				}
			}
		} else if (creep.memory.priority == 'farMiner' || creep.memory.priority == 'farMinerNearDeath') {
			if (creep.ticksToLive <= 60) {
				creep.memory.priority == 'farMinerNearDeath';
				creep.room.visual.text("\u2620\u27A1\u26CF", creep.pos.x, creep.pos.y, {
					align: 'left',
					color: '#7DE3B5'
				});
			} else {
				creep.room.visual.text("\u27A1\u26CF", creep.pos.x, creep.pos.y, {
					align: 'left',
					color: '#7DE3B5'
				});
			}

			if (creep.room.name != creep.memory.destination) {
				creep.moveTo(new RoomPosition(25, 25, creep.memory.destination), {
					reusePath: 25
				});
			} else {
				if (creep.room.controller.reservation && (creep.room.name == creep.memory.destination)) {
					if (creep.room.controller.reservation.ticksToEnd <= 1000) {
						Memory.FarClaimerNeeded[creep.room.name] = true;
					} else {
						Memory.FarClaimerNeeded[creep.room.name] = false;
					}
				} else if (creep.room.name == creep.memory.destination) {
					Memory.FarClaimerNeeded[creep.room.name] = true;
				}

				var mineTarget = "";

				if (creep.memory.mineSource) {
					mineTarget = Game.getObjectById(creep.memory.mineSource);
					if (mineTarget && _.sum(creep.carry) <= 35) {
						if (creep.harvest(mineTarget) == ERR_NOT_IN_RANGE) {
							creep.moveTo(mineTarget, {
								reusePath: 25
							});
						}
					}
				} else {
					//Get the source ID while in the room
					var markedSources = [];
					if (Game.flags[creep.memory.targetFlag]) {
						markedSources = Game.flags[creep.memory.targetFlag].pos.lookFor(LOOK_SOURCES);
					}
					if (markedSources.length) {
						creep.memory.mineSource = markedSources[0].id;
					}
					mineTarget = Game.getObjectById(creep.memory.mineSource);
					if (mineTarget) {
						if (creep.harvest(mineTarget) == ERR_NOT_IN_RANGE) {
							creep.moveTo(mineTarget, {
								reusePath: 25
							});
						}
					}
				}

				if (creep.memory.storageUnit) {
					var thisUnit = Game.getObjectById(creep.memory.storageUnit);
					if (thisUnit) {
						if (thisUnit.hits < thisUnit.hitsMax) {
							creep.repair(thisUnit);
						} else {
							if (creep.transfer(thisUnit, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
								creep.moveTo(thisUnit, {
									reusePath: 25
								});
							}
						}
					}
				} else {
					if (mineTarget) {
						if (creep.pos.inRangeTo(mineTarget, 5)) {
							var containers = creep.pos.findInRange(FIND_STRUCTURES, 5, {
								filter: (structure) => structure.structureType == STRUCTURE_CONTAINER
							});
							if (containers.length) {
								if (creep.transfer(containers[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
									creep.moveTo(containers[0], {
										reusePath: 25
									});
								}
								creep.memory.storageUnit = containers[0].id;
							} else {
								var sites = creep.pos.findInRange(FIND_CONSTRUCTION_SITES, 5)
								if (sites.length) {
									if (creep.build(sites[0]) == ERR_NOT_IN_RANGE) {
										creep.moveTo(sites[0], {
											reusePath: 25
										});
									}
								} else {
									//Create new container
									if (creep.pos.isNearTo(mineTarget)) {
										creep.room.createConstructionSite(creep.pos, STRUCTURE_CONTAINER)
									}
								}
							}
						}
					}
				}
			}
		} else if (creep.memory.priority == 'farMule' || creep.memory.priority == 'farMuleNearDeath') {
			if (creep.ticksToLive <= 170) {
				creep.memory.priority = 'farMuleNearDeath';
				creep.room.visual.text("\u2620\u27A1\uD83D\uDC02", creep.pos.x, creep.pos.y, {
					align: 'left',
					color: '#7DE3B5'
				});
			} else {
				creep.room.visual.text("\u27A1\uD83D\uDC02", creep.pos.x, creep.pos.y, {
					align: 'left',
					color: '#7DE3B5'
				});
			}

			if (creep.room.name != creep.memory.destination && _.sum(creep.carry) <= 600) {
				var droppedSources = creep.pos.findInRange(FIND_DROPPED_ENERGY, 3);
				if (droppedSources.length) {
					//Pick up dropped energy from dead mules, etc.
					if (creep.pickup(droppedSources[0]) == ERR_NOT_IN_RANGE) {
						creep.moveTo(droppedSources[0], {
							reusePath: 25
						});
					}
				} else {
					creep.moveTo(new RoomPosition(25, 25, creep.memory.destination), {
						reusePath: 25
					});
				}
			} else if (creep.room.name != creep.memory.homeRoom && _.sum(creep.carry) > 600) {
				creep.moveTo(new RoomPosition(25, 25, creep.memory.homeRoom), {
					reusePath: 25
				});
			} else {
				if (creep.room.controller.reservation && (creep.room.name == creep.memory.destination)) {
					if (creep.room.controller.reservation.ticksToEnd <= 1000) {
						Memory.FarClaimerNeeded[creep.room.name] = true;
					} else {
						Memory.FarClaimerNeeded[creep.room.name] = false;
					}
				} else if (creep.room.name == creep.memory.destination) {
					Memory.FarClaimerNeeded[creep.room.name] = true;
				}

				if (_.sum(creep.carry) <= 600) {
					var droppedSources = creep.pos.findInRange(FIND_DROPPED_ENERGY, 10);
					if (droppedSources.length) {
						//Pick up dropped energy from dead mules, etc.
						if (creep.pickup(droppedSources[0]) == ERR_NOT_IN_RANGE) {
							creep.moveTo(droppedSources[0], {
								reusePath: 25
							});
						}
					} else {
						//in farRoom, pick up container contents
						if (creep.memory.containerTarget) {
							var thisContainer = Game.getObjectById(creep.memory.containerTarget);
							if (thisContainer) {
								if (thisContainer.store[RESOURCE_ENERGY] > 0) {
									if (creep.withdraw(thisContainer, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
										creep.moveTo(thisContainer, {
											reusePath: 25,
											ignoreRoads: true
										});
									}
								} else {
									//Wait by controller
									creep.moveTo(creep.room.controller);
								}

							}
						} else {
							//No container yet, move to be near source
							if (!creep.memory.mineSource) {
								var markedSources = [];
								if (Game.flags[creep.memory.targetFlag]) {
									markedSources = Game.flags[creep.memory.targetFlag].pos.lookFor(LOOK_SOURCES);
								}
								if (markedSources.length) {
									creep.memory.mineSource = markedSources[0].id;
								}
							}

							var thisSource = Game.getObjectById(creep.memory.mineSource);
							if (thisSource) {
								creep.moveTo(thisSource, {
									reusePath: 25,
									ignoreRoads: true
								});
								if (creep.pos.inRangeTo(thisSource, 5)) {
									//Search for container
									var containers = creep.pos.findInRange(FIND_STRUCTURES, 5, {
										filter: (structure) => structure.structureType == STRUCTURE_CONTAINER
									});
									if (containers.length) {
										creep.memory.containerTarget = containers[0].id;
										if (creep.withdraw(containers[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
											creep.moveTo(containers[0], {
												reusePath: 25,
												ignoreRoads: true
											});
										}
									}
								}
							}
						}
					}
				} else {
					//in home room, drop off energy
					var storageUnit = Game.getObjectById(creep.memory.storageSource)
					if (storageUnit) {
						if (creep.transfer(storageUnit, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
							creep.moveTo(storageUnit, {
								reusePath: 25,
								ignoreRoads: true
							});
						}
					}
				}
			}
		} else if (creep.memory.priority == 'farGuard' || creep.memory.priority == 'farGuardNearDeath') {
			creep.notifyWhenAttacked(false);
			if (creep.ticksToLive <= 70) {
				creep.memory.priority == 'farGuardNearDeath';
				creep.room.visual.text("\u2620\u27A1\u2694", creep.pos.x, creep.pos.y, {
					align: 'left',
					color: '#7DE3B5'
				});
			} else {
				creep.room.visual.text("\u27A1\u2694", creep.pos.x, creep.pos.y, {
					align: 'left',
					color: '#7DE3B5'
				});
			}

			if (creep.hits < creep.hitsMax) {
				creep.heal(creep);
			}

			if (creep.room.controller.reservation && (creep.room.name == creep.memory.destination)) {
				if (creep.room.controller.reservation.ticksToEnd <= 1000) {
					Memory.FarClaimerNeeded[creep.room.name] = true;
				} else {
					Memory.FarClaimerNeeded[creep.room.name] = false;
				}
			} else if (creep.room.name == creep.memory.destination) {
				Memory.FarClaimerNeeded[creep.room.name] = true;
			}

			var Foe = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS);

			if (creep.room.controller.owner && creep.room.controller.owner.username != "Montblanc" && creep.room.name != creep.memory.destination) {
				creep.moveTo(new RoomPosition(25, 25, creep.memory.destination), {
					reusePath: 25
				});
			} else if (Foe) {
				if (creep.pos.getRangeTo(Foe) > 3 || (Foe.getActiveBodyparts(ATTACK) == 0) || (creep.getActiveBodyparts(RANGED_ATTACK) == 0)) {
					creep.moveTo(Foe, {
							maxRooms: 1
						});
					creep.attack(Foe);
					creep.rangedAttack(Foe);
				} else {
					var foeDirection = creep.pos.getDirectionTo(Foe);
					var evadeDirection = TOP;
					switch (foeDirection) {
						case TOP:
							evadeDirection = BOTTOM;
							break;
						case TOP_RIGHT:
							evadeDirection = BOTTOM_LEFT;
							break;
						case RIGHT:
							evadeDirection = LEFT;
							break;
						case BOTTOM_RIGHT:
							evadeDirection = TOP_LEFT;
							break;
						case BOTTOM:
							evadeDirection = TOP;
							break;
						case BOTTOM_LEFT:
							evadeDirection = TOP_RIGHT;
							break;
						case LEFT:
							evadeDirection = RIGHT;
							break;
						case TOP_LEFT:
							evadeDirection = BOTTOM_RIGHT;
							break;
					}
					creep.move(evadeDirection);
					creep.attack(Foe);
					creep.rangedAttack(Foe);
				}
			} else if (creep.room.controller.owner && creep.room.controller.owner.username != "Montblanc") {
				var hSpawn = creep.pos.findClosestByRange(FIND_HOSTILE_SPAWNS);
				if (hSpawn) {
					creep.moveTo(hSpawn);
					creep.attack(hSpawn);
					creep.rangedAttack(hSpawn);
				} else {
					try {
						creep.moveTo(Game.flags[creep.memory.targetFlag].pos);
					} catch (e) {
						//Eat it
					}
				}
			} else if (creep.room.name != creep.memory.destination) {
				creep.moveTo(new RoomPosition(25, 25, creep.memory.destination), {
					reusePath: 25
				});
			} else if (Game.flags[creep.memory.targetFlag]) {
				if (creep.pos != Game.flags[creep.memory.targetFlag].pos) {
					creep.moveTo(Game.flags[creep.memory.targetFlag]);
				}
			}
		}
	}
};
module.exports = creep_farMining;<|endoftext|>


<commit_before>var path = require('path');

var utils  = require('@djforth/ap_utils').config;

var defaults = {
  input: path.resolve('app/assets_uncompiled/stylesheets')
  , output: path.resolve('public/assets')
  ,  ext: [
    '*.css', '*.css.map', '*.gz'
  ]
  , plugins: [
    'css-mqpacker'
    , 'postcss-merge-longhand'
    , 'postcss-merge-rules'
    , 'postcss-cssnext'
    , 'autoprefixer'
    , 'css-mqpacker'
  ]
  , use: []
};

var config = utils(defaults, 'stylesheets');

module.exports = config;
<commit_msg>remove css-next add autoprefixer<commit_after>var path = require('path');

var utils  = require('@djforth/ap_utils').config;

var defaults = {
  input: path.resolve('app/assets_uncompiled/stylesheets')
  , output: path.resolve('public/assets')
  ,  ext: [
    '*.css', '*.css.map', '*.gz'
  ]
  , plugins: [
    'css-mqpacker'
    , 'postcss-merge-longhand'
    , 'postcss-merge-rules'
    , 'autoprefixer'
    , 'cssnano'
    , 'css-mqpacker'
  ]
  , use: []
};

var config = utils(defaults, 'stylesheets');

module.exports = config;
<|endoftext|>


<commit_before>import React, {PropTypes} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {browserHistory} from 'react-router';
import * as currentStatusesActions from '../../../actions/currentStatusesActions';
import CreateStatusForm from './CreateStatusForm';
import ErrorNotice from '../../common/ErrorNotice';

import {getRepoById,
        getBranchByName,
        findCommitBySha,
        firstSevenOfSha,
        validateObjectExists} from '../../../utils/utilityMethods';

import toastr from 'toastr';

import {GITHUB_STATUS_STATES} from '../../../utils/constants';

class CreateStatusPage extends React.Component {
  constructor(props, context) {
    super(props, context);

    this.state = {
      newStatus: {
        repoId: props.repo.id,
        branchName: props.branch.name,
        commitSha: props.commit.sha,
        state: GITHUB_STATUS_STATES.PENDING,
        description: "",
        targetUrl: "",
        context: ""
      }
    };

    //Bind component class functions to this context
    this.updateStatusState = this.updateStatusState.bind(this);
    this.createNewStatus = this.createNewStatus.bind(this);
  }

  updateStatusState(evt){
    const field = evt.target.name;
    let newStatus = this.state.newStatus;
    newStatus[field] = evt.target.value;
    return this.setState({newStatus: newStatus});
  }

  createNewStatus(evt){
    evt.preventDefault();
    const newStatus = this.state.newStatus;

    this.props.currentStatusesActions.createNewStatusForCommit(newStatus.repoId, newStatus.commitSha, newStatus.state, newStatus.description, newStatus.targetUrl, newStatus.context)
      .then(() => {
        toastr.success("New '" + newStatus.state + "' status for commit '" + firstSevenOfSha(newStatus.commitSha) + "' created successfully!");
        browserHistory.push("/repo/" + newStatus.repoId +"/branch/" + newStatus.branchName + "/commit/" + newStatus.commitSha + "/statuses");
      })
      .catch(error => {
        console.log(error);
        toastr.error("Failed to create new '" + newStatus.state + "' status for commit '" + firstSevenOfSha(newStatus.commitSha) + "!");
      });
  }

  render() {
    const {repo} = this.props;
    const {branch} = this.props;
    const {commit} = this.props;

    let commitShaShort = null;

    let createStatusFormElement = (
      <ErrorNotice/>
    );

    firstSevenOfSha(commit.sha);

    if(validateObjectExists(repo)){
      if(validateObjectExists(branch)){
        if(validateObjectExists(commit)){
          commitShaShort = firstSevenOfSha(commit.sha);
          createStatusFormElement = (
            <CreateStatusForm newStatus={this.state.newStatus} onSubmit={this.createNewStatus} onChange={this.updateStatusState} />
          );
        }
      }
    }

    return (

                Create Status For {commitShaShort} In {repo.name} On {branch.name}

                {createStatusFormElement}

    );
  }
}

CreateStatusPage.propTypes = {
  repo: PropTypes.object.isRequired,
  branch: PropTypes.object.isRequired,
  commit: PropTypes.object.isRequired,
  currentStatusesActions: PropTypes.object.isRequired
};

function mapStateToProps(state, ownProps) {
  let repoId = ownProps.params.repoId;
  let commitSha = ownProps.params.commitSha;
  let branchName = ownProps.params.branchName;

  let repo = null;
  let branch = null;
  let commit = null;

  if (repoId && state.repos.length > 0) {
    repo = getRepoById(state.repos, repoId);

    if (branchName && repo.branches.length > 0) {
      branch = getBranchByName(repo.branches, branchName);

      if (commitSha && branch.commits.length > 0) {
        commit = findCommitBySha(branch.commits, commitSha);
      } else {
        toastr.error("Invalid commitSha or empty branch.commits array.");
      }
    } else {
      toastr.error("Invalid branchName or empty repo.branches array.");
    }
  } else {
    toastr.error("Invalid repoId or empty repos array.");
  }

  return {
    repo: repo,
    branch: branch,
    commit: commit
  };
}

function mapDispatchToProps(dispatch) {
  return {
    currentStatusesActions: bindActionCreators(currentStatusesActions, dispatch)
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(CreateStatusPage);
<commit_msg>Fix accessing paginatedCommits in mapStateToProps on CreateStatusPage<commit_after>import React, {PropTypes} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {browserHistory} from 'react-router';
import * as currentStatusesActions from '../../../actions/currentStatusesActions';
import CreateStatusForm from './CreateStatusForm';
import ErrorNotice from '../../common/ErrorNotice';

import {getRepoById,
        getBranchByName,
        findCommitBySha,
        firstSevenOfSha,
        validateObjectExists} from '../../../utils/utilityMethods';

import toastr from 'toastr';

import {GITHUB_STATUS_STATES} from '../../../utils/constants';

class CreateStatusPage extends React.Component {
  constructor(props, context) {
    super(props, context);

    this.state = {
      newStatus: {
        repoId: props.repo.id,
        branchName: props.branch.name,
        commitSha: props.commit.sha,
        state: GITHUB_STATUS_STATES.PENDING,
        description: "",
        targetUrl: "",
        context: ""
      }
    };

    //Bind component class functions to this context
    this.updateStatusState = this.updateStatusState.bind(this);
    this.createNewStatus = this.createNewStatus.bind(this);
  }

  updateStatusState(evt){
    const field = evt.target.name;
    let newStatus = this.state.newStatus;
    newStatus[field] = evt.target.value;
    return this.setState({newStatus: newStatus});
  }

  createNewStatus(evt){
    evt.preventDefault();
    const newStatus = this.state.newStatus;

    this.props.currentStatusesActions.createNewStatusForCommit(newStatus.repoId, newStatus.commitSha, newStatus.state, newStatus.description, newStatus.targetUrl, newStatus.context)
      .then(() => {
        toastr.success("New '" + newStatus.state + "' status for commit '" + firstSevenOfSha(newStatus.commitSha) + "' created successfully!");
        browserHistory.push("/repo/" + newStatus.repoId +"/branch/" + newStatus.branchName + "/commit/" + newStatus.commitSha + "/statuses");
      })
      .catch(error => {
        console.log(error);
        toastr.error("Failed to create new '" + newStatus.state + "' status for commit '" + firstSevenOfSha(newStatus.commitSha) + "!");
      });
  }

  render() {
    const {repo} = this.props;
    const {branch} = this.props;
    const {commit} = this.props;

    let commitShaShort = null;

    let createStatusFormElement = (
      <ErrorNotice/>
    );

    firstSevenOfSha(commit.sha);

    if(validateObjectExists(repo)){
      if(validateObjectExists(branch)){
        if(validateObjectExists(commit)){
          commitShaShort = firstSevenOfSha(commit.sha);
          createStatusFormElement = (
            <CreateStatusForm newStatus={this.state.newStatus} onSubmit={this.createNewStatus} onChange={this.updateStatusState} />
          );
        }
      }
    }

    return (

                Create Status For {commitShaShort} In {repo.name} On {branch.name}

                {createStatusFormElement}

    );
  }
}

CreateStatusPage.propTypes = {
  repo: PropTypes.object.isRequired,
  branch: PropTypes.object.isRequired,
  commit: PropTypes.object.isRequired,
  currentStatusesActions: PropTypes.object.isRequired
};

function mapStateToProps(state, ownProps) {
  let repoId = ownProps.params.repoId;
  let commitSha = ownProps.params.commitSha;
  let branchName = ownProps.params.branchName;

  let repo = null;
  let branch = null;
  let commit = null;

  if (repoId && state.repos.length > 0) {
    repo = getRepoById(state.repos, repoId);

    if (branchName && repo.branches.length > 0) {
      branch = getBranchByName(repo.branches, branchName);
      let paginatedCommits = branch.commits.paginatedCommits;

      if (commitSha && paginatedCommits.length > 0) {
        commit = findCommitBySha(paginatedCommits, commitSha);
      } else {
        toastr.error("Invalid commitSha or empty branch.commits array.");
      }
    } else {
      toastr.error("Invalid branchName or empty repo.branches array.");
    }
  } else {
    toastr.error("Invalid repoId or empty repos array.");
  }

  return {
    repo: repo,
    branch: branch,
    commit: commit
  };
}

function mapDispatchToProps(dispatch) {
  return {
    currentStatusesActions: bindActionCreators(currentStatusesActions, dispatch)
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(CreateStatusPage);
<|endoftext|>