<commit_before>let test = require('ava'),
    webdriver = require('selenium-webdriver'),
    {By, until, Key} = webdriver,
    moment = require('moment'),
    _includes = require('lodash/includes'),
    _isRegExp = require('lodash/isRegExp'),
    url = require('url'),
    path = require('path'),
    chalk = require('chalk')

let capabilities = {},
    testEnv = process.env.TEST_ENV || 'local'
if (testEnv === 'local') {
    // This gives us access to send Chrome commands.
    require('chromedriver')
} else {
    // Set capabilities for BrowserStack
    require('./keep-alive.js')
    let config = require('config')
    capabilities = {
        // Ideally, we'd like to test with:
        //   browserName: 'IE',
        //   browser_version: '11.0',
        // but that is so prone to unexpected failures as to be unusable.
        // So test with latest stable Chrome instead.
        browserName: 'Chrome',
        browser_version: '67.0',
        chromeOptions: {
            // Maximize the window so we can see what's going on
            args: ['--start-maximized']
        },
        os: 'Windows',
        os_version: '7',
        resolution: '2048x1536',
        project: 'ANET',
        build: require("git-describe").gitDescribeSync(".", {match: '[0-9]*'}).semverString,
        // Will be replaced for each test:
        name: 'frontend tests',
        // Credentials for BrowserStack, get from config:
        'browserstack.user': config.get('browserstack_user'),
        'browserstack.key': config.get('browserstack_key'),
        // This requires that BrowserStackLocal is running!
        'browserstack.local': 'true'
    }
    if (config.has('browserstack_debug')) {
        capabilities['browserstack.debug'] = config.get('browserstack_debug')
    }
    let util = require('util')
    capabilities.build = util.format(capabilities.build,
                                     capabilities.os,
                                     capabilities.os_version,
                                     capabilities.browserName,
                                     capabilities.browser_version)
}

// Webdriver's promise manager only made sense before Node had async/await support.
// Now it's a deprecated legacy feature, so we should use the simpler native Node support instead.
webdriver.promise.USE_PROMISE_MANAGER = false

console.log(chalk.bold.cyan(
    `These tests assume that you have recently run ${path.resolve(__dirname, '..', '..', '..', 'insertSqlBaseData.sql')} on your SQLServer instance`
))

function debugLog(...args) {
    if (process.env.DEBUG_LOG === 'true') {
        console.log(chalk.grey('[DEBUG]'), ...args)
    }
}

let shortWaitMs = moment.duration(.5, 'seconds').asMilliseconds()

// We use the before hook to put helpers on t.context and set up test scaffolding.
test.beforeEach(t => {
    let builder = new webdriver.Builder()
    if (testEnv === 'local') {
        builder = builder
            .forBrowser('chrome')
    } else {
        capabilities.name = t.title.replace(/^beforeEach for /, '')
        builder = builder
            .usingServer('http://hub-cloud.browserstack.com/wd/hub')
            .withCapabilities(capabilities)
    }
    t.context.driver = builder.build()

    t.context.By = By
    t.context.until = until
    t.context.shortWaitMs = shortWaitMs
    t.context.Key = Key

    // This method is a helper so we don't have to keep repeating the hostname.
    // Passing the authentication through the querystring is a hack so we can
    // pass the information along via window.fetch.
    t.context.get = async (pathname, userPw) => {
        let credentials = userPw || 'erin'
        let urlToGet = `http://localhost:8080${pathname}?user=${credentials}&pass=${credentials}`
        debugLog('Getting URL', urlToGet)
        await t.context.driver.get(urlToGet)

        // If we have a page-wide error message, we would like to cleanly fail the test on that.
        try {
            await t.context.driver.wait(
                until.elementTextIs(
                    await t.context.$('.not-found-text', shortWaitMs),
                    'There was an error processing this request. Please contact an administrator.'),
                shortWaitMs
            )
            throw new Error('The API returned a 500. Do you need to restart the server?')
        } catch (e) {
            // NoSuchElementError: If we didn't find the "not found text" element, then we are not seeing a page-wide failure.
            // StaleElementReferenceError: If we found the "not found text" element but it's no longer on the page,
            //      then we are not seeing a page-wide failure.
            // TimeoutError: If we found the "not found text" element, but the text was never the backend error message,
            //      then we are not seeing a page-wide failure.
            if (!_includes(['NoSuchElementError', 'StaleElementReferenceError', 'TimeoutError'], e.name)) {
                throw e
            }
        }
    }

    // For debugging purposes.
    t.context.waitForever = async () => {
        console.log(chalk.red('Waiting forever so you can debug...'))
        await t.context.driver.wait(() => {})
    }

    let longWaitMs = moment.duration(10, 'seconds').asMilliseconds()
    t.context.$ = async (cssSelector, timeoutMs) => {
        debugLog(`Find element: $('${cssSelector}')`)
        let waitTimeoutMs = timeoutMs || longWaitMs
        let locator = By.css(cssSelector)
        await t.context.driver.wait(
            until.elementLocated(locator),
            waitTimeoutMs,
            `Could not find element by css selector ${cssSelector} within ${waitTimeoutMs} milliseconds`
        )
        return await t.context.driver.findElement(locator)
    }
    t.context.$$ = async (cssSelector, timeoutMs) => {
        debugLog(`Find elements: $$('${cssSelector}')`)
        let waitTimeoutMs = timeoutMs || longWaitMs
        let locator = By.css(cssSelector)
        await t.context.driver.wait(
            until.elementsLocated(locator),
            waitTimeoutMs,
            `Could not find elements by css selector ${cssSelector} within ${waitTimeoutMs} milliseconds`
        )
        return t.context.driver.findElements(locator)
    }

    // A helper method to combine waiting for an element to have rendered and then asserting on its contents.
    t.context.assertElementText = async (t, $elem, expectedText, message) => {
        try {
            let untilCondition = _isRegExp(expectedText) ?
                    until.elementTextMatches($elem, expectedText) : until.elementTextIs($elem, expectedText)

            await t.context.driver.wait(untilCondition, longWaitMs)
        } catch (e) {
            // If we got a TimeoutError because the element did not have the text we expected, just swallow it here
            // and let the assertion on blow up instead. That will produce a clearer error message.
            if (e.name !== 'TimeoutError') {
                throw e
            }
        }
        let actualText = (await $elem.getText()).trim()
        if (_isRegExp(expectedText)) {
            t.regex(actualText, expectedText, actualText, message)
        } else {
            t.is(actualText, expectedText, message)
        }
    }

    t.context.assertElementTextIsInt = (t, $elem, message) => t.context.assertElementText(t, $elem, /^\d+$/)

    t.context.assertElementNotPresent = async (t, cssSelector, message, timeoutMs) => {
        let waitTimeoutMs = timeoutMs || longWaitMs
        try {
            await t.context.driver.wait(
                async () => {
                    try {
                        return !(await t.context.$(cssSelector, waitTimeoutMs))
                    } catch (e) {
                        // Hilariously, when Selenium can't find an element, sometimes it throws TimeoutError,
                        // and sometimes it throws NoSuchElementError.
                        if (e.name === 'TimeoutError' || e.name === 'NoSuchElementError') {
                            return true
                        }
                        throw e
                    }
                },
                waitTimeoutMs,
                `Element was still present after ${waitTimeoutMs} milliseconds`
            )
        } catch (e) {
            if (e.name === 'TimeoutError') {
                t.fail(`Element with css selector '${cssSelector}' was still present after ${waitTimeoutMs} milliseconds: ${message}`)
            } else {
                throw e
            }
        }
        t.pass(message || 'Element was not present')
    }

    // A helper method to combine waiting for an element to have rendered and then asserting on its enabled status
    t.context.assertElementEnabled = async (t, cssSelector, message, timeoutMs) => {
      let waitTimeoutMs = timeoutMs || longWaitMs
      try {
         var elem = await t.context.$(cssSelector, waitTimeoutMs)
      } catch (e) {
        // If we got a TimeoutError because the element did not load, just swallow it here
        // and let the assertion on blow up instead. That will produce a clearer error message.
        if (e.name !== 'TimeoutError') {
            throw e
        }
      }
      t.is(await elem.isEnabled(), true, message)
    }

    // A helper method to combine waiting for an element to have rendered and then asserting it's disabled status
    t.context.assertElementDisabled = async (t, cssSelector, message, timeoutMs) => {
      let waitTimeoutMs = timeoutMs || longWaitMs
      try {
         var elem = await t.context.$(cssSelector, waitTimeoutMs)
      } catch (e) {
        // If we got a TimeoutError because the element did not load, just swallow it here
        // and let the assertion on blow up instead. That will produce a clearer error message.
        if (e.name !== 'TimeoutError') {
            throw e
        }
      }
      t.is(await elem.isEnabled(), false, message)
    }

    t.context.getCurrentPathname = async () => {
        let currentUrl = await t.context.driver.getCurrentUrl()
        return url.parse(currentUrl).pathname
    }

    t.context.pageHelpers = {
        async goHomeAndThenToReportsPage() {
            await t.context.get('/')

            let $createButton = await t.context.$('#createButton')
            await $createButton.click()
        },
        async clickTodayButton() {
            let $todayButton = await t.context.$('.u-today-button')
            await $todayButton.click()
        },
        async chooseAutocompleteOption(autocompleteSelector, text) {
            let $autocompleteTextbox = await t.context.$(autocompleteSelector)
            await $autocompleteTextbox.sendKeys(text)
            let $autocompleteSuggestion = await t.context.$('#react-autowhatever-1--item-0')
            await $autocompleteSuggestion.click()
            return $autocompleteTextbox
        },
        async writeInForm(inputSelector, text) {
            let $meetingGoalInput = await t.context.$(inputSelector)
            await $meetingGoalInput.sendKeys(text)
        },
        async assertReportShowStatusText(t, text) {
            await t.context.assertElementText(t, await t.context.$('.report-show h4'), text)
        },
        async clickMyOrgLink() {
            let $myOrgLink = await t.context.$('#my-organization')
            await t.context.driver.wait(t.context.until.elementIsVisible($myOrgLink))
            await $myOrgLink.click()
        },
        async clickFormBottomSubmit() {
            let $formBottomSubmit = await t.context.$('#formBottomSubmit')
            await t.context.driver.wait(t.context.until.elementIsVisible($formBottomSubmit))
            await $formBottomSubmit.click()
        },
        async clickPersonNameFromSupportedPositionsFieldset(personName) {
            let $supportedPositionsRows = await t.context.$$('#supportedPositions table tbody tr')
            for (let $row of $supportedPositionsRows) {
                let [$billetCell, $advisorCell] = await $row.findElements(By.css('td'))
                let billetText = await $billetCell.getText()
                let advisorText = await $advisorCell.getText()

                if (advisorText === personName) {
                    await t.context.driver.wait(until.elementIsVisible($advisorCell))
                    let $advisorLink = await $advisorCell.findElement(By.css('a'))
                    await $advisorLink.click()
                    return
                }
            }
            t.fail(`Could not find a row with person name = '${personName}'` +
                'in the supported positions table. ' +
                'Please fix the database to be the way this test expects.')
        }
    }
})

// Shut down the browser when we are done.
test.afterEach.always(async t => {
    if (t.context.driver) {
        await t.context.driver.quit()
    }
})

/**
 * Technically speaking, everything should be wrapped in a wait() block to give
 * the the browser time to run JS to update the page. In practice, this does not
 * always seem to be necessary, since the JS can run very fast. If the tests are flaky,
 * this would be a good thing to investigate.
 *
 * Also, I suspect that we may see a bunch of stale element errors as React replaces
 * DOM nodes. To fix this, we should use a model of passing around CSS selectors instead
 * of element references, and always query for the element at the last possible moment.
 */

module.exports = test
module.exports.debugLog = debugLog
<commit_msg>Add a sleep to the autocomplete page helper<commit_after>let test = require('ava'),
    webdriver = require('selenium-webdriver'),
    {By, until, Key} = webdriver,
    moment = require('moment'),
    _includes = require('lodash/includes'),
    _isRegExp = require('lodash/isRegExp'),
    url = require('url'),
    path = require('path'),
    chalk = require('chalk')

let capabilities = {},
    testEnv = process.env.TEST_ENV || 'local'
if (testEnv === 'local') {
    // This gives us access to send Chrome commands.
    require('chromedriver')
} else {
    // Set capabilities for BrowserStack
    require('./keep-alive.js')
    let config = require('config')
    capabilities = {
        // Ideally, we'd like to test with:
        //   browserName: 'IE',
        //   browser_version: '11.0',
        // but that is so prone to unexpected failures as to be unusable.
        // So test with latest stable Chrome instead.
        browserName: 'Chrome',
        browser_version: '67.0',
        chromeOptions: {
            // Maximize the window so we can see what's going on
            args: ['--start-maximized']
        },
        os: 'Windows',
        os_version: '7',
        resolution: '2048x1536',
        project: 'ANET',
        build: require("git-describe").gitDescribeSync(".", {match: '[0-9]*'}).semverString,
        // Will be replaced for each test:
        name: 'frontend tests',
        // Credentials for BrowserStack, get from config:
        'browserstack.user': config.get('browserstack_user'),
        'browserstack.key': config.get('browserstack_key'),
        // This requires that BrowserStackLocal is running!
        'browserstack.local': 'true'
    }
    if (config.has('browserstack_debug')) {
        capabilities['browserstack.debug'] = config.get('browserstack_debug')
    }
    let util = require('util')
    capabilities.build = util.format(capabilities.build,
                                     capabilities.os,
                                     capabilities.os_version,
                                     capabilities.browserName,
                                     capabilities.browser_version)
}

// Webdriver's promise manager only made sense before Node had async/await support.
// Now it's a deprecated legacy feature, so we should use the simpler native Node support instead.
webdriver.promise.USE_PROMISE_MANAGER = false

console.log(chalk.bold.cyan(
    `These tests assume that you have recently run ${path.resolve(__dirname, '..', '..', '..', 'insertSqlBaseData.sql')} on your SQLServer instance`
))

function debugLog(...args) {
    if (process.env.DEBUG_LOG === 'true') {
        console.log(chalk.grey('[DEBUG]'), ...args)
    }
}

let shortWaitMs = moment.duration(.5, 'seconds').asMilliseconds()

// We use the before hook to put helpers on t.context and set up test scaffolding.
test.beforeEach(t => {
    let builder = new webdriver.Builder()
    if (testEnv === 'local') {
        builder = builder
            .forBrowser('chrome')
    } else {
        capabilities.name = t.title.replace(/^beforeEach for /, '')
        builder = builder
            .usingServer('http://hub-cloud.browserstack.com/wd/hub')
            .withCapabilities(capabilities)
    }
    t.context.driver = builder.build()

    t.context.By = By
    t.context.until = until
    t.context.shortWaitMs = shortWaitMs
    t.context.Key = Key

    // This method is a helper so we don't have to keep repeating the hostname.
    // Passing the authentication through the querystring is a hack so we can
    // pass the information along via window.fetch.
    t.context.get = async (pathname, userPw) => {
        let credentials = userPw || 'erin'
        let urlToGet = `http://localhost:8080${pathname}?user=${credentials}&pass=${credentials}`
        debugLog('Getting URL', urlToGet)
        await t.context.driver.get(urlToGet)

        // If we have a page-wide error message, we would like to cleanly fail the test on that.
        try {
            await t.context.driver.wait(
                until.elementTextIs(
                    await t.context.$('.not-found-text', shortWaitMs),
                    'There was an error processing this request. Please contact an administrator.'),
                shortWaitMs
            )
            throw new Error('The API returned a 500. Do you need to restart the server?')
        } catch (e) {
            // NoSuchElementError: If we didn't find the "not found text" element, then we are not seeing a page-wide failure.
            // StaleElementReferenceError: If we found the "not found text" element but it's no longer on the page,
            //      then we are not seeing a page-wide failure.
            // TimeoutError: If we found the "not found text" element, but the text was never the backend error message,
            //      then we are not seeing a page-wide failure.
            if (!_includes(['NoSuchElementError', 'StaleElementReferenceError', 'TimeoutError'], e.name)) {
                throw e
            }
        }
    }

    // For debugging purposes.
    t.context.waitForever = async () => {
        console.log(chalk.red('Waiting forever so you can debug...'))
        await t.context.driver.wait(() => {})
    }

    let longWaitMs = moment.duration(10, 'seconds').asMilliseconds()
    t.context.$ = async (cssSelector, timeoutMs) => {
        debugLog(`Find element: $('${cssSelector}')`)
        let waitTimeoutMs = timeoutMs || longWaitMs
        let locator = By.css(cssSelector)
        await t.context.driver.wait(
            until.elementLocated(locator),
            waitTimeoutMs,
            `Could not find element by css selector ${cssSelector} within ${waitTimeoutMs} milliseconds`
        )
        return await t.context.driver.findElement(locator)
    }
    t.context.$$ = async (cssSelector, timeoutMs) => {
        debugLog(`Find elements: $$('${cssSelector}')`)
        let waitTimeoutMs = timeoutMs || longWaitMs
        let locator = By.css(cssSelector)
        await t.context.driver.wait(
            until.elementsLocated(locator),
            waitTimeoutMs,
            `Could not find elements by css selector ${cssSelector} within ${waitTimeoutMs} milliseconds`
        )
        return t.context.driver.findElements(locator)
    }

    // A helper method to combine waiting for an element to have rendered and then asserting on its contents.
    t.context.assertElementText = async (t, $elem, expectedText, message) => {
        try {
            let untilCondition = _isRegExp(expectedText) ?
                    until.elementTextMatches($elem, expectedText) : until.elementTextIs($elem, expectedText)

            await t.context.driver.wait(untilCondition, longWaitMs)
        } catch (e) {
            // If we got a TimeoutError because the element did not have the text we expected, just swallow it here
            // and let the assertion on blow up instead. That will produce a clearer error message.
            if (e.name !== 'TimeoutError') {
                throw e
            }
        }
        let actualText = (await $elem.getText()).trim()
        if (_isRegExp(expectedText)) {
            t.regex(actualText, expectedText, actualText, message)
        } else {
            t.is(actualText, expectedText, message)
        }
    }

    t.context.assertElementTextIsInt = (t, $elem, message) => t.context.assertElementText(t, $elem, /^\d+$/)

    t.context.assertElementNotPresent = async (t, cssSelector, message, timeoutMs) => {
        let waitTimeoutMs = timeoutMs || longWaitMs
        try {
            await t.context.driver.wait(
                async () => {
                    try {
                        return !(await t.context.$(cssSelector, waitTimeoutMs))
                    } catch (e) {
                        // Hilariously, when Selenium can't find an element, sometimes it throws TimeoutError,
                        // and sometimes it throws NoSuchElementError.
                        if (e.name === 'TimeoutError' || e.name === 'NoSuchElementError') {
                            return true
                        }
                        throw e
                    }
                },
                waitTimeoutMs,
                `Element was still present after ${waitTimeoutMs} milliseconds`
            )
        } catch (e) {
            if (e.name === 'TimeoutError') {
                t.fail(`Element with css selector '${cssSelector}' was still present after ${waitTimeoutMs} milliseconds: ${message}`)
            } else {
                throw e
            }
        }
        t.pass(message || 'Element was not present')
    }

    // A helper method to combine waiting for an element to have rendered and then asserting on its enabled status
    t.context.assertElementEnabled = async (t, cssSelector, message, timeoutMs) => {
      let waitTimeoutMs = timeoutMs || longWaitMs
      try {
         var elem = await t.context.$(cssSelector, waitTimeoutMs)
      } catch (e) {
        // If we got a TimeoutError because the element did not load, just swallow it here
        // and let the assertion on blow up instead. That will produce a clearer error message.
        if (e.name !== 'TimeoutError') {
            throw e
        }
      }
      t.is(await elem.isEnabled(), true, message)
    }

    // A helper method to combine waiting for an element to have rendered and then asserting it's disabled status
    t.context.assertElementDisabled = async (t, cssSelector, message, timeoutMs) => {
      let waitTimeoutMs = timeoutMs || longWaitMs
      try {
         var elem = await t.context.$(cssSelector, waitTimeoutMs)
      } catch (e) {
        // If we got a TimeoutError because the element did not load, just swallow it here
        // and let the assertion on blow up instead. That will produce a clearer error message.
        if (e.name !== 'TimeoutError') {
            throw e
        }
      }
      t.is(await elem.isEnabled(), false, message)
    }

    t.context.getCurrentPathname = async () => {
        let currentUrl = await t.context.driver.getCurrentUrl()
        return url.parse(currentUrl).pathname
    }

    t.context.pageHelpers = {
        async goHomeAndThenToReportsPage() {
            await t.context.get('/')

            let $createButton = await t.context.$('#createButton')
            await $createButton.click()
        },
        async clickTodayButton() {
            let $todayButton = await t.context.$('.u-today-button')
            await $todayButton.click()
        },
        async chooseAutocompleteOption(autocompleteSelector, text) {
            let $autocompleteTextbox = await t.context.$(autocompleteSelector)
            await $autocompleteTextbox.sendKeys(text)
            t.context.driver.sleep(shortWaitMs) // give the autocomplete some time to send the request (debounce!)
            let $autocompleteSuggestion = await t.context.$('#react-autowhatever-1--item-0')
            await $autocompleteSuggestion.click()
            return $autocompleteTextbox
        },
        async writeInForm(inputSelector, text) {
            let $meetingGoalInput = await t.context.$(inputSelector)
            await $meetingGoalInput.sendKeys(text)
        },
        async assertReportShowStatusText(t, text) {
            await t.context.assertElementText(t, await t.context.$('.report-show h4'), text)
        },
        async clickMyOrgLink() {
            let $myOrgLink = await t.context.$('#my-organization')
            await t.context.driver.wait(t.context.until.elementIsVisible($myOrgLink))
            await $myOrgLink.click()
        },
        async clickFormBottomSubmit() {
            let $formBottomSubmit = await t.context.$('#formBottomSubmit')
            await t.context.driver.wait(t.context.until.elementIsVisible($formBottomSubmit))
            await $formBottomSubmit.click()
        },
        async clickPersonNameFromSupportedPositionsFieldset(personName) {
            let $supportedPositionsRows = await t.context.$$('#supportedPositions table tbody tr')
            for (let $row of $supportedPositionsRows) {
                let [$billetCell, $advisorCell] = await $row.findElements(By.css('td'))
                let billetText = await $billetCell.getText()
                let advisorText = await $advisorCell.getText()

                if (advisorText === personName) {
                    await t.context.driver.wait(until.elementIsVisible($advisorCell))
                    let $advisorLink = await $advisorCell.findElement(By.css('a'))
                    await $advisorLink.click()
                    return
                }
            }
            t.fail(`Could not find a row with person name = '${personName}'` +
                'in the supported positions table. ' +
                'Please fix the database to be the way this test expects.')
        }
    }
})

// Shut down the browser when we are done.
test.afterEach.always(async t => {
    if (t.context.driver) {
        await t.context.driver.quit()
    }
})

/**
 * Technically speaking, everything should be wrapped in a wait() block to give
 * the the browser time to run JS to update the page. In practice, this does not
 * always seem to be necessary, since the JS can run very fast. If the tests are flaky,
 * this would be a good thing to investigate.
 *
 * Also, I suspect that we may see a bunch of stale element errors as React replaces
 * DOM nodes. To fix this, we should use a model of passing around CSS selectors instead
 * of element references, and always query for the element at the last possible moment.
 */

module.exports = test
module.exports.debugLog = debugLog
<|endoftext|>


<commit_before>var express					= require('express'),
		path						= require('path'),
		passwordless		= require('passwordless'),
		RouteController	= require('./controllers/routes'),
		AuthController	= require('./controllers/auth');

module.exports = function(app) {
	var router = express.Router();
	// ==========================================================================
	// API Routes ===============================================================
	// ==========================================================================

	router.get('/', function (req, res) {
		res.json({ message: 'Welcome to the API!' });
	});

	// Media Routes =============================================================

	// API route handlers for /media
	router.route('/media')
		.get(RouteController.getMedia);

	// Photo Routes =============================================================
	// API route handlers for /photos
	router.route('/photos')
		.get(RouteController.getPhotos)
		.post(RouteController.postPhotos);

	// API route handlers for /photos/:id
	router.route('/photos/:id')
		.get(RouteController.getPhoto)
		.put(RouteController.putPhoto)
		.delete(RouteController.deletePhoto);

	// Video Routes =============================================================

	// API route handlers for /videos
	router.route('/videos')
		.get(RouteController.getVideos)
		.post(RouteController.postVideos);

	// API route handlers for /photos/:id
	router.route('/videos/:id')
		.get(RouteController.getVideo)
		.put(RouteController.putVideo)
		.delete(RouteController.deleteVideo);

	// User Routes ==============================================================

	// API route handlers for /users
	router.route('/users')
		// .post(passwordless.restricted, RouteController.postUsers)
		.post(RouteController.postUsers)
		.get(RouteController.getUsers);

	// API route handlers for /users/:user
	router.route('/users/:user')
		.get(RouteController.getUser)
		// .put(passwordless.restricted, RouteController.putUser)
		// .delete(passwordless.restricted, RouteController.deleteUser);
		.put(RouteController.putUser)
		.delete(RouteController.deleteUser);

	// API route handlers for /sendtoken
	router.route('/sendtoken')
		.post(AuthController.requestToken, RouteController.postSendToken);

	// API route handlers for /login
	router.route('/login')
		.post(passwordless.acceptToken, RouteController.postLogin);

	// API route handlers for /logout
	router.route('/logout')
		// .post(passwordless.logout);
		.post();

	// Register API Routes ======================================================

	app.use('/api/v1', router);

	// Frontend rRutes ==========================================================

	/* Front End Routes Handled by Angular */
	app.get('*', function (req, res) {
		res.sendFile(path.join(__dirname, '../public/views', 'index.html'));
	});
};<commit_msg>Removing AuthController references until new authentication method is setup<commit_after>var express					= require('express'),
		path						= require('path'),
		passwordless		= require('passwordless'),
		RouteController	= require('./controllers/routes');
		//AuthController	= require('./controllers/auth');

module.exports = function(app) {
	var router = express.Router();
	// ==========================================================================
	// API Routes ===============================================================
	// ==========================================================================

	router.get('/', function (req, res) {
		res.json({ message: 'Welcome to the API!' });
	});

	// Media Routes =============================================================

	// API route handlers for /media
	router.route('/media')
		.get(RouteController.getMedia);

	// Photo Routes =============================================================
	// API route handlers for /photos
	router.route('/photos')
		.get(RouteController.getPhotos)
		.post(RouteController.postPhotos);

	// API route handlers for /photos/:id
	router.route('/photos/:id')
		.get(RouteController.getPhoto)
		.put(RouteController.putPhoto)
		.delete(RouteController.deletePhoto);

	// Video Routes =============================================================

	// API route handlers for /videos
	router.route('/videos')
		.get(RouteController.getVideos)
		.post(RouteController.postVideos);

	// API route handlers for /photos/:id
	router.route('/videos/:id')
		.get(RouteController.getVideo)
		.put(RouteController.putVideo)
		.delete(RouteController.deleteVideo);

	// User Routes ==============================================================

	// API route handlers for /users
	router.route('/users')
		// .post(passwordless.restricted, RouteController.postUsers)
		.post(RouteController.postUsers)
		.get(RouteController.getUsers);

	// API route handlers for /users/:user
	router.route('/users/:user')
		.get(RouteController.getUser)
		// .put(passwordless.restricted, RouteController.putUser)
		// .delete(passwordless.restricted, RouteController.deleteUser);
		.put(RouteController.putUser)
		.delete(RouteController.deleteUser);

	// API route handlers for /sendtoken
	router.route('/sendtoken')
		//.post(AuthController.requestToken, RouteController.postSendToken);
		.post(RouteController.postSendToken);

	// API route handlers for /login
	router.route('/login')
		//.post(passwordless.acceptToken, RouteController.postLogin);
		.post(RouteController.postLogin);

	// API route handlers for /logout
	router.route('/logout')
		// .post(passwordless.logout);
		.post();

	// Register API Routes ======================================================

	app.use('/api/v1', router);

	// Frontend rRutes ==========================================================

	/* Front End Routes Handled by Angular */
	app.get('*', function (req, res) {
		res.sendFile(path.join(__dirname, '../public/views', 'index.html'));
	});
};<|endoftext|>


<commit_before>var React = require('react');
var Navigation = require('navigation');
var NavigationShared = require('./NavigationShared');
var Listing = require('./Listing');
var Details = require('./Details');

function registerNavigators() {
	var states = Navigation.StateInfoConfig.dialogs.masterDetails.states;
	states.listing.navigating = function(data, url, navigate) {
		getData('/data/people/' + data.pageNumber, function(data){
			navigate(data);
		})
	}

	states.listing.navigated = function(data, asyncData) {
		React.render(
			React.createElement(Listing, { people: asyncData }),
			document.getElementById('content')
		);
	}

	states.details.navigating = function(data, url, navigate) {
		getData('/data/person/' + data.id, function(data){
			navigate(data);
		})
	}

	states.details.navigated = function(data, asyncData) {
		React.render(
			React.createElement(Details, { person: asyncData }),
			document.getElementById('content')
		);
	}

	function getData(url, callback) {
		var req = new XMLHttpRequest();
        req.onreadystatechange = function() {
			if (req.readyState === 4){
				callback(JSON.parse(req.responseText));
			}
		};
        req.open('get', url);
		req.setRequestHeader("Content-Type", "application/json");
        req.send(null);
	}
}

exports.start = function(props) {
	Navigation.start();
	React.render(React.createElement(NavigationShared.getContent(), props), document.getElementById('content'));
	registerNavigators();
}
<commit_msg>Used NavigationShared to render from navigated<commit_after>var React = require('react');
var Navigation = require('navigation');
var NavigationShared = require('./NavigationShared');

function registerNavigators() {
	var states = Navigation.StateInfoConfig.dialogs.masterDetails.states;
	states.listing.navigating = function(data, url, navigate) {
		getData('/data/people/' + data.pageNumber, function(data){
			navigate({ people: data });
		})
	}

	states.listing.navigated = function(data, asyncData) {
		render(asyncData);
	}

	states.details.navigating = function(data, url, navigate) {
		getData('/data/person/' + data.id, function(data){
			navigate({ person: data });
		})
	}

	states.details.navigated = function(data, asyncData) {
		render(asyncData);
	}

	function getData(url, callback) {
		var req = new XMLHttpRequest();
        req.onreadystatechange = function() {
			if (req.readyState === 4){
				callback(JSON.parse(req.responseText));
			}
		};
        req.open('get', url);
		req.setRequestHeader("Content-Type", "application/json");
        req.send(null);
	}
}

exports.start = function(props) {
	Navigation.start();
	render(props);
	registerNavigators();
}

function render(props) {
	React.render(
		React.createElement(NavigationShared.getContent(), props),
		document.getElementById('content')
	);
}

<|endoftext|>


<commit_before>var co = require('co')
var BikeshedBuilderStore = require('../stores/BikeshedBuilderStore')

module.exports = {
  addFiles: co.wrap(function* addFiles (context, payload) {
    var browserImageSize = require('browser-image-size')
    var fileList = yield Array.from(payload)
    .filter(file => {
      var isValid = ['image/png', 'image/jpeg'].indexOf(file.type) > -1
      if (!isValid)
        context.dispatch('ADD_TOAST_MESSAGE', `File ${file.name} has invalid type ${file.type}`)
      return isValid
    })
    .map(file => {
      var name = file.name
      return browserImageSize(file).then(size => ({name, file, size}))
    })

    context.dispatch('ADD_BIKES_TO_BIKESHED_BUILDER', fileList)
  }),

  removeBike: function removeBike (context, payload) {
    context.dispatch('REMOVE_BIKE_FROM_BIKESHED_BUILDER', payload)
  },

  openPreview: function openPreview (context, bikeName) {
    if (context.getStore(BikeshedBuilderStore).hasBike(bikeName))
      context.dispatch('OPEN_BIKE_PREVIEW', bikeName)
    else
      context.dispatch('ADD_TOAST_MESSAGE', `Bike ${bikeName} does not exist`)
  },

  closePreview: function closePreview (context) {
    context.dispatch('CLOSE_BIKE_PREVIEW')
  },

  openDialog: function (context) {
    context.dispatch('OPEN_BIKESHED_BUILDER_DIALOG', true)
  },

  closeDialog: function (context) {
    context.dispatch('OPEN_BIKESHED_BUILDER_DIALOG', false)
  },

  formChange: function (context, payload) {
    context.dispatch('BIKESHED_BUILDER_FORM_CHANGE', payload)
  }

}
<commit_msg>Simplify BIkeshedBuilderActions<commit_after>var co = require('co')

module.exports = {
  addFiles: co.wrap(function* addFiles (context, payload) {
    var browserImageSize = require('browser-image-size')
    var fileList = yield Array.from(payload)
    .filter(file => {
      var isValid = ['image/png', 'image/jpeg'].indexOf(file.type) > -1
      if (!isValid)
        context.dispatch('ADD_TOAST_MESSAGE', `File ${file.name} has invalid type ${file.type}`)
      return isValid
    })
    .map(file => {
      var name = file.name
      return browserImageSize(file).then(size => ({name, file, size}))
    })

    context.dispatch('ADD_BIKES_TO_BIKESHED_BUILDER', fileList)
  }),

  removeBike: function removeBike (context, payload) {
    context.dispatch('REMOVE_BIKE_FROM_BIKESHED_BUILDER', payload)
  },

  openPreview: function openPreview (context, bikeName) {
    context.dispatch('OPEN_BIKE_PREVIEW', bikeName)
  },

  closePreview: function closePreview (context) {
    context.dispatch('CLOSE_BIKE_PREVIEW')
  },

  openDialog: function (context) {
    context.dispatch('OPEN_BIKESHED_BUILDER_DIALOG', true)
  },

  closeDialog: function (context) {
    context.dispatch('OPEN_BIKESHED_BUILDER_DIALOG', false)
  },

  formChange: function (context, payload) {
    context.dispatch('BIKESHED_BUILDER_FORM_CHANGE', payload)
  }

}
<|endoftext|>


<commit_before>var PARAMS = Object.freeze({
  COLLECTION_TIME: 1000,
  MAX_COLOR_BIAS: 3,
  MOVE_THRESHOLD: 200,
  MOVE_THRESHOLD_SMALL: 50,
  MOVE_ADJUSTMENT_MULTIPLIER: 2,
  INPUT_WIDTH: 300,
  INPUT_HEIGHT: 250,
  CANVAS_WIDTH: 500,
  CANVAS_HEIGHT: 300,
  PIXEL_SIZE: 5,
  INVADER_COUNT: 7
});

document.addEventListener('DOMContentLoaded', function(){

  var runCount = 0;
  var ctx = document.getElementById('fleet-display').getContext('2d');
  var progressButton = document.getElementById('button-progress');
  var clickHandler = function(){ startGeneration(); };
  progressButton.addEventListener('click', clickHandler);

  // Only one half, a 6x8 grid is stored for an invader, because they are
  // symmetrical to the vertical axis (making their final size 11x8 pixels).
  // The half of the "standard" space invader looks like this:
  //[0,0,1,0,0,0],
  //[0,0,0,1,0,0],
  //[0,0,1,1,1,1],
  //[0,1,1,0,1,1],
  //[1,1,1,1,1,1],
  //[1,0,1,1,1,1],
  //[1,0,1,0,0,0],
  //[0,0,0,1,1,0],
  //but it's not necessary to store this, because the mutators recreate it if there's no mouse input

  var baseInvader = [
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
  ];

  var mutators = [hullMutator, antennaMutator, weaponMutator, thrusterMutator];

  function resetMutators(){
    mutators = [hullMutator, antennaMutator, weaponMutator, thrusterMutator];
  }

  function startGeneration() {
    if(runCount === 0){
      ctx.clearRect(0,0,PARAMS.CANVAS_WIDTH,PARAMS.CANVAS_HEIGHT);
      ctx.fillSTyle = 'black';
      ctx.fillRect(0,0,PARAMS.CANVAS_WIDTH,PARAMS.CANVAS_HEIGHT);
    }
    runCount++;
    collectInput(function(inputs){
      // --- add a special random mutator, without a dedicated collection interval
      // it gets the same input as the first mutator
      mutators.push(randomMutator);
      inputs.push(inputs[0]);
      // ----
      var invader = mutateInvader(baseInvader, inputs, mutators);
      display(invader);
    });
  }

  function collectInput(callback){
    var inputArea = document.getElementById('input-area');
    var inputWidth = inputArea.getBoundingClientRect().width; //NB this includes borders
    var inputHeight = inputArea.getBoundingClientRect().height;
    var inputSeed = [];
    var moveCount = 0;
    var firstMove;
    var lastMove;
    var moveCounter = function(event){
      moveCount++;
      var X = event.clientX - this.getBoundingClientRect().left;
      var Y = event.clientY - this.getBoundingClientRect().top;
      if(firstMove){
        lastMove = {x: X, y: Y};
      } else {
        firstMove = {x: X, y: Y};
      }
    };

    inputArea.addEventListener('mousemove', moveCounter);

    progressButton.removeEventListener('click', clickHandler);
    progressButton.innerHTML = 'Generating row... (0/'+mutators.length+')';

    //Dispatch a timeout for each mutator, with increasing delays. Mouse moves are
    // collected between the callbacks, creating the input seed for each mutator.
    mutators.forEach(function(_, i){
      setTimeout(function(){
        progressButton.innerHTML = 'Generating row... ('+(i+1)+'/'+mutators.length+')';
        inputSeed.push({
          moveCount: moveCount,
          firstMove: firstMove,
          lastMove: lastMove
        });
        moveCount = 0;
        firstMove = undefined;
        lastMove = undefined;
        if(i===mutators.length-1){
          inputArea.removeEventListener('mousemove', moveCounter);
          callback(inputSeed);
          progressButton.innerHTML = 'Fleet generated. (Click to restart)';
          resetMutators();
          progressButton.addEventListener('click', clickHandler);
          if(runCount < 3){
            clickHandler();
          } else {
            runCount = 0;
          }
        }
      }, PARAMS.COLLECTION_TIME*(i+1));
    });

  }

  function display(invader){
    var colWidth = (11+3)*PARAMS.PIXEL_SIZE;
    var rowHeight = (8+3)*PARAMS.PIXEL_SIZE;
    for(var i=0;i<PARAMS.INVADER_COUNT;i++){
      for(var row=0;row<2;row++){
        drawInvader(
          ctx,
          2*PARAMS.PIXEL_SIZE+(i*colWidth),
          -(rowHeight)+2*PARAMS.PIXEL_SIZE+(row*rowHeight)+((runCount-1)*2*rowHeight),
          invader
        );
      }
    }
  }

});

function deepCopy(obj){
  return JSON.parse(JSON.stringify(obj));
}

function mutateInvader(base, inputs, mutators){
  var invader = deepCopy(base);
  mutators.forEach(function(mutator, i){
    invader = mutator(invader, inputs[i]);
  });
  return invader;
}

function hullMutator(invader, input){
  var p = { //base pixel
    color: getColorString(input.moveCount)
  };
  var s = deepCopy(p); //secondary pixel
  if(input.firstMove && input.lastMove){
    var x0 = input.firstMove.x;
    var y0 = input.firstMove.y;
    var x1 = input.lastMove.x;
    var y1 = input.lastMove.y;
    if(Math.abs(x0-x1)<100 && Math.abs(y0-y1)<100){
      s.color = getColorString(input.moveCount, 0.8, 0.8, 1)
    }
  }
  var e = 0; //eye pixel
  if(input.firstMove && input.lastMove){
    //only color eyes if movement was downwards - should be rare due to layout
    if(input.firstMove.y < input.lastMove.y ){
      e = {
        color: input.firstMove.x < input.lastMove.x? 'rgb(200,15,15)' : 'rgb(50,175,20)'
      };
    }
  }
  var part = [
    [0,0,0,s], // antenna will overwrite first 3 anyway
    [s,e,s,p],
    [p,s,p,s],
    [s,p,s,p]
  ];
  return applyPart(invader, part, 2, 2);
}

function antennaMutator(invader, input){
  var biasR = 1;
  var biasG = 1;
  var biasB = 1;
  if(input.firstMove && input.lastMove){
    biasR = input.firstMove.x/PARAMS.INPUT_WIDTH;
    biasG = input.firstMove.y/PARAMS.INPUT_HEIGHT;
    biasB = input.lastMove.x/PARAMS.INPUT_WIDTH;
  }
  var p = {
    color: getColorString(input.moveCount, biasR, biasG, biasB)
  };
  var part = [
    [p,0,0,0],
    [0,p,0,0],
    [p,p,p,null]
  ];
  var antenna = [[]];
  //tilt antennae based on movement direction:
  if(input.firstMove && input.lastMove){
    var antenna;
    if( Math.abs(input.firstMove.x-input.lastMove.x)<100 ){
      antenna = [
        [0,p],
        [0,p]
      ];
    } else if (input.firstMove.x < input.lastMove.x){
      antenna = [
        [0,0,p],
        [0,p,0]
      ];
    }
  }
  part = applyPart(part, antenna, 0, 0);
  return applyPart(invader, part, 2, 0);
}

function weaponMutator(invader, input){
  var p = {
    color: getColorString(input.moveCount)
  };
  var part = [
    [0,0],
    [0,0],
    [0,0],
    [0,p],
    [p,p],
    [p,0],
    [p,0],
    [0,0]
  ];
  var weapon = [
    [0,0],
    [0,0],
    [0,0],
    [0,p],
    [p,p]
  ];
  if(input.moveCount > PARAMS.MOVE_THRESHOLD_SMALL){
    weapon = [];
    var binArray = input.moveCount.toString(2).split('');
    //normalize and replace 1s with base pixel
    binArray = binArray.map(function(el){
      return el==='1'? p: 0;
    });
    while(binArray.length > 0) {
      weapon.push(binArray.splice(0,2));
    }
  }
  part = applyPart(part, weapon, 0, 0);
  return applyPart(invader, part, 0, 0);
}

function thrusterMutator(invader, input){
  var biasR = 1;
  var biasG = 1;
  var biasB = 1;
  if(input.lastMove){
    var biasR = Math.min(PARAMS.MAX_COLOR_BIAS/2, input.lastMove.x/input.lastMove.y);
    var biasG = input.lastMove.x > input.lastMove.y? 1: 0;
    var biasB = (input.lastMove.x<20 && input.lastMove.y<20)? 0: 1;
  }
  var p = {
    color: getColorString(input.moveCount, biasR, biasG, biasB)
  };
  var part = [
    [0,0,0,0],
    [0,0,0,0]
  ];
  var thrusters = [
    [p,0,0],
    [0,p,p]
  ];
  if(input.firstMove && input.lastMove){
    if(input.moveCount%3 === 1){
      thrusters = [
        [p,p,p,p],
        [p,0,0,p]
      ];
    } else if(input.moveCount%3 === 2){
      thrusters = [
        [p,p,0,0],
        [0,0,0,0]
      ];
    } else if(input.moveCount > PARAMS.MOVE_THRESHOLD_SMALL){
      thrusters = [
        [p,0,p,0],
        [0,p,0,p]
      ]
    }
  }
  part = applyPart(part, thrusters, 0, 0);
  return applyPart(invader, part, 2, 6);
}

function randomMutator(invader, input){
  var p = {
    color: getColorString(input.moveCount, 0.5, 0.5, 0.5)
  };
  var mutation = [
    [0,0],
    [0,0]
  ];
  if(input.moveCount){
    var _ = (input.moveCount%2)? 0 : null; //50% chance to clear
    switch(input.moveCount%5){
      case 0:
        mutation = [
          [_,p],
          [_,p]
        ];
        break;
      case 1:
        mutation = [
          [_,_],
          [p,p]
        ];
        break;
      case 2:
        mutation = [
          [p,_],
          [_,p]
        ];
        break;
      case 3:
        mutation = [
          [_,p],
          [p,_]
        ];
        break;
      case 4:
        mutation = [
          [_,p],
          [p,p]
        ];
        break;
    }
  }
  // +4 offset ensures that it does not clear anything from the standard invader
  // if there was no input (clears between antennae)
  // The min call ensures that we don't override cells outside of the invader boundary
  var x = Math.min( (input.moveCount+4) % invader[0].length, invader[0].length-mutation[0].length );
  var y = Math.min( (input.moveCount*101) % invader.length, invader.length-mutation.length);
  return applyPart(invader, mutation, x, y);
}

function getColorString(moveCount, biasR, biasG, biasB){
  var n = 256-Math.min(PARAMS.MOVE_THRESHOLD,moveCount*PARAMS.MOVE_ADJUSTMENT_MULTIPLIER);
  var R = 1;
  var G = 1;
  var B = 1;
  if(biasR) R=biasR;
  if(biasG) G=biasG;
  if(biasB) B=biasB;
  //NB: non-integer values are not valid here!
  return 'rgb('+Math.floor(n*R)+','+Math.floor(n*G)+','+Math.floor(n*B)+')';
}

function applyPart(base, part, x, y){
  var invader = deepCopy(base);
  for(var i=0;i<part.length;i++){
    for(var j=0;j<part[i].length;j++){
      if(part[i][j] != null){ // null signals ignore, 0 signals overwrite with empty
        invader[y+i][x+j] = part[i][j];
      }
    }
  }
  return invader;
}

function drawInvader(context, x0, y0, invader){
  for(var y=0;y<invader.length;y++){
    var len = invader[y].length;
    //we're mirroring every column but the last
    for(var x=0;x<len*2-1;x++){
      var xPos = x>=len? x-(x-len+1)*2 : x;
      if(invader[y][xPos]){
        context.fillStyle = invader[y][xPos].color;
        context.fillRect(
          x0+x*PARAMS.PIXEL_SIZE,
          y0+y*PARAMS.PIXEL_SIZE,
          PARAMS.PIXEL_SIZE,
          PARAMS.PIXEL_SIZE
        );
      }
    }
  }
}<commit_msg>fix typo in background reset<commit_after>var PARAMS = Object.freeze({
  COLLECTION_TIME: 1000,
  MAX_COLOR_BIAS: 3,
  MOVE_THRESHOLD: 200,
  MOVE_THRESHOLD_SMALL: 50,
  MOVE_ADJUSTMENT_MULTIPLIER: 2,
  INPUT_WIDTH: 300,
  INPUT_HEIGHT: 250,
  CANVAS_WIDTH: 500,
  CANVAS_HEIGHT: 300,
  PIXEL_SIZE: 5,
  INVADER_COUNT: 7
});

document.addEventListener('DOMContentLoaded', function(){

  var runCount = 0;
  var ctx = document.getElementById('fleet-display').getContext('2d');
  var progressButton = document.getElementById('button-progress');
  var clickHandler = function(){ startGeneration(); };
  progressButton.addEventListener('click', clickHandler);

  // Only one half, a 6x8 grid is stored for an invader, because they are
  // symmetrical to the vertical axis (making their final size 11x8 pixels).
  // The half of the "standard" space invader looks like this:
  //[0,0,1,0,0,0],
  //[0,0,0,1,0,0],
  //[0,0,1,1,1,1],
  //[0,1,1,0,1,1],
  //[1,1,1,1,1,1],
  //[1,0,1,1,1,1],
  //[1,0,1,0,0,0],
  //[0,0,0,1,1,0],
  //but it's not necessary to store this, because the mutators recreate it if there's no mouse input

  var baseInvader = [
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
  ];

  var mutators = [hullMutator, antennaMutator, weaponMutator, thrusterMutator];

  function resetMutators(){
    mutators = [hullMutator, antennaMutator, weaponMutator, thrusterMutator];
  }

  function startGeneration() {
    if(runCount === 0){
      ctx.clearRect(0,0,PARAMS.CANVAS_WIDTH,PARAMS.CANVAS_HEIGHT);
      ctx.fillStyle = 'black';
      ctx.fillRect(0,0,PARAMS.CANVAS_WIDTH,PARAMS.CANVAS_HEIGHT);
    }
    runCount++;
    collectInput(function(inputs){
      // --- add a special random mutator, without a dedicated collection interval
      // it gets the same input as the first mutator
      mutators.push(randomMutator);
      inputs.push(inputs[0]);
      // ----
      var invader = mutateInvader(baseInvader, inputs, mutators);
      display(invader);
    });
  }

  function collectInput(callback){
    var inputArea = document.getElementById('input-area');
    var inputWidth = inputArea.getBoundingClientRect().width; //NB this includes borders
    var inputHeight = inputArea.getBoundingClientRect().height;
    var inputSeed = [];
    var moveCount = 0;
    var firstMove;
    var lastMove;
    var moveCounter = function(event){
      moveCount++;
      var X = event.clientX - this.getBoundingClientRect().left;
      var Y = event.clientY - this.getBoundingClientRect().top;
      if(firstMove){
        lastMove = {x: X, y: Y};
      } else {
        firstMove = {x: X, y: Y};
      }
    };

    inputArea.addEventListener('mousemove', moveCounter);

    progressButton.removeEventListener('click', clickHandler);
    progressButton.innerHTML = 'Generating row... (0/'+mutators.length+')';

    //Dispatch a timeout for each mutator, with increasing delays. Mouse moves are
    // collected between the callbacks, creating the input seed for each mutator.
    mutators.forEach(function(_, i){
      setTimeout(function(){
        progressButton.innerHTML = 'Generating row... ('+(i+1)+'/'+mutators.length+')';
        inputSeed.push({
          moveCount: moveCount,
          firstMove: firstMove,
          lastMove: lastMove
        });
        moveCount = 0;
        firstMove = undefined;
        lastMove = undefined;
        if(i===mutators.length-1){
          inputArea.removeEventListener('mousemove', moveCounter);
          callback(inputSeed);
          progressButton.innerHTML = 'Fleet generated. (Click to restart)';
          resetMutators();
          progressButton.addEventListener('click', clickHandler);
          if(runCount < 3){
            clickHandler();
          } else {
            runCount = 0;
          }
        }
      }, PARAMS.COLLECTION_TIME*(i+1));
    });

  }

  function display(invader){
    var colWidth = (11+3)*PARAMS.PIXEL_SIZE;
    var rowHeight = (8+3)*PARAMS.PIXEL_SIZE;
    for(var i=0;i<PARAMS.INVADER_COUNT;i++){
      for(var row=0;row<2;row++){
        drawInvader(
          ctx,
          2*PARAMS.PIXEL_SIZE+(i*colWidth),
          -(rowHeight)+2*PARAMS.PIXEL_SIZE+(row*rowHeight)+((runCount-1)*2*rowHeight),
          invader
        );
      }
    }
  }

});

function deepCopy(obj){
  return JSON.parse(JSON.stringify(obj));
}

function mutateInvader(base, inputs, mutators){
  var invader = deepCopy(base);
  mutators.forEach(function(mutator, i){
    invader = mutator(invader, inputs[i]);
  });
  return invader;
}

function hullMutator(invader, input){
  var p = { //base pixel
    color: getColorString(input.moveCount)
  };
  var s = deepCopy(p); //secondary pixel
  if(input.firstMove && input.lastMove){
    var x0 = input.firstMove.x;
    var y0 = input.firstMove.y;
    var x1 = input.lastMove.x;
    var y1 = input.lastMove.y;
    if(Math.abs(x0-x1)<100 && Math.abs(y0-y1)<100){
      s.color = getColorString(input.moveCount, 0.8, 0.8, 1)
    }
  }
  var e = 0; //eye pixel
  if(input.firstMove && input.lastMove){
    //only color eyes if movement was downwards - should be rare due to layout
    if(input.firstMove.y < input.lastMove.y ){
      e = {
        color: input.firstMove.x < input.lastMove.x? 'rgb(200,15,15)' : 'rgb(50,175,20)'
      };
    }
  }
  var part = [
    [0,0,0,s], // antenna will overwrite first 3 anyway
    [s,e,s,p],
    [p,s,p,s],
    [s,p,s,p]
  ];
  return applyPart(invader, part, 2, 2);
}

function antennaMutator(invader, input){
  var biasR = 1;
  var biasG = 1;
  var biasB = 1;
  if(input.firstMove && input.lastMove){
    biasR = input.firstMove.x/PARAMS.INPUT_WIDTH;
    biasG = input.firstMove.y/PARAMS.INPUT_HEIGHT;
    biasB = input.lastMove.x/PARAMS.INPUT_WIDTH;
  }
  var p = {
    color: getColorString(input.moveCount, biasR, biasG, biasB)
  };
  var part = [
    [p,0,0,0],
    [0,p,0,0],
    [p,p,p,null]
  ];
  var antenna = [[]];
  //tilt antennae based on movement direction:
  if(input.firstMove && input.lastMove){
    var antenna;
    if( Math.abs(input.firstMove.x-input.lastMove.x)<100 ){
      antenna = [
        [0,p],
        [0,p]
      ];
    } else if (input.firstMove.x < input.lastMove.x){
      antenna = [
        [0,0,p],
        [0,p,0]
      ];
    }
  }
  part = applyPart(part, antenna, 0, 0);
  return applyPart(invader, part, 2, 0);
}

function weaponMutator(invader, input){
  var p = {
    color: getColorString(input.moveCount)
  };
  var part = [
    [0,0],
    [0,0],
    [0,0],
    [0,p],
    [p,p],
    [p,0],
    [p,0],
    [0,0]
  ];
  var weapon = [
    [0,0],
    [0,0],
    [0,0],
    [0,p],
    [p,p]
  ];
  if(input.moveCount > PARAMS.MOVE_THRESHOLD_SMALL){
    weapon = [];
    var binArray = input.moveCount.toString(2).split('');
    //normalize and replace 1s with base pixel
    binArray = binArray.map(function(el){
      return el==='1'? p: 0;
    });
    while(binArray.length > 0) {
      weapon.push(binArray.splice(0,2));
    }
  }
  part = applyPart(part, weapon, 0, 0);
  return applyPart(invader, part, 0, 0);
}

function thrusterMutator(invader, input){
  var biasR = 1;
  var biasG = 1;
  var biasB = 1;
  if(input.lastMove){
    var biasR = Math.min(PARAMS.MAX_COLOR_BIAS/2, input.lastMove.x/input.lastMove.y);
    var biasG = input.lastMove.x > input.lastMove.y? 1: 0;
    var biasB = (input.lastMove.x<20 && input.lastMove.y<20)? 0: 1;
  }
  var p = {
    color: getColorString(input.moveCount, biasR, biasG, biasB)
  };
  var part = [
    [0,0,0,0],
    [0,0,0,0]
  ];
  var thrusters = [
    [p,0,0],
    [0,p,p]
  ];
  if(input.firstMove && input.lastMove){
    if(input.moveCount%3 === 1){
      thrusters = [
        [p,p,p,p],
        [p,0,0,p]
      ];
    } else if(input.moveCount%3 === 2){
      thrusters = [
        [p,p,0,0],
        [0,0,0,0]
      ];
    } else if(input.moveCount > PARAMS.MOVE_THRESHOLD_SMALL){
      thrusters = [
        [p,0,p,0],
        [0,p,0,p]
      ]
    }
  }
  part = applyPart(part, thrusters, 0, 0);
  return applyPart(invader, part, 2, 6);
}

function randomMutator(invader, input){
  var p = {
    color: getColorString(input.moveCount, 0.5, 0.5, 0.5)
  };
  var mutation = [
    [0,0],
    [0,0]
  ];
  if(input.moveCount){
    var _ = (input.moveCount%2)? 0 : null; //50% chance to clear
    switch(input.moveCount%5){
      case 0:
        mutation = [
          [_,p],
          [_,p]
        ];
        break;
      case 1:
        mutation = [
          [_,_],
          [p,p]
        ];
        break;
      case 2:
        mutation = [
          [p,_],
          [_,p]
        ];
        break;
      case 3:
        mutation = [
          [_,p],
          [p,_]
        ];
        break;
      case 4:
        mutation = [
          [_,p],
          [p,p]
        ];
        break;
    }
  }
  // +4 offset ensures that it does not clear anything from the standard invader
  // if there was no input (clears between antennae)
  // The min call ensures that we don't override cells outside of the invader boundary
  var x = Math.min( (input.moveCount+4) % invader[0].length, invader[0].length-mutation[0].length );
  var y = Math.min( (input.moveCount*101) % invader.length, invader.length-mutation.length);
  return applyPart(invader, mutation, x, y);
}

function getColorString(moveCount, biasR, biasG, biasB){
  var n = 256-Math.min(PARAMS.MOVE_THRESHOLD,moveCount*PARAMS.MOVE_ADJUSTMENT_MULTIPLIER);
  var R = 1;
  var G = 1;
  var B = 1;
  if(biasR) R=biasR;
  if(biasG) G=biasG;
  if(biasB) B=biasB;
  //NB: non-integer values are not valid here!
  return 'rgb('+Math.floor(n*R)+','+Math.floor(n*G)+','+Math.floor(n*B)+')';
}

function applyPart(base, part, x, y){
  var invader = deepCopy(base);
  for(var i=0;i<part.length;i++){
    for(var j=0;j<part[i].length;j++){
      if(part[i][j] != null){ // null signals ignore, 0 signals overwrite with empty
        invader[y+i][x+j] = part[i][j];
      }
    }
  }
  return invader;
}

function drawInvader(context, x0, y0, invader){
  for(var y=0;y<invader.length;y++){
    var len = invader[y].length;
    //we're mirroring every column but the last
    for(var x=0;x<len*2-1;x++){
      var xPos = x>=len? x-(x-len+1)*2 : x;
      if(invader[y][xPos]){
        context.fillStyle = invader[y][xPos].color;
        context.fillRect(
          x0+x*PARAMS.PIXEL_SIZE,
          y0+y*PARAMS.PIXEL_SIZE,
          PARAMS.PIXEL_SIZE,
          PARAMS.PIXEL_SIZE
        );
      }
    }
  }
}<|endoftext|>


<commit_before>//This is needed so pnpm links the needed webpack loaders in node_modules
module.exports = {
    hooks: {
        readPackage
    }
};

function readPackage(pkg, context) {
    if (pkg['one-fits-all']) {
        pkg.devDependencies = Object.assign({}, pkg.devDependencies, {
            tslint: '*',
            jsverify: '*',
            webpack: '*',
            mocha: '*',
            typescript: '*',
            'awesome-typescript-loader': '*',
            'style-loader': '*',
            'css-loader': '*',
            'tslint-loader': '*',
            'sass-loader': '*',
            'postcss-loader': '*',
            'istanbul-instrumenter-loader-fix': '*',
            '@types/history': '*',
            'cross-env': '*',
            'mocha-webpack': '2.0.0-beta.0'
        });
        pkg.dependencies = Object.assign({}, pkg.dependencies, {
            snabbdom: '*',
            history: '*'
        });
    }

    return pkg;
}
<commit_msg>Fix eject for pnpm<commit_after>//This is needed so pnpm links the needed webpack loaders in node_modules
module.exports = {
    hooks: {
        readPackage
    }
};

function readPackage(pkg, context) {
    if (pkg['one-fits-all']) {
        pkg.devDependencies = Object.assign({}, pkg.devDependencies, {
            tslint: '*',
            jsverify: '*',
            webpack: '*',
            mocha: '*',
            typescript: '*',
            'awesome-typescript-loader': '*',
            'style-loader': '*',
            'css-loader': '*',
            'tslint-loader': '*',
            'sass-loader': '*',
            'postcss-loader': '*',
            'istanbul-instrumenter-loader-fix': '*',
            '@types/history': '*',
            '@types/node': '*',
            'source-map': '*',
            tapable: '*',
            '@types/tapable': '*',
            'uglify-js': '*',
            '@types/uglify-js': '*',
            'cross-env': '*',
            'mocha-webpack': '2.0.0-beta.0'
        });
        pkg.dependencies = Object.assign({}, pkg.dependencies, {
            snabbdom: '*',
            history: '*'
        });
    }

    return pkg;
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';

import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Alert,
  Button,
  Platform,
  AppState,
  DeviceEventEmitter
} from 'react-native';

import SInfo from 'react-native-sensitive-info';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

class example extends Component {

  constructor(props) {
    super(props);
    this.handleStateChange = this.handleStateChange.bind(this);
    this.handleAuthFeedback = this.handleAuthFeedback.bind(this);
    this.state = {
      helpText: ''
    }
  }

  componentDidMount(){
    SInfo.setItem('key1', 'value1', {
      sharedPreferencesName: 'mySharedPrefs',
      keychainService: 'myKeychain' });

    SInfo.setItem('key2', 'value2', {}).then((test) => {
      console.log('My test', test); //Value 2
    });

    SInfo.setItem('key3', 'value3', {
      keychainService: 'myKeychain'
    });

    SInfo.setItem('key5', 'kSecAttrAccessibleValue', {
      keychainService: 'myKeychain',
      kSecAttrAccessible: 'kSecAttrAccessibleAlways'
    });

    SInfo.getItem('key1', {
      sharedPreferencesName: 'mySharedPrefs',
      keychainService: 'myKeychain' }).then((value) => {
        console.log(value); //value1
      });

    SInfo.getItem('key2', {}).then((value) => {
      console.log(value); //value2
    });

    SInfo.getItem('key3', {}).then((value) => {
      console.log(value); //value3
    });

    SInfo.getAllItems({
      sharedPreferencesName: 'mySharedPrefs',
      keychainService: 'myKeychain' }).then((values) => {
        console.log(values); //value1, value2
      });

    SInfo.getAllItems({}).then((values) => {
      console.log(values); //value3, value2
    });

    SInfo.deleteItem('key1', {
      sharedPreferencesName: 'mySharedPrefs',
      keychainService: 'myKeychain' }).then((values) => {
        console.log('deleted');
      });

    AppState.addEventListener('change', this.handleStateChange);
    DeviceEventEmitter.addListener('FINGERPRINT_AUTHENTICATION_HELP', this.handleAuthFeedback);
  }

  componentWillUnmount() {
    AppState.addEventListener('change', this.handleStateChange);
    SInfo.cancelFingerprintAuth();
    DeviceEventEmitter.removeListener('FINGERPRINT_AUTHENTICATION_HELP', this.handleAuthFeedback);
  }

  async setTouchIDItem(){
    if(!await SInfo.isSensorAvailable()){
      Alert.alert('Touch Sensor not found')
      return;
    }
    if(Platform.OS === 'android'){
      this.setState({
        helpText: 'Scan your fingerprint get the item.'
      })
    }
    try{
      await SInfo.setItem('touchItem', new Date().toISOString(), {touchID: true})
    } catch (err){
      Alert.alert(err.message);
    } finally {
      if(Platform.OS === 'android'){
        this.setState({
          helpText: ''
        })
      }
    }
  }

  handleStateChange(appState) {
    switch (appState) {
      case 'background':
        this.setState({
          helpText: ''
        })
        SInfo.cancelFingerprintAuth();
    }
  }

  handleAuthFeedback(helpText) {
    this.setState({helpText});
  }

  async getTouchIDItem(){
    if(!await SInfo.isSensorAvailable()){
      Alert.alert('Touch Sensor not found')
      return;
    }
    if(Platform.OS === 'android'){
      this.setState({
        helpText: 'Scan your fingerprint get the item.'
      })
    }
    try{
      let result = await SInfo.getItem('touchItem', {
        touchID: true,
        kSecUseOperationPrompt: 'Scan your fingerprint get the item.' // this is for iOS
      })
      if(result){
        Alert.alert('Touch ID item', result);
      }
    } catch (err){
      Alert.alert(err.message);
    } finally {
      if(Platform.OS === 'android'){
        this.setState({
          helpText: ''
        })
      }
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <Text>{this.state.helpText}</Text>
        <Button
          onPress={()=>this.setTouchIDItem()}
          title="set touchID item"
        />
        <Button
          onPress={()=>this.getTouchIDItem()}
          title="get touchID item"
        />
      </View>
    );
  }
}

AppRegistry.registerComponent('example', () => example);
<commit_msg>Should remove listener when component unmount<commit_after>import React, { Component } from 'react';

import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Alert,
  Button,
  Platform,
  AppState,
  DeviceEventEmitter
} from 'react-native';

import SInfo from 'react-native-sensitive-info';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

class example extends Component {

  constructor(props) {
    super(props);
    this.handleStateChange = this.handleStateChange.bind(this);
    this.handleAuthFeedback = this.handleAuthFeedback.bind(this);
    this.state = {
      helpText: ''
    }
  }

  componentDidMount(){
    SInfo.setItem('key1', 'value1', {
      sharedPreferencesName: 'mySharedPrefs',
      keychainService: 'myKeychain' });

    SInfo.setItem('key2', 'value2', {}).then((test) => {
      console.log('My test', test); //Value 2
    });

    SInfo.setItem('key3', 'value3', {
      keychainService: 'myKeychain'
    });

    SInfo.setItem('key5', 'kSecAttrAccessibleValue', {
      keychainService: 'myKeychain',
      kSecAttrAccessible: 'kSecAttrAccessibleAlways'
    });

    SInfo.getItem('key1', {
      sharedPreferencesName: 'mySharedPrefs',
      keychainService: 'myKeychain' }).then((value) => {
        console.log(value); //value1
      });

    SInfo.getItem('key2', {}).then((value) => {
      console.log(value); //value2
    });

    SInfo.getItem('key3', {}).then((value) => {
      console.log(value); //value3
    });

    SInfo.getAllItems({
      sharedPreferencesName: 'mySharedPrefs',
      keychainService: 'myKeychain' }).then((values) => {
        console.log(values); //value1, value2
      });

    SInfo.getAllItems({}).then((values) => {
      console.log(values); //value3, value2
    });

    SInfo.deleteItem('key1', {
      sharedPreferencesName: 'mySharedPrefs',
      keychainService: 'myKeychain' }).then((values) => {
        console.log('deleted');
      });

    AppState.addEventListener('change', this.handleStateChange);
    DeviceEventEmitter.addListener('FINGERPRINT_AUTHENTICATION_HELP', this.handleAuthFeedback);
  }

  componentWillUnmount() {
    AppState.removeEventListener('change', this.handleStateChange);
    SInfo.cancelFingerprintAuth();
    DeviceEventEmitter.removeListener('FINGERPRINT_AUTHENTICATION_HELP', this.handleAuthFeedback);
  }

  async setTouchIDItem(){
    if(!await SInfo.isSensorAvailable()){
      Alert.alert('Touch Sensor not found')
      return;
    }
    if(Platform.OS === 'android'){
      this.setState({
        helpText: 'Scan your fingerprint get the item.'
      })
    }
    try{
      await SInfo.setItem('touchItem', new Date().toISOString(), {touchID: true})
    } catch (err){
      Alert.alert(err.message);
    } finally {
      if(Platform.OS === 'android'){
        this.setState({
          helpText: ''
        })
      }
    }
  }

  handleStateChange(appState) {
    switch (appState) {
      case 'background':
        this.setState({
          helpText: ''
        })
        SInfo.cancelFingerprintAuth();
    }
  }

  handleAuthFeedback(helpText) {
    this.setState({helpText});
  }

  async getTouchIDItem(){
    if(!await SInfo.isSensorAvailable()){
      Alert.alert('Touch Sensor not found')
      return;
    }
    if(Platform.OS === 'android'){
      this.setState({
        helpText: 'Scan your fingerprint get the item.'
      })
    }
    try{
      let result = await SInfo.getItem('touchItem', {
        touchID: true,
        kSecUseOperationPrompt: 'Scan your fingerprint get the item.' // this is for iOS
      })
      if(result){
        Alert.alert('Touch ID item', result);
      }
    } catch (err){
      Alert.alert(err.message);
    } finally {
      if(Platform.OS === 'android'){
        this.setState({
          helpText: ''
        })
      }
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <Text>{this.state.helpText}</Text>
        <Button
          onPress={()=>this.setTouchIDItem()}
          title="set touchID item"
        />
        <Button
          onPress={()=>this.getTouchIDItem()}
          title="get touchID item"
        />
      </View>
    );
  }
}

AppRegistry.registerComponent('example', () => example);
<|endoftext|>


<commit_before>/**
 * @fileOverview Ensures that editorconfig settings are appropriate
 */

var expect = require('expect.js'),
    editorconfig = require('editorconfig'),

    /**
     * The width (in spaces) of tabs used for indentation throughout the project
     * @type {Number}
     */
    TAB_WIDTH = 4;

/* global describe, it */
describe('.editorconfig', function () {
    var config = editorconfig.parseSync('.editorconfig'); // eslint-disable-line no-sync

    it('should have a tab_width of 4', function () {
        expect(config.tab_width).to.be(TAB_WIDTH);
    });

    it('should have a charset of utf-8', function () {
        expect(config.charset).to.be('utf-8');
    });

    it('should have an indent_size of 4', function () {
        expect(config.indent_size).to.be(TAB_WIDTH);
    });

    it('should have an indent_style of 4', function () {
        expect(config.indent_style).to.be('space');
    });

    it('should have a truthy insert_final_newline value', function () {
        expect(config.insert_final_newline).to.be(true);
    });

    it('should have a truthy trim_trailing_whitespace', function () {
        expect(config.trim_trailing_whitespace).to.be(true);
    });
});
<commit_msg>Update Editorconfig tests to chai<commit_after>/**
 * @fileOverview Ensures that editorconfig settings are appropriate
 */

var editorconfig = require('editorconfig'),

    /**
     * The width (in spaces) of tabs used for indentation throughout the project
     * @type {Number}
     */
    TAB_WIDTH = 4;

describe('.editorconfig', function () {
    var config = editorconfig.parseSync('.editorconfig'); // eslint-disable-line no-sync

    it('should have a tab_width of 4', function () {
        expect(config.tab_width).to.equal(TAB_WIDTH);
    });

    it('should have a charset of utf-8', function () {
        expect(config.charset).to.equal('utf-8');
    });

    it('should have an indent_size of 4', function () {
        expect(config.indent_size).to.equal(TAB_WIDTH);
    });

    it('should have an indent_style of 4', function () {
        expect(config.indent_style).to.equal('space');
    });

    it('should have a truthy insert_final_newline value', function () {
        expect(config.insert_final_newline, 'Should insert final line').to.be.true;
    });

    it('should have a truthy trim_trailing_whitespace', function () {
        expect(config.trim_trailing_whitespace, 'Should trim trailing whitespace').to.be.true;
    });
});
<|endoftext|>


<commit_before>//View that will drive the Students list page.

define(['modernizr', 'cookie', '../../service/DataService', 'validate', 'toggles', '../../Router', '../../Notify', '../../view/admin/AdminView','../../view/studentlist/StudentListView'], function(modernizr, cookie, service, validate, toggles, router, notify, admin, studentlist) {"use strict";

	var MembersEditView = ( function() {

			/**
			 * Constructor
			 *
			 */

			var validator;

			function MembersEditView() {

				function populateData() {

				}

				function checkForActiveCookie() {
					if (jQuery.cookie('user') && jQuery.cookie('user') !== 'home') {
						return true;
					} else {
						//Paranoid Cookie Clearing
						jQuery.removeCookie('user', {
							path : '/univ'
						});
						jQuery.removeCookie('subuser', {
							path : '/univ'
						});
						router.go('/home', '/admin');
						return false;
					}
				}

				function clearForm() {
					jQuery('#member-first-name').val('');
					jQuery('#member-last-name').val('');
					jQuery('#member-first-name').removeAttr('readonly');
					jQuery('#member-last-name').removeAttr('readonly');
					jQuery('#member-email').removeAttr('readonly');
					jQuery('#member-email').val('');
					validator.resetForm();
					jQuery('#member-first-name').focus();
				};

				this.pause = function() {

				};

				this.resume = function() {
					populateData();
					clearForm();
				};

				this.init = function(args) {
					//Check for Cookoverview-manageie before doing any thing.
					//Light weight DOM.

					if (checkForActiveCookie() === true) {

						populateData();

						//HTML Event - Actions
						jQuery('.modal_close').on('click', function() {
							router.returnToPrevious();
						});

						jQuery('#member-add').on('click', function() {
							if (!jQuery('.edit-form').valid()) {
								console.log(validator.numberOfInvalids());
							} else {
								console.log(validator.numberOfInvalids());
							}
							if (jQuery('#member-email').val().length == 0) {
								if (validator.numberOfInvalids() === 1) {
									validator.resetForm();
									var _domainid;
									service.returnDomainIDList({
										success : function(data) {
											_domainid = data;
										}
									});
									var _userid = service.thisuserID();
									service.addMemberRegular(_domainid[0], _userid, $('#member-first-name').val(), $('#member-last-name').val(), {
										success : function(data) {
											if (data.status !== 'error') {
												notify.showNotification('OK', data.message);
											} else {
												notify.showNotification('ERROR', data.message);
											}
											setTimeout(function() {
												studentlist.reload();
												router.returnToPrevious();
											}, 2000);
										}
									});
								}
							} else {
								if (validator.numberOfInvalids() == 2) {
									validator.resetForm();
									var domainname = service.returnDomainList();
									var roles = [{
										"roleName" : "ROLE_TIER3"
									}];
									service.sendInvite(jQuery('#member-email').val(), 'You are added to ' + domainname[0], domainname[0], roles, {
										success : function(response) {
											if (response !== 'error' && response.status !== 'error') {
												notify.showNotification('OK', response.message);
											} else {
												notify.showNotification('ERROR', response.message);
											}
											setTimeout(function() {
												router.returnToPrevious();
											}, 2000);
										}
									});
								}
							}
						});

						//Add and wait for more inputs:
						jQuery('#member-addmore').on('click', function() {
							if (!jQuery('.edit-form').valid()) {
								console.log(validator.numberOfInvalids());
							} else {
								console.log(validator.numberOfInvalids());
							}
							if (jQuery('#member-email').val().length == 0) {
								if (validator.numberOfInvalids() === 1) {
									validator.resetForm();
									var _domainid;
									service.returnDomainIDList({
										success : function(data) {
											_domainid = data;
										}
									});
									var _userid = service.thisuserID();
									service.addMemberRegular(_domainid[0], _userid, $('#member-first-name').val(), $('#member-last-name').val(), {
										success : function(data) {
											if (data.status !== 'error') {
												notify.showNotification('OK', data.message);
											} else {
												notify.showNotification('ERROR', data.message);
											}
											setTimeout(function() {
												clearForm();
											}, 2000);
										}
									});
								}
							} else {
								if (validator.numberOfInvalids() == 2) {
									validator.resetForm();
									var domainname = service.returnDomainList();
									var roles = [{
										"roleName" : "ROLE_TIER3"
									}];
									service.sendInvite(jQuery('#member-email').val(), 'You are added to ' + domainname[0], domainname[0], roles, {
										success : function(response) {
											if (response !== 'error' && response.status !== 'error') {
												notify.showNotification('OK', response.message);
											} else {
												notify.showNotification('ERROR', response.message);
											}
											setTimeout(function() {
												clearForm();
											}, 2000);
										}
									});
								}
							}
						});

						//Adjusting Focus:
						jQuery('#member-first-name').keyup(function() {
							if (jQuery('#member-first-name').val().length > 0 && jQuery('#member-last-name').val().length > 0) {
								jQuery('#member-email').attr('readonly', 'readonly');
							} else {
								jQuery('#member-email').removeAttr('readonly');
							}
						});
						jQuery('#member-last-name').keyup(function() {
							if (jQuery('#member-first-name').val().length > 0 && jQuery('#member-last-name').val().length > 0) {
								jQuery('#member-email').attr('readonly', 'readonly');
								jQuery('#member-email').val('');
							} else {
								jQuery('#member-email').removeAttr('readonly');
							}
						});
						jQuery('#member-email').keyup(function() {
							if (jQuery('#member-email').val().length > 0) {
								jQuery('#member-first-name').val('');
								jQuery('#member-last-name').val('');
								jQuery('#member-first-name').attr('readonly', 'readonly');
								jQuery('#member-last-name').attr('readonly', 'readonly');
							} else {
								jQuery('#member-first-name').removeAttr('readonly');
								jQuery('#member-last-name').removeAttr('readonly');
							}
						});

						jQuery('#form-reset').click(function() {
							jQuery('#member-first-name').val('');
							jQuery('#member-last-name').val('');
							jQuery('#member-first-name').removeAttr('readonly');
							jQuery('#member-last-name').removeAttr('readonly');
							jQuery('#member-email').removeAttr('readonly');
							jQuery('#member-email').val('');
							validator.resetForm();
						});

						jQuery('#member-addmore').click(function() {

						});

						validator = jQuery(".edit-form").validate({
							rules : {
								memberfirstname : {
									required : true,
								},
								memberlastname : {
									required : true,
								},
								memberemail : {
									required : true,
									email : true
								}
							}
						});

					} // Cookie Guider
				};

			}

			return MembersEditView;
		}());

	return new MembersEditView();
});
<commit_msg>Student List Reload, if Member Added<commit_after>//View that will drive the Students list page.

define(['modernizr', 'cookie', '../../service/DataService', 'validate', 'toggles', '../../Router', '../../Notify', '../../view/admin/AdminView','../../view/studentlist/StudentListView'], function(modernizr, cookie, service, validate, toggles, router, notify, admin, studentlist) {"use strict";

	var MembersEditView = ( function() {

			/**
			 * Constructor
			 *
			 */

			var validator;

			function MembersEditView() {

				function populateData() {

				}

				function checkForActiveCookie() {
					if (jQuery.cookie('user') && jQuery.cookie('user') !== 'home') {
						return true;
					} else {
						//Paranoid Cookie Clearing
						jQuery.removeCookie('user', {
							path : '/univ'
						});
						jQuery.removeCookie('subuser', {
							path : '/univ'
						});
						router.go('/home', '/admin');
						return false;
					}
				}

				function clearForm() {
					jQuery('#member-first-name').val('');
					jQuery('#member-last-name').val('');
					jQuery('#member-first-name').removeAttr('readonly');
					jQuery('#member-last-name').removeAttr('readonly');
					jQuery('#member-email').removeAttr('readonly');
					jQuery('#member-email').val('');
					validator.resetForm();
					jQuery('#member-first-name').focus();
				};

				this.pause = function() {

				};

				this.resume = function() {
					populateData();
					clearForm();
				};

				this.init = function(args) {
					//Check for Cookoverview-manageie before doing any thing.
					//Light weight DOM.

					if (checkForActiveCookie() === true) {

						populateData();

						//HTML Event - Actions
						jQuery('.modal_close').on('click', function() {
							router.returnToPrevious();
						});

						jQuery('#member-add').on('click', function() {
							if (!jQuery('.edit-form').valid()) {
								console.log(validator.numberOfInvalids());
							} else {
								console.log(validator.numberOfInvalids());
							}
							if (jQuery('#member-email').val().length == 0) {
								if (validator.numberOfInvalids() === 1) {
									validator.resetForm();
									var _domainid;
									service.returnDomainIDList({
										success : function(data) {
											_domainid = data;
										}
									});
									var _userid = service.thisuserID();
									service.addMemberRegular(_domainid[0], _userid, $('#member-first-name').val(), $('#member-last-name').val(), {
										success : function(data) {
											if (data.status !== 'error') {
												notify.showNotification('OK', data.message);
											} else {
												notify.showNotification('ERROR', data.message);
											}
											setTimeout(function() {
												studentlist.reload();
												router.returnToPrevious();
											}, 2000);
										}
									});
								}
							} else {
								if (validator.numberOfInvalids() == 2) {
									validator.resetForm();
									var domainname = service.returnDomainList();
									var roles = [{
										"roleName" : "ROLE_TIER3"
									}];
									service.sendInvite(jQuery('#member-email').val(), 'You are added to ' + domainname[0], domainname[0], roles, {
										success : function(response) {
											if (response !== 'error' && response.status !== 'error') {
												notify.showNotification('OK', response.message);
											} else {
												notify.showNotification('ERROR', response.message);
											}
											setTimeout(function() {
												router.returnToPrevious();
											}, 2000);
										}
									});
								}
							}
						});

						//Add and wait for more inputs:
						jQuery('#member-addmore').on('click', function() {
							if (!jQuery('.edit-form').valid()) {
								console.log(validator.numberOfInvalids());
							} else {
								console.log(validator.numberOfInvalids());
							}
							if (jQuery('#member-email').val().length == 0) {
								if (validator.numberOfInvalids() === 1) {
									validator.resetForm();
									var _domainid;
									service.returnDomainIDList({
										success : function(data) {
											_domainid = data;
										}
									});
									var _userid = service.thisuserID();
									service.addMemberRegular(_domainid[0], _userid, $('#member-first-name').val(), $('#member-last-name').val(), {
										success : function(data) {
											if (data.status !== 'error') {
												notify.showNotification('OK', data.message);
											} else {
												notify.showNotification('ERROR', data.message);
											}
											setTimeout(function() {
												studentlist.reload();
												clearForm();
											}, 2000);
										}
									});
								}
							} else {
								if (validator.numberOfInvalids() == 2) {
									validator.resetForm();
									var domainname = service.returnDomainList();
									var roles = [{
										"roleName" : "ROLE_TIER3"
									}];
									service.sendInvite(jQuery('#member-email').val(), 'You are added to ' + domainname[0], domainname[0], roles, {
										success : function(response) {
											if (response !== 'error' && response.status !== 'error') {
												notify.showNotification('OK', response.message);
											} else {
												notify.showNotification('ERROR', response.message);
											}
											setTimeout(function() {
												clearForm();
											}, 2000);
										}
									});
								}
							}
						});

						//Adjusting Focus:
						jQuery('#member-first-name').keyup(function() {
							if (jQuery('#member-first-name').val().length > 0 && jQuery('#member-last-name').val().length > 0) {
								jQuery('#member-email').attr('readonly', 'readonly');
							} else {
								jQuery('#member-email').removeAttr('readonly');
							}
						});
						jQuery('#member-last-name').keyup(function() {
							if (jQuery('#member-first-name').val().length > 0 && jQuery('#member-last-name').val().length > 0) {
								jQuery('#member-email').attr('readonly', 'readonly');
								jQuery('#member-email').val('');
							} else {
								jQuery('#member-email').removeAttr('readonly');
							}
						});
						jQuery('#member-email').keyup(function() {
							if (jQuery('#member-email').val().length > 0) {
								jQuery('#member-first-name').val('');
								jQuery('#member-last-name').val('');
								jQuery('#member-first-name').attr('readonly', 'readonly');
								jQuery('#member-last-name').attr('readonly', 'readonly');
							} else {
								jQuery('#member-first-name').removeAttr('readonly');
								jQuery('#member-last-name').removeAttr('readonly');
							}
						});

						jQuery('#form-reset').click(function() {
							jQuery('#member-first-name').val('');
							jQuery('#member-last-name').val('');
							jQuery('#member-first-name').removeAttr('readonly');
							jQuery('#member-last-name').removeAttr('readonly');
							jQuery('#member-email').removeAttr('readonly');
							jQuery('#member-email').val('');
							validator.resetForm();
						});

						jQuery('#member-addmore').click(function() {

						});

						validator = jQuery(".edit-form").validate({
							rules : {
								memberfirstname : {
									required : true,
								},
								memberlastname : {
									required : true,
								},
								memberemail : {
									required : true,
									email : true
								}
							}
						});

					} // Cookie Guider
				};

			}

			return MembersEditView;
		}());

	return new MembersEditView();
});
<|endoftext|>


<commit_before>
// limbus-buildgen - A "build anywhere" C/C++ makefile/project generator.
// Written in 2014 by Jesper Oskarsson jesosk@gmail.com
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain worldwide.
// This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.

var should = require('should');
var util = require('./util.js');
var shell = require('./shell.js');

describe('Linking', function () {
    beforeEach(function () {
        return util.beforeEach().then(function () {
            return shell.mkdir('temp/include');
        }).then(function () {
            return shell.copyFiles([
                'linked.c',
                'linked_dynamic.c',
                'source/mylibrary.c',
                'include/mylibrary.h',
                'source/mydynamiclibrary.c',
                'include/mydynamiclibrary.h',
                'math.c',
            ], 'features/linking/', 'temp/');
        });
    });

    afterEach(function () {
        return util.afterEach();
    });

    it('should compile and link correctly given several source files and includes', function () {
        return util.generateCompileAndRun({
            config: {
                type: 'application',
                host: process.platform,
                files: [
                    'linked.c',
                    'source/mylibrary.c'
                ],
                includePaths: [
                    'include'
                ],
                outputName: 'linked'
            },
            command: 'linked',
            expectOutputToMatch: /42/
        });
    });

    it('should pass linker flags as is', function () {
        return util.buildSimple({
            type: 'application',
            host: process.platform,
            files: ['simple.c'],
            outputName: 'app',
            linkerFlags: process.platform === 'win32' ? '/KEYFILE' : '-nostdlib'
        }).should.be.rejected();
    });

    it('should link with libm by default', function () {
        return util.generateCompileAndRun({
            config: {
                type: 'application',
                host: process.platform,
                files: [
                    'math.c'
                ],
                outputName: 'math'
            },
            command: 'math',
            expectOutputToMatch: /42/
        });
    });

    it('should compile to an executable with outputName', function () {
        return util.generateCompileAndRun({
            config: {
                type: 'application',
                host: process.platform,
                files: [
                    'simple.c'
                ],
                outputName: 'my_executable'
            },
            command: 'my_executable',
            expectOutputToMatch: /42/
        });
    });

    it('should compile a static library and then be able to link to it', function () {
        return util.generateCompileAndRun({
            config: [
                {
                    type: 'static-library',
                    host: process.platform,
                    files: [
                        'source/mylibrary.c'
                    ],
                    outputName: 'my_lib_name'
                },
                {
                    type: 'application',
                    host: process.platform,
                    files: [
                        'linked.c'
                    ],
                    libraries: [
                        'my_lib_name'
                    ],
                    includePaths: [
                        'include'
                    ],
                    outputName: 'linked_with_library'
                }
            ],
            command: 'linked_with_library',
            expectOutputToMatch: /42/
        });
    });

    it('should compile a dynamic library and then be able to link to it', function () {
        return util.generateCompileAndRun({
            config: [
                {
                    type: 'static-library',
                    host: process.platform,
                    files: [
                        'source/mylibrary.c'
                    ],
                    outputName: 'my_lib_name'
                },
                {
                    type: 'dynamic-library',
                    host: process.platform,
                    files: [
                        'source/mydynamiclibrary.c'
                    ],
                    libraries: [
                        'my_lib_name'
                    ],
                    outputName: 'my_dyn_lib_name'
                },
                {
                    type: 'application',
                    host: process.platform,
                    files: [
                        'linked_dynamic.c'
                    ],
                    libraries: [
                        'my_dyn_lib_name'
                    ],
                    includePaths: [
                        'include'
                    ],
                    // On linux systems the shared object won't be looked for in
                    // the current working directory by default. We just add a
                    // flag so that it is.
                    linkerFlags: (process.platform === 'linux') ? '-Wl,-rpath=.' : '',
                    outputName: 'linked_with_library'
                }
            ],
            command: 'linked_with_library',
            expectOutputToMatch: /42/
        });
    });
});
<commit_msg>Update linking.feature.js<commit_after>
// limbus-buildgen - A "build anywhere" C/C++ makefile/project generator.
// Written in 2014 by Jesper Oskarsson jesosk@gmail.com
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain worldwide.
// This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.

var should = require('should');
var util = require('./util.js');
var shell = require('./shell.js');

describe('Linking', function () {
    beforeEach(function () {
        return util.beforeEach().then(function () {
            return shell.mkdir('temp/include');
        }).then(function () {
            return shell.copyFiles([
                'linked.c',
                'linked_dynamic.c',
                'source/mylibrary.c',
                'include/mylibrary.h',
                'source/mydynamiclibrary.c',
                'include/mydynamiclibrary.h',
                'math.c',
            ], 'features/linking/', 'temp/');
        });
    });

    afterEach(function () {
        return util.afterEach();
    });

    it('should compile and link correctly given several source files and includes', function () {
        return util.generateCompileAndRun({
            config: {
                type: 'application',
                host: process.platform,
                files: [
                    'linked.c',
                    'source/mylibrary.c'
                ],
                includePaths: [
                    'include'
                ],
                outputName: 'linked'
            },
            command: 'linked',
            expectOutputToMatch: /42/
        });
    });

    it('should pass linker flags as is', function () {
        return util.buildSimple({
            type: 'application',
            host: process.platform,
            files: ['simple.c'],
            outputName: 'app',
            linkerFlags: process.platform === 'win32' ? '/NODEFAULTLIB' : '-nostdlib'
        }).should.be.rejected();
    });

    it('should link with libm by default', function () {
        return util.generateCompileAndRun({
            config: {
                type: 'application',
                host: process.platform,
                files: [
                    'math.c'
                ],
                outputName: 'math'
            },
            command: 'math',
            expectOutputToMatch: /42/
        });
    });

    it('should compile to an executable with outputName', function () {
        return util.generateCompileAndRun({
            config: {
                type: 'application',
                host: process.platform,
                files: [
                    'simple.c'
                ],
                outputName: 'my_executable'
            },
            command: 'my_executable',
            expectOutputToMatch: /42/
        });
    });

    it('should compile a static library and then be able to link to it', function () {
        return util.generateCompileAndRun({
            config: [
                {
                    type: 'static-library',
                    host: process.platform,
                    files: [
                        'source/mylibrary.c'
                    ],
                    outputName: 'my_lib_name'
                },
                {
                    type: 'application',
                    host: process.platform,
                    files: [
                        'linked.c'
                    ],
                    libraries: [
                        'my_lib_name'
                    ],
                    includePaths: [
                        'include'
                    ],
                    outputName: 'linked_with_library'
                }
            ],
            command: 'linked_with_library',
            expectOutputToMatch: /42/
        });
    });

    it('should compile a dynamic library and then be able to link to it', function () {
        return util.generateCompileAndRun({
            config: [
                {
                    type: 'static-library',
                    host: process.platform,
                    files: [
                        'source/mylibrary.c'
                    ],
                    outputName: 'my_lib_name'
                },
                {
                    type: 'dynamic-library',
                    host: process.platform,
                    files: [
                        'source/mydynamiclibrary.c'
                    ],
                    libraries: [
                        'my_lib_name'
                    ],
                    outputName: 'my_dyn_lib_name'
                },
                {
                    type: 'application',
                    host: process.platform,
                    files: [
                        'linked_dynamic.c'
                    ],
                    libraries: [
                        'my_dyn_lib_name'
                    ],
                    includePaths: [
                        'include'
                    ],
                    // On linux systems the shared object won't be looked for in
                    // the current working directory by default. We just add a
                    // flag so that it is.
                    linkerFlags: (process.platform === 'linux') ? '-Wl,-rpath=.' : '',
                    outputName: 'linked_with_library'
                }
            ],
            command: 'linked_with_library',
            expectOutputToMatch: /42/
        });
    });
});
<|endoftext|>