<commit_before>/*********************************************
 *  Copyright (c) 2014 AnsibleWorks, Inc.
 *
 *  HostEventsViewer.js
 *
 *  View a list of events for a given job and host
 *
 */

'use strict';

angular.module('HostEventsViewerHelper', ['ModalDialog', 'Utilities', 'EventViewerHelper'])

    .factory('HostEventsViewer', ['$log', '$compile', 'CreateDialog', 'Wait', 'GetBasePath', 'Empty', 'GetEvents', 'EventViewer',
    function($log, $compile, CreateDialog, Wait, GetBasePath, Empty, GetEvents, EventViewer) {
        return function(params) {
            var parent_scope = params.scope,
                scope = parent_scope.$new(true),
                job_id = params.job_id,
                url = params.url,
                title = params.title, //optional
                fixHeight, buildTable,
                lastID, setStatus, buildRow, status;

            // initialize the status dropdown
            scope.host_events_status_options = [
                { value: "all", name: "All" },
                { value: "changed", name: "Changed" },
                { value: "failed", name: "Failed" },
                { value: "ok", name: "OK" },
                { value: "unreachable", name: "Unreachable" }
                ];
            scope.host_events_search_name = params.name;
            status = (params.status) ?  params.status : 'all';
            scope.host_events_status_options.every(function(opt, idx) {
                if (opt.value === status) {
                    scope.host_events_search_status = scope.host_events_status_options[idx];
                    return false;
                }
                return true;
            });
            if (!scope.host_events_search_status) {
                scope.host_events_search_status = scope.host_events_status_options[0];
            }

            $log.debug('job_id: ' + job_id + ' url: ' + url + ' title: ' + title + ' name: ' + name + ' status: ' + status);

            scope.eventsSearchActive = (scope.host_events_search_name) ? true : false;

            if (scope.removeModalReady) {
                scope.removeModalReady();
            }
            scope.removeModalReady = scope.$on('ModalReady', function() {
                scope.hostViewSearching = false;
                $('#host-events-modal-dialog').dialog('open');
            });

            if (scope.removeJobReady) {
                scope.removeJobReady();
            }
            scope.removeEventReady = scope.$on('EventsReady', function(e, data, maxID) {
                var elem, html;

                lastID = maxID;
                html = buildTable(data);
                $('#host-events').html(html);
                elem = angular.element(document.getElementById('host-events-modal-dialog'));
                $compile(elem)(scope);

                CreateDialog({
                    scope: scope,
                    width: 675,
                    height: 600,
                    minWidth: 450,
                    callback: 'ModalReady',
                    id: 'host-events-modal-dialog',
                    onResizeStop: fixHeight,
                    title: ( (title) ? title : 'Host Events' ),
                    onClose: function() {
                        try {
                            scope.$destroy();
                        }
                        catch(e) {
                            //ignore
                        }
                    },
                    onOpen: function() {
                        fixHeight();
                    }
                });
            });

            if (scope.removeRefreshHTML) {
                scope.removeRefreshHTML();
            }
            scope.removeRefreshHTML = scope.$on('RefreshHTML', function(e, data) {
                var elem, html = buildTable(data);
                $('#host-events').html(html);
                scope.hostViewSearching = false;
                elem = angular.element(document.getElementById('host-events'));
                $compile(elem)(scope);
            });

            setStatus = function(result) {
                var msg = '', status = 'ok', status_text = 'OK';
                if (!result.task && result.event_data && result.event_data.res && result.event_data.res.ansible_facts) {
                    result.task = "Gathering Facts";
                }
                if (result.event === "runner_on_no_hosts") {
                    msg = "No hosts remaining";
                }
                if (result.event === 'runner_on_unreachable') {
                    status = 'unreachable';
                    status_text = 'Unreachable';
                }
                else if (result.failed) {
                    status = 'failed';
                    status_text = 'Failed';
                }
                else if (result.changed) {
                    status = 'changed';
                    status_text = 'Changed';
                }
                if (result.event_data.res && result.event_data.res.msg) {
                    msg = result.event_data.res.msg;
                }
                result.msg = msg;
                result.status = status;
                result.status_text = status_text;
                return result;
            };

            buildRow = function(res) {
                var html = '';
                html += "
\n";
                html += " " + res.status_text + "	\n";
                html += "" + res.host_name + "	\n";
                html += "" + res.play + "	\n";
                html += "" + res.task + "	\n";
                html += "
";
                return html;
            };

            buildTable = function(data) {
                var html = "
\n";
                html += "
\n";
                data.results.forEach(function(result) {
                    var res = setStatus(result);
                    html += buildRow(res);
                });
                html += "
\n";
                html += "
\n";
                return html;
            };

            fixHeight = function() {
                var available_height = $('#host-events-modal-dialog').height() - $('#host-events-modal-dialog #search-form').height() - $('#host-events-modal-dialog #fixed-table-header').height();
                $('#host-events').height(available_height);
                $log.debug('set height to: ' + available_height);
                // Check width and reset search fields
                if ($('#host-events-modal-dialog').width() <= 450) {
                    $('#host-events-modal-dialog #status-field').css({'margin-left': '7px'});
                }
                else {
                    $('#host-events-modal-dialog #status-field').css({'margin-left': '15px'});
                }
            };

            GetEvents({
                url: url,
                scope: scope,
                callback: 'EventsReady'
            });

            scope.modalOK = function() {
                $('#host-events-modal-dialog').dialog('close');
                scope.$destroy();
            };

            scope.searchEvents = function() {
                scope.eventsSearchActive = (scope.host_events_search_name) ? true : false;
                GetEvents({
                    scope: scope,
                    url: url,
                    callback: 'RefreshHTML'
                });
            };

            scope.searchEventKeyPress = function(e) {
                if (e.keyCode === 13) {
                    scope.searchEvents();
                }
            };

            scope.showDetails = function(id) {
                EventViewer({
                    scope: parent_scope,
                    url: GetBasePath('jobs') + job_id + '/job_events/?id=' + id,
                });
            };

            if (scope.removeEventsScrollDownBuild) {
                scope.removeEventsScrollDownBuild();
            }
            scope.removeEventsScrollDownBuild = scope.$on('EventScrollDownBuild', function(e, data, maxID) {
                var elem, html = '';
                lastID = maxID;
                data.results.forEach(function(result) {
                    var res = setStatus(result);
                    html += buildRow(res);
                });
                if (html) {
                    $('#host-events table tbody').append(html);
                    elem = angular.element(document.getElementById('host-events'));
                    $compile(elem)(scope);
                }
            });

            scope.hostEventsScrollDown = function() {
                GetEvents({
                    scope: scope,
                    url: url,
                    gt: lastID,
                    callback: 'EventScrollDownBuild'
                });
            };

        };
    }])

    .factory('GetEvents', ['Rest', 'ProcessErrors', function(Rest, ProcessErrors) {
        return function(params) {
            var url = params.url,
                scope = params.scope,
                gt = params.gt,
                callback = params.callback;

            if (scope.host_events_search_name) {
                url += '?host_name=' + scope.host_events_search_name;
            }
            else {
                url += '?host_name__isnull=false';
            }

            if (scope.host_events_search_status.value === 'changed') {
                url += '&event__icontains=runner&changed=true';
            }
            else if (scope.host_events_search_status.value === 'failed') {
                url += '&event__icontains=runner&failed=true';
            }
            else if (scope.host_events_search_status.value === 'ok') {
                url += '&event=runner_on_ok&changed=false';
            }
            else if (scope.host_events_search_status.value === 'unreachable') {
                url += '&event=runner_on_unreachable';
            }
            else if (scope.host_events_search_status.value === 'all') {
                url += '&event__icontains=runner&not__event=runner_on_skipped';
            }

            if (gt) {
                // used for endless scroll
                url += '&id__gt=' + gt;
            }

            url += '&page_size=50&order=id';

            scope.hostViewSearching = true;
            Rest.setUrl(url);
            Rest.get()
                .success(function(data) {
                    var lastID;
                    scope.hostViewSearching = false;
                    if (data.results.length > 0) {
                        lastID = data.results[data.results.length - 1].id;
                    }
                    scope.$emit(callback, data, lastID);
                })
                .error(function(data, status) {
                    scope.hostViewSearching = false;
                    ProcessErrors(scope, data, status, null, { hdr: 'Error!',
                        msg: 'Failed to get events ' + url + '. GET returned: ' + status });
                });
        };
    }]);
<commit_msg>Fixed jshint error<commit_after>/*********************************************
 *  Copyright (c) 2014 AnsibleWorks, Inc.
 *
 *  HostEventsViewer.js
 *
 *  View a list of events for a given job and host
 *
 */

'use strict';

angular.module('HostEventsViewerHelper', ['ModalDialog', 'Utilities', 'EventViewerHelper'])

    .factory('HostEventsViewer', ['$log', '$compile', 'CreateDialog', 'Wait', 'GetBasePath', 'Empty', 'GetEvents', 'EventViewer',
    function($log, $compile, CreateDialog, Wait, GetBasePath, Empty, GetEvents, EventViewer) {
        return function(params) {
            var parent_scope = params.scope,
                scope = parent_scope.$new(true),
                job_id = params.job_id,
                url = params.url,
                title = params.title, //optional
                fixHeight, buildTable,
                lastID, setStatus, buildRow, status;

            // initialize the status dropdown
            scope.host_events_status_options = [
                { value: "all", name: "All" },
                { value: "changed", name: "Changed" },
                { value: "failed", name: "Failed" },
                { value: "ok", name: "OK" },
                { value: "unreachable", name: "Unreachable" }
            ];
            scope.host_events_search_name = params.name;
            status = (params.status) ?  params.status : 'all';
            scope.host_events_status_options.every(function(opt, idx) {
                if (opt.value === status) {
                    scope.host_events_search_status = scope.host_events_status_options[idx];
                    return false;
                }
                return true;
            });
            if (!scope.host_events_search_status) {
                scope.host_events_search_status = scope.host_events_status_options[0];
            }

            $log.debug('job_id: ' + job_id + ' url: ' + url + ' title: ' + title + ' name: ' + name + ' status: ' + status);

            scope.eventsSearchActive = (scope.host_events_search_name) ? true : false;

            if (scope.removeModalReady) {
                scope.removeModalReady();
            }
            scope.removeModalReady = scope.$on('ModalReady', function() {
                scope.hostViewSearching = false;
                $('#host-events-modal-dialog').dialog('open');
            });

            if (scope.removeJobReady) {
                scope.removeJobReady();
            }
            scope.removeEventReady = scope.$on('EventsReady', function(e, data, maxID) {
                var elem, html;

                lastID = maxID;
                html = buildTable(data);
                $('#host-events').html(html);
                elem = angular.element(document.getElementById('host-events-modal-dialog'));
                $compile(elem)(scope);

                CreateDialog({
                    scope: scope,
                    width: 675,
                    height: 600,
                    minWidth: 450,
                    callback: 'ModalReady',
                    id: 'host-events-modal-dialog',
                    onResizeStop: fixHeight,
                    title: ( (title) ? title : 'Host Events' ),
                    onClose: function() {
                        try {
                            scope.$destroy();
                        }
                        catch(e) {
                            //ignore
                        }
                    },
                    onOpen: function() {
                        fixHeight();
                    }
                });
            });

            if (scope.removeRefreshHTML) {
                scope.removeRefreshHTML();
            }
            scope.removeRefreshHTML = scope.$on('RefreshHTML', function(e, data) {
                var elem, html = buildTable(data);
                $('#host-events').html(html);
                scope.hostViewSearching = false;
                elem = angular.element(document.getElementById('host-events'));
                $compile(elem)(scope);
            });

            setStatus = function(result) {
                var msg = '', status = 'ok', status_text = 'OK';
                if (!result.task && result.event_data && result.event_data.res && result.event_data.res.ansible_facts) {
                    result.task = "Gathering Facts";
                }
                if (result.event === "runner_on_no_hosts") {
                    msg = "No hosts remaining";
                }
                if (result.event === 'runner_on_unreachable') {
                    status = 'unreachable';
                    status_text = 'Unreachable';
                }
                else if (result.failed) {
                    status = 'failed';
                    status_text = 'Failed';
                }
                else if (result.changed) {
                    status = 'changed';
                    status_text = 'Changed';
                }
                if (result.event_data.res && result.event_data.res.msg) {
                    msg = result.event_data.res.msg;
                }
                result.msg = msg;
                result.status = status;
                result.status_text = status_text;
                return result;
            };

            buildRow = function(res) {
                var html = '';
                html += "
\n";
                html += " " + res.status_text + "	\n";
                html += "" + res.host_name + "	\n";
                html += "" + res.play + "	\n";
                html += "" + res.task + "	\n";
                html += "
";
                return html;
            };

            buildTable = function(data) {
                var html = "
\n";
                html += "
\n";
                data.results.forEach(function(result) {
                    var res = setStatus(result);
                    html += buildRow(res);
                });
                html += "
\n";
                html += "
\n";
                return html;
            };

            fixHeight = function() {
                var available_height = $('#host-events-modal-dialog').height() - $('#host-events-modal-dialog #search-form').height() - $('#host-events-modal-dialog #fixed-table-header').height();
                $('#host-events').height(available_height);
                $log.debug('set height to: ' + available_height);
                // Check width and reset search fields
                if ($('#host-events-modal-dialog').width() <= 450) {
                    $('#host-events-modal-dialog #status-field').css({'margin-left': '7px'});
                }
                else {
                    $('#host-events-modal-dialog #status-field').css({'margin-left': '15px'});
                }
            };

            GetEvents({
                url: url,
                scope: scope,
                callback: 'EventsReady'
            });

            scope.modalOK = function() {
                $('#host-events-modal-dialog').dialog('close');
                scope.$destroy();
            };

            scope.searchEvents = function() {
                scope.eventsSearchActive = (scope.host_events_search_name) ? true : false;
                GetEvents({
                    scope: scope,
                    url: url,
                    callback: 'RefreshHTML'
                });
            };

            scope.searchEventKeyPress = function(e) {
                if (e.keyCode === 13) {
                    scope.searchEvents();
                }
            };

            scope.showDetails = function(id) {
                EventViewer({
                    scope: parent_scope,
                    url: GetBasePath('jobs') + job_id + '/job_events/?id=' + id,
                });
            };

            if (scope.removeEventsScrollDownBuild) {
                scope.removeEventsScrollDownBuild();
            }
            scope.removeEventsScrollDownBuild = scope.$on('EventScrollDownBuild', function(e, data, maxID) {
                var elem, html = '';
                lastID = maxID;
                data.results.forEach(function(result) {
                    var res = setStatus(result);
                    html += buildRow(res);
                });
                if (html) {
                    $('#host-events table tbody').append(html);
                    elem = angular.element(document.getElementById('host-events'));
                    $compile(elem)(scope);
                }
            });

            scope.hostEventsScrollDown = function() {
                GetEvents({
                    scope: scope,
                    url: url,
                    gt: lastID,
                    callback: 'EventScrollDownBuild'
                });
            };

        };
    }])

    .factory('GetEvents', ['Rest', 'ProcessErrors', function(Rest, ProcessErrors) {
        return function(params) {
            var url = params.url,
                scope = params.scope,
                gt = params.gt,
                callback = params.callback;

            if (scope.host_events_search_name) {
                url += '?host_name=' + scope.host_events_search_name;
            }
            else {
                url += '?host_name__isnull=false';
            }

            if (scope.host_events_search_status.value === 'changed') {
                url += '&event__icontains=runner&changed=true';
            }
            else if (scope.host_events_search_status.value === 'failed') {
                url += '&event__icontains=runner&failed=true';
            }
            else if (scope.host_events_search_status.value === 'ok') {
                url += '&event=runner_on_ok&changed=false';
            }
            else if (scope.host_events_search_status.value === 'unreachable') {
                url += '&event=runner_on_unreachable';
            }
            else if (scope.host_events_search_status.value === 'all') {
                url += '&event__icontains=runner&not__event=runner_on_skipped';
            }

            if (gt) {
                // used for endless scroll
                url += '&id__gt=' + gt;
            }

            url += '&page_size=50&order=id';

            scope.hostViewSearching = true;
            Rest.setUrl(url);
            Rest.get()
                .success(function(data) {
                    var lastID;
                    scope.hostViewSearching = false;
                    if (data.results.length > 0) {
                        lastID = data.results[data.results.length - 1].id;
                    }
                    scope.$emit(callback, data, lastID);
                })
                .error(function(data, status) {
                    scope.hostViewSearching = false;
                    ProcessErrors(scope, data, status, null, { hdr: 'Error!',
                        msg: 'Failed to get events ' + url + '. GET returned: ' + status });
                });
        };
    }]);
<|endoftext|>


<commit_before>/**
 *  Copyright (C) 2017 3D Repo Ltd
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.ap
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

(() => {
	"use strict";

	// calulate how many weeks an issue has been created.
	// 0 - <=1 = week 1
	// >1 - <=2 = week 2
	// ...

	module.exports = {
		'$ceil': {
			'$divide': [
				{'$subtract': [new Date().valueOf(), '$$CURRENT.created']},
				// one week in milliseconds
				604800000
			]
		}
	};

})();<commit_msg>ISSUE #340 - correct comments<commit_after>/**
 *  Copyright (C) 2017 3D Repo Ltd
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.ap
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

(() => {
	"use strict";

	// calulate how many weeks an issue has been created.
	// 0 - <=1 = week 0
	// >1 - <=2 = week 1
	// ...

	module.exports = {
		'$ceil': {
			'$divide': [
				{'$subtract': [new Date().valueOf(), '$$CURRENT.created']},
				// one week in milliseconds
				604800000
			]
		}
	};

})();<|endoftext|>


<commit_before>'use strict';

require('module-alias/register');

const os = require('os');
const path = require('path');

exports['default'] = {
    servers: {
        web: (api) => {
            let uploadDir = () => {
                let base = process.env.MCDIR;
                return base ? path.join(base.split(':')[0], 'uploadTmp') : os.tmpdir();
            };
            return {
                enabled: true,
                // HTTP or HTTPS?
                secure: false,
                // Passed to https.createServer if secure=true. Should contain SSL certificates
                serverOptions: {},
                // Should we redirect all traffic to the first host in this array if hte request header doesn't match?
                // i.e.: [ 'https://www.site.com' ]
                allowedRequestHosts: process.env.ALLOWED_HOSTS ? process.env.ALLOWED_HOSTS.split(',') : [],
                // Port or Socket Path
                port: process.env.MCAPID_PORT || 5028,
                // Which IP to listen on (use '0.0.0.0' for all; '::' for all on ipv4 and ipv6)
                // Set to `null` when listening to socket
                bindIP: '127.0.0.1',
                // Any additional headers you want actionhero to respond with
                httpHeaders: {
                    'X-Powered-By': api.config.general.serverName,
                    'Access-Control-Allow-Origin': '*',
                    'Access-Control-Allow-Methods': 'HEAD, GET, POST, PUT, PATCH, DELETE, OPTIONS, TRACE',
                    'Access-Control-Allow-Headers': 'Content-Type'
                },
                // Route that actions will be served from; secondary route against this route will be treated as actions,
                //  IE: /api/?action=test == /api/test/
                urlPathForActions: 'api',
                // Route that static files will be served from;
                //  path (relative to your project root) to serve static content from
                //  set to `null` to disable the file server entirely
                urlPathForFiles: 'public',
                // When visiting the root URL, should visitors see 'api' or 'file'?
                //  Visitors can always visit /api and /public as normal
                rootEndpointType: 'file',
                // simple routing also adds an 'all' route which matches /api/:action for all actions
                simpleRouting: true,
                // queryRouting allows an action to be defined via a URL param, ie: /api?action=:action
                queryRouting: true,
                // The cache or (if etags are enabled) next-revalidation time to be returned for all flat files served from /public; defined in seconds
                flatFileCacheDuration: 60,
                // Add an etag header to requested flat files which acts as fingerprint that changes when the file is updated;
                // Client will revalidate the fingerprint at latest after flatFileCacheDuration and reload it if the etag (and therfore the file) changed
                // or continue to use the cached file if it's still valid
                enableEtag: true,
                // should we save the un-parsed HTTP POST/PUT payload to connection.rawConnection.params.rawBody?
                saveRawBody: false,
                // How many times should we try to boot the server?
                // This might happen if the port is in use by another process or the socketfile is claimed
                bootAttempts: 1,
                // Settings for determining the id of an http(s) request (browser-fingerprint)
                fingerprintOptions: {
                    cookieKey: 'sessionID',
                    toSetCookie: true,
                    onlyStaticElements: false,
                    settings: {
                        path: '/',
                        expires: 3600000
                    }
                },
                // Options to be applied to incoming file uploads.
                //  More options and details at https://github.com/felixge/node-formidable
                formOptions: {
                    uploadDir: uploadDir(),
                    keepExtensions: true,
                    maxFieldsSize: 1024 * 1024 * 20,
                    maxFileSize: 1024 * 1024 * 200,
                    hash: 'md5',
                },
                // Should we pad JSON responses with whitespace to make them more human-readable?
                // set to null to disable
                padding: 2,
                // Options to configure metadata in responses
                metadataOptions: {
                    serverInformation: true,
                    requesterInformation: true
                },
                // When true, returnErrorCodes will modify the response header for http(s) clients if connection.error is not null.
                // You can also set connection.rawConnection.responseHttpCode to specify a code per request.
                returnErrorCodes: true,
                // should this node server attempt to gzip responses if the client can accept them?
                // this will slow down the performance of actionhero, and if you need this funcionality, it is recommended that you do this upstream with nginx or your load balancer
                compress: false,
                // options to pass to the query parser
                // learn more about the options @ https://github.com/hapijs/qs
                queryParseOptions: {}
            };
        }
    }
};

exports.production = {
    servers: {
        web: (api) => {
            return {
                padding: null,
                metadataOptions: {
                    serverInformation: false,
                    requesterInformation: false
                }
            };
        }
    }
};

exports.test = {
    servers: {
        web: (api) => {
            return {
                secure: false,
                port: 18080 + parseInt(process.env.JEST_WORKER_ID || 0),
                matchExtensionMime: true,
                metadataOptions: {
                    serverInformation: true,
                    requesterInformation: true
                }
            };
        }
    }
};
<commit_msg>Add comment describing why module-alias is registered in the web.js config file<commit_after>'use strict';

// module-alias is registered here in config because I surmised that
// config is loaded before any other modules. This allows us to register
// module aliases early and use them in the rest of the code.
//
// The module-alias package allows us to get rid of requires such as
// const x = require('../../lib/common/x) and replace it with
// const x = require('@lib/common/x')
// To see the aliases look in package.json - "_moduleAliases"
//
require('module-alias/register');

const os = require('os');
const path = require('path');

exports['default'] = {
    servers: {
        web: (api) => {
            let uploadDir = () => {
                let base = process.env.MCDIR;
                return base ? path.join(base.split(':')[0], 'uploadTmp') : os.tmpdir();
            };
            return {
                enabled: true,
                // HTTP or HTTPS?
                secure: false,
                // Passed to https.createServer if secure=true. Should contain SSL certificates
                serverOptions: {},
                // Should we redirect all traffic to the first host in this array if hte request header doesn't match?
                // i.e.: [ 'https://www.site.com' ]
                allowedRequestHosts: process.env.ALLOWED_HOSTS ? process.env.ALLOWED_HOSTS.split(',') : [],
                // Port or Socket Path
                port: process.env.MCAPID_PORT || 5028,
                // Which IP to listen on (use '0.0.0.0' for all; '::' for all on ipv4 and ipv6)
                // Set to `null` when listening to socket
                bindIP: '127.0.0.1',
                // Any additional headers you want actionhero to respond with
                httpHeaders: {
                    'X-Powered-By': api.config.general.serverName,
                    'Access-Control-Allow-Origin': '*',
                    'Access-Control-Allow-Methods': 'HEAD, GET, POST, PUT, PATCH, DELETE, OPTIONS, TRACE',
                    'Access-Control-Allow-Headers': 'Content-Type'
                },
                // Route that actions will be served from; secondary route against this route will be treated as actions,
                //  IE: /api/?action=test == /api/test/
                urlPathForActions: 'api',
                // Route that static files will be served from;
                //  path (relative to your project root) to serve static content from
                //  set to `null` to disable the file server entirely
                urlPathForFiles: 'public',
                // When visiting the root URL, should visitors see 'api' or 'file'?
                //  Visitors can always visit /api and /public as normal
                rootEndpointType: 'file',
                // simple routing also adds an 'all' route which matches /api/:action for all actions
                simpleRouting: true,
                // queryRouting allows an action to be defined via a URL param, ie: /api?action=:action
                queryRouting: true,
                // The cache or (if etags are enabled) next-revalidation time to be returned for all flat files served from /public; defined in seconds
                flatFileCacheDuration: 60,
                // Add an etag header to requested flat files which acts as fingerprint that changes when the file is updated;
                // Client will revalidate the fingerprint at latest after flatFileCacheDuration and reload it if the etag (and therfore the file) changed
                // or continue to use the cached file if it's still valid
                enableEtag: true,
                // should we save the un-parsed HTTP POST/PUT payload to connection.rawConnection.params.rawBody?
                saveRawBody: false,
                // How many times should we try to boot the server?
                // This might happen if the port is in use by another process or the socketfile is claimed
                bootAttempts: 1,
                // Settings for determining the id of an http(s) request (browser-fingerprint)
                fingerprintOptions: {
                    cookieKey: 'sessionID',
                    toSetCookie: true,
                    onlyStaticElements: false,
                    settings: {
                        path: '/',
                        expires: 3600000
                    }
                },
                // Options to be applied to incoming file uploads.
                //  More options and details at https://github.com/felixge/node-formidable
                formOptions: {
                    uploadDir: uploadDir(),
                    keepExtensions: true,
                    maxFieldsSize: 1024 * 1024 * 20,
                    maxFileSize: 1024 * 1024 * 200,
                    hash: 'md5',
                },
                // Should we pad JSON responses with whitespace to make them more human-readable?
                // set to null to disable
                padding: 2,
                // Options to configure metadata in responses
                metadataOptions: {
                    serverInformation: true,
                    requesterInformation: true
                },
                // When true, returnErrorCodes will modify the response header for http(s) clients if connection.error is not null.
                // You can also set connection.rawConnection.responseHttpCode to specify a code per request.
                returnErrorCodes: true,
                // should this node server attempt to gzip responses if the client can accept them?
                // this will slow down the performance of actionhero, and if you need this funcionality, it is recommended that you do this upstream with nginx or your load balancer
                compress: false,
                // options to pass to the query parser
                // learn more about the options @ https://github.com/hapijs/qs
                queryParseOptions: {}
            };
        }
    }
};

exports.production = {
    servers: {
        web: (api) => {
            return {
                padding: null,
                metadataOptions: {
                    serverInformation: false,
                    requesterInformation: false
                }
            };
        }
    }
};

exports.test = {
    servers: {
        web: (api) => {
            return {
                secure: false,
                port: 18080 + parseInt(process.env.JEST_WORKER_ID || 0),
                matchExtensionMime: true,
                metadataOptions: {
                    serverInformation: true,
                    requesterInformation: true
                }
            };
        }
    }
};
<|endoftext|>


<commit_before><commit_msg>setting precision by kbd misses 1 column #3787<commit_after><|endoftext|>


<commit_before>export default function workerSpawner (params, rawData) {
  const {transferable} = params
  const mode = transferable ? 'transferable' : 'copy'
  const worker = new Worker('src/worker.js')
  let startTime
  let endTime

  worker.onmessage = function (event) {
    //console.log('on message', event.data)
    //console.log('data size', event.data.positions.byteLength)
    // const positions = new Float32Array(event.data.positions)
    // const normals = new Float32Array(event.data.normals)
    endTime = new Date()

    console.log(`Mode: ${mode},  elapsed: `, endTime - startTime)
  }

  worker.onerror = function (event) {
    console.error(event)
  // console.error(`filename:${event.filename} lineno: ${event.lineno} error: ${event.message}`)
  }

  // let data = {size: 999999999, data: rawData} // 1048576*128}
  const data = rawData
  //console.log('rawData', rawData)
  startTime = new Date()

  if (transferable) {
    console.log('sending data to worker in transferable mode')
    worker.postMessage(data, [data])
  } else {
    console.log('sending data to worker in copy mode')
    worker.postMessage(data)
  }
}
<commit_msg>feat(workerSpawner): added clearer message to distinguish between non stream/stream runners<commit_after>export default function workerSpawner (params, rawData) {
  const {transferable} = params
  const mode = transferable ? 'standard transferable' : 'standard copy'
  const worker = new Worker('src/worker.js')
  let startTime
  let endTime

  worker.onmessage = function (event) {
    //console.log('on message', event.data)
    //console.log('data size', event.data.positions.byteLength)
    // const positions = new Float32Array(event.data.positions)
    // const normals = new Float32Array(event.data.normals)
    endTime = new Date()

    console.log(`Mode: ${mode},  elapsed: `, endTime - startTime)
  }

  worker.onerror = function (event) {
    console.error(event)
  // console.error(`filename:${event.filename} lineno: ${event.lineno} error: ${event.message}`)
  }

  // let data = {size: 999999999, data: rawData} // 1048576*128}
  const data = rawData
  //console.log('rawData', rawData)
  startTime = new Date()

  if (transferable) {
    console.log('sending data to worker in transferable mode')
    worker.postMessage(data, [data])
  } else {
    console.log('sending data to worker in copy mode')
    worker.postMessage(data)
  }
}
<|endoftext|>


<commit_before>/* -*- mode: espresso; espresso-indent-level: 2; indent-tabs-mode: nil -*- */
/* vim: set softtabstop=2 shiftwidth=2 tabstop=2 expandtab: */

(function(CATMAID) {

  "use strict";

  var ConnectivityMatrixWidget = function() {
    this.widgetID = this.registerInstance();
    this.matrix = new CATMAID.ConnectivityMatrix();
    this.rowDimension = new CATMAID.BasicSkeletonSource(this.getName() + " Rows");
    this.colDimension = new CATMAID.BasicSkeletonSource(this.getName() + " Columns");
  };

  ConnectivityMatrixWidget.prototype = {};
  $.extend(ConnectivityMatrixWidget.prototype, new InstanceRegistry());

  // Make connectivity matrix widget available in CATMAID namespace
  CATMAID.ConnectivityMatrixWidget = ConnectivityMatrixWidget;

  /* Implement interfaces */

  ConnectivityMatrixWidget.prototype.getName = function()
  {
    return "Connectivity Matrix " + this.widgetID;
  };

  /**
   * Handle destruction of widget.
   */
  ConnectivityMatrixWidget.prototype.destroy = function() {
    NeuronNameService.getInstance().unregister(this);
    this.content = null;
    this.rowDimension.destroy();
    this.colDimension.destroy();
    this.unregisterInstance();
  };

  /* Non-interface methods */

  /**
   * Create an object with all relevant information for creating a CATMAID
   * widget. All methods can expect to be executed in the context of this
   * object.
   */
  ConnectivityMatrixWidget.prototype.getWidgetConfiguration = function() {
    return {
      class: 'connectivity_matrix',
      controlsID: 'connectivity_matrix_controls' + this.widgetID,
      contentID: 'connectivity_matrix' + this.widgetID,

      /**
       * Create widget controls.
       */
      createControls: function(controls) {
        // Create hidden select elements for row and column sources
        var rowSelect = CATMAID.skeletonListSources.createSelect(this.rowDimension);
        rowSelect.style.display = 'none';
        controls.appendChild(rowSelect);
        var colSelect = CATMAID.skeletonListSources.createSelect(this.colDimension);
        colSelect.style.display = 'none';
        controls.appendChild(colSelect);

        // This UI combines two skeleton source selects into one.
        controls.appendChild(document.createTextNode('From'));
        var sourceSelect = CATMAID.skeletonListSources.createSelect(this,
           [this.rowDimension.getName(), this.colDimension.getName()]);
        controls.appendChild(sourceSelect);
        sourceSelect.onchange = function() {
          rowSelect.value = this.value;
          colSelect.value = this.value;
        };

        /**
         * Load rows and/or coulmns and refresh.
         */
        var loadWith = function(withRows, withCols) {
          if (withRows) this.rowDimension.loadSource();
          if (withCols) this.colDimension.loadSource();
          if (withRows || withCols) this.refresh();
        };

        var loadRows = document.createElement('input');
        loadRows.setAttribute("type", "button");
        loadRows.setAttribute("value", "Append rows");
        loadRows.onclick = loadWith.bind(this, true, false);
        controls.appendChild(loadRows);

        var loadColumns = document.createElement('input');
        loadColumns.setAttribute("type", "button");
        loadColumns.setAttribute("value", "Append columns");
        loadColumns.onclick = loadWith.bind(this, false, true);
        controls.appendChild(loadColumns);

        var loadAll = document.createElement('input');
        loadAll.setAttribute("type", "button");
        loadAll.setAttribute("value", "Append to both");
        loadAll.onclick = loadWith.bind(this, true, true);
        controls.appendChild(loadAll);

        var clear = document.createElement('input');
        clear.setAttribute("type", "button");
        clear.setAttribute("value", "Clear");
        clear.onclick = (function() {
          if (confirm("Do you really want to clear the current selection?")) {
            this.clear();
          }
        }).bind(this);
        controls.appendChild(clear);

        var update = document.createElement('input');
        update.setAttribute("type", "button");
        update.setAttribute("value", "Refresh");
        update.onclick = this.refresh.bind(this);
        controls.appendChild(update);
      },

      /**
       * Create widget content.
       */
      createContent: function(container) {
        this.content = container;
        this.refresh();
      }
    };
  };

  /**
   * Clear all sources.
   */
  ConnectivityMatrixWidget.prototype.clear = function() {
    this.rowDimension.clear();
    this.colDimension.clear();
    this.refresh();
  };

  /**
   * Update names of neurons in connectivity widget.
   */
  ConnectivityMatrixWidget.prototype.updateNeuronNames = function() {
    this.refresh();
  };

  /**
   * Refresh the UI.
   */
  ConnectivityMatrixWidget.prototype.refresh = function(container) {
    if (!this.matrix) {
      return;
    }

    // Clrear container
    var $content = $(this.content);
    $content.empty();

    var nRows = this.rowDimension.orderedSkeletonIDs.length;
    var nCols = this.colDimension.orderedSkeletonIDs.length;

    // If there are now row or column skeletons, display a message and return
    if (0 === nRows && 0 === nCols) {
      this.content.dataset.msg = "Please append row and column skeletons";
      return;
    } else if (0 === nRows) {
      this.content.dataset.msg = "Please append row skeletons, " + nCols +
          " column skeletons are already available.";
      return;
    } else if (0 === nCols) {
      this.content.dataset.msg = "Please append column skeletons, " + nRows +
          " row skeletons are already available.";
      return;
    } else {
      this.content.dataset.msg = "Please wait, connectivity information is retrieved.";
    }

    // Update connectivity matrix and make sure all currently looked at
    // skeletons are known to the neuron name service.
    var nns = NeuronNameService.getInstance();
    this.matrix.setRowSkeletonIDs(this.rowDimension.orderedSkeletonIDs);
    this.matrix.setColumnSkeletonIDs(this.colDimension.orderedSkeletonIDs);
    this.matrix.refresh()
      .then(nns.registerAll.bind(nns, this, this.rowDimension.getSelectedSkeletonModels()))
      .then(nns.registerAll.bind(nns, this, this.colDimension.getSelectedSkeletonModels()))
      .then((function() {
        // Clear any message
        if (this.content.dataset.msg) delete this.content.dataset.msg;

        var m = this.matrix.get();
        // Create table representation for connectivity matrix
        var table = document.createElement('table');
        table.setAttribute('class', 'partner_table');
        // Add column header, prepend one blank cell for row headers
        var colHeader = table.appendChild(document.createElement('tr'));
        colHeader.appendChild(document.createElement('th'));
        for (var c=0; c<nCols; ++c) {
          var th = document.createElement('th');
          th.appendChild(document.createTextNode(nns.getName(
                this.colDimension.orderedSkeletonIDs[c])));
          th.setAttribute('colspan', 2);
          colHeader.appendChild(th);
        }
        // Add row headers and connectivity matrix rows
        for (var r=0; r<nRows; ++r) {
          var rowSkid = this.rowDimension.orderedSkeletonIDs[r];
          var row = document.createElement('tr');
          table.appendChild(row);
          var th = document.createElement('th');
          th.appendChild(document.createTextNode(nns.getName(rowSkid)));
          row.appendChild(th);
          for (var c=0; c<nCols; ++c) {
            var colSkid = this.colDimension.orderedSkeletonIDs[c];
            var connections = m[r][c];
            var tdIn = createSynapseCountCell(rowSkid, colSkid, connections[0]);
            var tdOut = createSynapseCountCell(colSkid, rowSkid, connections[1]);
            row.appendChild(tdIn);
            row.appendChild(tdOut);
          }
        }
        $content.append(table);

        // Add a handler for openening connector selections for individual partners
        $('a[partnerID]', table).click(function () {
          var sourceID = $(this).attr('sourceID');
          var partnerID = $(this).attr('partnerID');
          if (sourceID && partnerID) {
            ConnectorSelection.show_shared_connectors(sourceID, [partnerID],
               "postsynaptic_to");
          } else {
            CATMAID.error("Could not find partner or source ID!");
          }

          return true;
        });
      }).bind(this));
  };

  /**
   * Create a synapse count table cell.
   */
  function createSynapseCountCell(sourceID, partnerID, count) {
    var td = document.createElement('td');
    td.setAttribute('class', 'syncount');
    if (count > 0) {
      // Create a links that will open a connector selection when clicked. The
      // handler to do this is created separate to only require one handler.
      var a = document.createElement('a');
      td.appendChild(a);
      a.appendChild(document.createTextNode(count));
      a.setAttribute('href', '#');
      a.setAttribute('sourceID', sourceID);
      a.setAttribute('partnerID', partnerID);
    } else {
      // Make a hidden span including the zero for semantic clarity and table exports.
      var s = document.createElement('span');
      td.appendChild(s);
      s.appendChild(document.createTextNode(count));
      s.style.display = 'none';
    }
    return td;
  }

})(CATMAID);
<commit_msg>Connectivity matrix: factor table redrawing into own method<commit_after>/* -*- mode: espresso; espresso-indent-level: 2; indent-tabs-mode: nil -*- */
/* vim: set softtabstop=2 shiftwidth=2 tabstop=2 expandtab: */

(function(CATMAID) {

  "use strict";

  var ConnectivityMatrixWidget = function() {
    this.widgetID = this.registerInstance();
    this.matrix = new CATMAID.ConnectivityMatrix();
    this.rowDimension = new CATMAID.BasicSkeletonSource(this.getName() + " Rows");
    this.colDimension = new CATMAID.BasicSkeletonSource(this.getName() + " Columns");
  };

  ConnectivityMatrixWidget.prototype = {};
  $.extend(ConnectivityMatrixWidget.prototype, new InstanceRegistry());

  // Make connectivity matrix widget available in CATMAID namespace
  CATMAID.ConnectivityMatrixWidget = ConnectivityMatrixWidget;

  /* Implement interfaces */

  ConnectivityMatrixWidget.prototype.getName = function()
  {
    return "Connectivity Matrix " + this.widgetID;
  };

  /**
   * Handle destruction of widget.
   */
  ConnectivityMatrixWidget.prototype.destroy = function() {
    NeuronNameService.getInstance().unregister(this);
    this.content = null;
    this.rowDimension.destroy();
    this.colDimension.destroy();
    this.unregisterInstance();
  };

  /* Non-interface methods */

  /**
   * Create an object with all relevant information for creating a CATMAID
   * widget. All methods can expect to be executed in the context of this
   * object.
   */
  ConnectivityMatrixWidget.prototype.getWidgetConfiguration = function() {
    return {
      class: 'connectivity_matrix',
      controlsID: 'connectivity_matrix_controls' + this.widgetID,
      contentID: 'connectivity_matrix' + this.widgetID,

      /**
       * Create widget controls.
       */
      createControls: function(controls) {
        // Create hidden select elements for row and column sources
        var rowSelect = CATMAID.skeletonListSources.createSelect(this.rowDimension);
        rowSelect.style.display = 'none';
        controls.appendChild(rowSelect);
        var colSelect = CATMAID.skeletonListSources.createSelect(this.colDimension);
        colSelect.style.display = 'none';
        controls.appendChild(colSelect);

        // This UI combines two skeleton source selects into one.
        controls.appendChild(document.createTextNode('From'));
        var sourceSelect = CATMAID.skeletonListSources.createSelect(this,
           [this.rowDimension.getName(), this.colDimension.getName()]);
        controls.appendChild(sourceSelect);
        sourceSelect.onchange = function() {
          rowSelect.value = this.value;
          colSelect.value = this.value;
        };

        /**
         * Load rows and/or coulmns and refresh.
         */
        var loadWith = function(withRows, withCols) {
          if (withRows) this.rowDimension.loadSource();
          if (withCols) this.colDimension.loadSource();
          if (withRows || withCols) this.update();
        };

        var loadRows = document.createElement('input');
        loadRows.setAttribute("type", "button");
        loadRows.setAttribute("value", "Append rows");
        loadRows.onclick = loadWith.bind(this, true, false);
        controls.appendChild(loadRows);

        var loadColumns = document.createElement('input');
        loadColumns.setAttribute("type", "button");
        loadColumns.setAttribute("value", "Append columns");
        loadColumns.onclick = loadWith.bind(this, false, true);
        controls.appendChild(loadColumns);

        var loadAll = document.createElement('input');
        loadAll.setAttribute("type", "button");
        loadAll.setAttribute("value", "Append to both");
        loadAll.onclick = loadWith.bind(this, true, true);
        controls.appendChild(loadAll);

        var clear = document.createElement('input');
        clear.setAttribute("type", "button");
        clear.setAttribute("value", "Clear");
        clear.onclick = (function() {
          if (confirm("Do you really want to clear the current selection?")) {
            this.clear();
          }
        }).bind(this);
        controls.appendChild(clear);

        var update = document.createElement('input');
        update.setAttribute("type", "button");
        update.setAttribute("value", "Refresh");
        update.onclick = this.update.bind(this);
        controls.appendChild(update);
      },

      /**
       * Create widget content.
       */
      createContent: function(container) {
        this.content = container;
        this.update();
      }
    };
  };

  /**
   * Clear all sources.
   */
  ConnectivityMatrixWidget.prototype.clear = function() {
    this.rowDimension.clear();
    this.colDimension.clear();
    this.update();
  };

  /**
   * Update names of neurons in connectivity widget.
   */
  ConnectivityMatrixWidget.prototype.updateNeuronNames = function() {
    this.refresh();
  };

  /**
   * Refresh the UI without recreating the connectivity matrix.
   */
  ConnectivityMatrixWidget.prototype.refresh = function(container) {
    // Clrear container and add new table
    $(this.content).empty();
    this.addConnectivityMatrixTable(this.matrix, this.content);
  };

  /**
   * Recreate the connectivity matrix and refresh the UI.
   */
  ConnectivityMatrixWidget.prototype.update = function(container) {
    if (!this.matrix) {
      return;
    }

    // Clrear container
    var $content = $(this.content);
    $content.empty();

    var nRows = this.rowDimension.orderedSkeletonIDs.length;
    var nCols = this.colDimension.orderedSkeletonIDs.length;

    // If there are now row or column skeletons, display a message and return
    if (0 === nRows && 0 === nCols) {
      this.content.dataset.msg = "Please append row and column skeletons";
      return;
    } else if (0 === nRows) {
      this.content.dataset.msg = "Please append row skeletons, " + nCols +
          " column skeletons are already available.";
      return;
    } else if (0 === nCols) {
      this.content.dataset.msg = "Please append column skeletons, " + nRows +
          " row skeletons are already available.";
      return;
    } else {
      this.content.dataset.msg = "Please wait, connectivity information is retrieved.";
    }

    // Update connectivity matrix and make sure all currently looked at
    // skeletons are known to the neuron name service.
    var nns = NeuronNameService.getInstance();
    this.matrix.setRowSkeletonIDs(this.rowDimension.orderedSkeletonIDs);
    this.matrix.setColumnSkeletonIDs(this.colDimension.orderedSkeletonIDs);
    this.matrix.refresh()
      .then(nns.registerAll.bind(nns, this, this.rowDimension.getSelectedSkeletonModels()))
      .then(nns.registerAll.bind(nns, this, this.colDimension.getSelectedSkeletonModels()))
      .then((function() {
        // Clear any message
        if (this.content.dataset.msg) delete this.content.dataset.msg;
        // Create table
        this.addConnectivityMatrixTable(this.matrix, this.content);
      }).bind(this));
  };

  /**
   * Add a tabular representation of the connectivity matrix to the given DOM
   * element.
   *
   * @param {ConnectivityMatrix} The connectivity matrix to add.
   * @param {DOMElement} The element to add the table to.
   * @returns the content element passed in.
   */
  ConnectivityMatrixWidget.prototype.addConnectivityMatrixTable = function(
      matrix, content) {
    var nRows = matrix.getNumberOfRows();
    var nCols = matrix.getNumberOfColumns();
    if (0 === nRows || 0 === nCols) {
      return;
    }

    var m = matrix.get();
    var nns = NeuronNameService.getInstance();

    // Create table representation for connectivity matrix
    var table = document.createElement('table');
    table.setAttribute('class', 'partner_table');
    // Add column header, prepend one blank cell for row headers
    var colHeader = table.appendChild(document.createElement('tr'));
    colHeader.appendChild(document.createElement('th'));
    for (var c=0; c<nCols; ++c) {
      var th = document.createElement('th');
      th.appendChild(document.createTextNode(nns.getName(
            this.colDimension.orderedSkeletonIDs[c])));
      th.setAttribute('colspan', 2);
      colHeader.appendChild(th);
    }
    // Add row headers and connectivity matrix rows
    for (var r=0; r<nRows; ++r) {
      var rowSkid = this.rowDimension.orderedSkeletonIDs[r];
      var row = document.createElement('tr');
      table.appendChild(row);
      var th = document.createElement('th');
      th.appendChild(document.createTextNode(nns.getName(rowSkid)));
      row.appendChild(th);
      for (var c=0; c<nCols; ++c) {
        var colSkid = this.colDimension.orderedSkeletonIDs[c];
        var connections = m[r][c];
        var tdIn = createSynapseCountCell(rowSkid, colSkid, connections[0]);
        var tdOut = createSynapseCountCell(colSkid, rowSkid, connections[1]);
        row.appendChild(tdIn);
        row.appendChild(tdOut);
      }
    }
    content.appendChild(table);

    // Add a handler for openening connector selections for individual partners
    $('a[partnerID]', table).click(function () {
      var sourceID = $(this).attr('sourceID');
      var partnerID = $(this).attr('partnerID');
      if (sourceID && partnerID) {
        ConnectorSelection.show_shared_connectors(sourceID, [partnerID],
           "postsynaptic_to");
      } else {
        CATMAID.error("Could not find partner or source ID!");
      }

      return true;
    });

    return content;
  };

  /**
   * Create a synapse count table cell.
   */
  function createSynapseCountCell(sourceID, partnerID, count) {
    var td = document.createElement('td');
    td.setAttribute('class', 'syncount');
    if (count > 0) {
      // Create a links that will open a connector selection when clicked. The
      // handler to do this is created separate to only require one handler.
      var a = document.createElement('a');
      td.appendChild(a);
      a.appendChild(document.createTextNode(count));
      a.setAttribute('href', '#');
      a.setAttribute('sourceID', sourceID);
      a.setAttribute('partnerID', partnerID);
    } else {
      // Make a hidden span including the zero for semantic clarity and table exports.
      var s = document.createElement('span');
      td.appendChild(s);
      s.appendChild(document.createTextNode(count));
      s.style.display = 'none';
    }
    return td;
  }

})(CATMAID);
<|endoftext|>


<commit_before>/* eslint comma-dangle: 0 */

// Thanks to www.fantasynamegenerators.com for some tips

const Names = {};
const RG = require('../src/rg.js');

Names.place = {
    dungeon: [
        'Crypt', 'Catacombs', 'Tombs',
        'Dungeon', 'Cave', 'Grotto', 'Cavern',
        'Burrows',
        'Delves',
        'Haunt', 'Point',
        'Vault', 'Lair', 'Tunnels', 'Cells', 'Pits',
        'Labyrinth', 'Maze'
    ],

    mountain: [
        'Summit', 'Volcano', 'Tops', 'Peaks',
        'Bluff', 'Highlands', 'Pinnacle', 'Rise', 'Needle', 'Hills',
        'Slopes'
    ],

    face: [
        'Face', 'Buttress', 'Ridge', 'Shoulder'
    ],

    forest: [
        'Grove', 'Wilds', 'Woodlands', 'Timberland', 'Forest', 'Covert',
        'Woods', 'Thicket', 'Glade',
    ],

    city: [

    ],

    lake: [
        'Basin', 'Cove', 'Reservoir', 'Depths', 'Gorge', 'Lagoon', 'Domain',
        'Pond', 'Expanse', 'Lake', 'Shallows', 'Loch', 'Falls', 'Rapids',
    ],

    quarter: [
        'Plaza', 'Garden', 'Row', 'Works', 'Side', 'Market', 'Acre', 'Bazaar',
    ],

};

Names.actor = {

};

Names.item = {

};

Names.getRandPlaceName = (type) => {
    const arr = Names.place[type];
    return RG.RAND.arrayGetRand(arr);
};

module.exports = Names;

<commit_msg>Created places.generic and places.unique.<commit_after>/* eslint comma-dangle: 0 */

// Thanks to www.fantasynamegenerators.com for some tips

const Names = {};
const RG = require('../src/rg.js');

// There are two kinds of names:
// 1. Generic ones such as Dungeon, City, Town, Vault etc.
// 2. Unique ones such as Everhold or Ebonfell.

/* As the whole purpose of this module is to generate random names, each
 * function will return randomly picked values of course.
 */

Names.place = {};

/* Generic place names are placed here. */
Names.place.generic = {
    branch: [
        'Hand', 'Foot', 'Small', 'Large'
    ],
    dungeon: [
        'Crypt', 'Catacombs', 'Tombs',
        'Dungeon', 'Cave', 'Grotto', 'Cavern',
        'Burrows',
        'Delves',
        'Haunt', 'Point',
        'Vault', 'Lair', 'Tunnels', 'Cells', 'Pits',
        'Labyrinth', 'Maze'
    ],

    mountain: [
        'Summit', 'Volcano', 'Tops', 'Peaks',
        'Bluff', 'Highlands', 'Pinnacle', 'Rise', 'Needle', 'Hills',
        'Slopes'
    ],

    face: [
        'Face', 'Buttress', 'Ridge', 'Shoulder', 'Crag', 'Crest', 'Brink',
        'Cairn', 'Col', 'Pass', 'Crown', 'Scree', 'Watershed'
    ],

    forest: [
        'Grove', 'Wilds', 'Woodlands', 'Timberland', 'Forest', 'Covert',
        'Woods', 'Thicket', 'Glade',
    ],

    city: ['Town', 'Keep', 'Fort', 'Fortress', 'Town', 'Village', 'Township',
        'Guard', 'Capital'
    ],
    lake: [
        'Basin', 'Cove', 'Reservoir', 'Depths', 'Gorge', 'Lagoon', 'Domain',
        'Pond', 'Expanse', 'Lake', 'Shallows', 'Loch', 'Falls', 'Rapids',
    ],

    quarter: [
        'Plaza', 'Garden', 'Row', 'Works', 'Side', 'Market', 'Acre', 'Bazaar',
    ],

};

Names.place.unique = {
    city: {
        first: [
            'Stag', 'Small', 'Mud', 'Ebon', 'Silk', 'Spirit', 'Basin',
            'Shadow', 'Gold', 'Snow', 'Frost', 'Ice', 'Hound', 'Moon',
            'Dire', 'Ever', 'Iron', 'Ruby', 'Star', 'Crystal', 'Glimmer',
            'Winters', 'Raven', 'Pine', 'Ever', 'Never'
        ],
        second: [
            'guard', 'point', 'fell', 'mire', 'shield', 'crest', 'yard',
            'minster', 'swallow', 'grasp', 'cliff', 'cross', 'host', 'barrow',
            'vein', 'view', 'home'
        ]
    },
};

Names.actor = {

};

Names.item = {

};

Names.getUniqueCityName = () => {
    const first = RG.RAND.arrayGetRand(Names.place.unique.city.first);
    const second = RG.RAND.arrayGetRand(Names.place.unique.city.second);
    return first + second;
};

Names.getGenericPlaceName = (type) => {
    const arr = Names.place.generic[type];
    return RG.RAND.arrayGetRand(arr);
};

module.exports = Names;

<|endoftext|>


<commit_before>/* @flow */
import type { CreateTemplate } from '../../types';

module.exports = (createTemplate: CreateTemplate) => createTemplate`
/* @flow */

/** DO NOT MODIFY **/
import React, { Component } from "react";
import { render } from "react-dom";
import { Root, getHttpClient } from "gluestick-shared";
import originalMatch from "react-router/lib/match";
import browserHistory from "react-router/lib/browserHistory";

// This function is called only on client.
const start = (
  getRoutes,
  getStore,
  { rootWrappers } = {},
  match = originalMatch,
  history = browserHistory
) => {
  // Allow developers to include code that will be executed before the app is
  // set up in the browser.
  require("config/init.browser");

  const httpClient = getHttpClient(/*config.httpClient*/);
  const store = getStore(httpClient);
  match({ history, routes: getRoutes(store, httpClient) }, (error, redirectLocation, renderProps) => {
    const entry = (
      <EntryWrapper
        radiumConfig={{userAgent: window.navigator.userAgent}}
        store={store}
        getRoutes={getRoutes}
        httpClient={httpClient}
        rootWrappers={rootWrappers}
        {...renderProps}
      />
    );
    render(entry, document.getElementById("main"));
  });
};

export default class EntryWrapper extends Component {
  static start = start;
  static defaultProps = {
    rootWrappers: [],
  }

  render () {
    const {
      routerContext,
      getRoutes,
      radiumConfig,
      store,
      httpClient,
      rootWrappers,
      rootWrappersOptions,
    } = this.props;

    return rootWrappers.reduce((prev, curr) => {
      return curr(prev, rootWrappersOptions);
    }, (
      <Root
        routerContext={routerContext}
        routes={getRoutes(store, httpClient)}
        store={store}
      />
    ));
  }
}
`;
<commit_msg>pass root wrapper otption on client<commit_after>/* @flow */
import type { CreateTemplate } from '../../types';

module.exports = (createTemplate: CreateTemplate) => createTemplate`
/* @flow */

/** DO NOT MODIFY **/
import React, { Component } from "react";
import { render } from "react-dom";
import { Root, getHttpClient } from "gluestick-shared";
import originalMatch from "react-router/lib/match";
import browserHistory from "react-router/lib/browserHistory";

// This function is called only on client.
const start = (
  getRoutes,
  getStore,
  { rootWrappers, rootWrappersOptions } = {},
  match = originalMatch,
  history = browserHistory
) => {
  // Allow developers to include code that will be executed before the app is
  // set up in the browser.
  require("config/init.browser");

  const httpClient = getHttpClient(/*config.httpClient*/);
  const store = getStore(httpClient);
  match({ history, routes: getRoutes(store, httpClient) }, (error, redirectLocation, renderProps) => {
    const entry = (
      <EntryWrapper
        radiumConfig={{userAgent: window.navigator.userAgent}}
        store={store}
        getRoutes={getRoutes}
        httpClient={httpClient}
        rootWrappers={rootWrappers}
        rootWrappersOptions={{
          userAgent: window.navigator.userAgent,
          ...rootWrappersOptions
        }}
        {...renderProps}
      />
    );
    render(entry, document.getElementById("main"));
  });
};

export default class EntryWrapper extends Component {
  static start = start;
  static defaultProps = {
    rootWrappers: [],
  }

  render () {
    const {
      routerContext,
      getRoutes,
      radiumConfig,
      store,
      httpClient,
      rootWrappers,
      rootWrappersOptions,
    } = this.props;

    return rootWrappers.reduce((prev, curr) => {
      return curr(prev, rootWrappersOptions);
    }, (
      <Root
        routerContext={routerContext}
        routes={getRoutes(store, httpClient)}
        store={store}
      />
    ));
  }
}
`;
<|endoftext|>


<commit_before>angular.module('gettext').directive('translate', function (gettextCatalog, $interpolate, $parse) {
    /**
     * Trim fallback for old browsers(instead of jQuery)
     * Based on AngularJS-v1.2.2 (angular.js#620)
     */
    var trim = (function () {
        if (!String.prototype.trim) {
            return function (value) {
                return (typeof value === 'string') ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
            };
        }
        return function (value) {
            return (typeof value === 'string') ? value.trim() : value;
        };
    })();

    return {
        transclude: 'element',
        priority: 499,
        compile: function (element, attrs, transclude) {
            return function ($scope, $element) {
                // Validate attributes
                var assert = function (condition, missing, found) {
                    if (!condition) {
                        throw new Error("You should add a " + missing + " attribute whenever you add a " + found + " attribute.");
                    }
                };

                assert(!attrs.translatePlural || attrs.translateN, 'translate-n', 'translate-plural');
                assert(!attrs.translateN || attrs.translatePlural, 'translate-plural', 'translate-n');
                assert(!attrs.ngIf, 'ng-if', 'translate');
                assert(!attrs.ngSwitchWhen, 'ng-switch-when', 'translate');

                var countFn = $parse(attrs.translateN);

                transclude($scope, function (clone) {
                    var input = trim(clone.html());
                    clone.removeAttr('translate');
                    $element.replaceWith(clone);

                    return $scope.$watch(function () {
                        var prev = clone.html();

                        // Fetch correct translated string.
                        var translated;
                        if (attrs.translatePlural) {
                            translated = gettextCatalog.getPlural(countFn($scope), input, attrs.translatePlural);
                        } else {
                            translated = gettextCatalog.getString(input);
                        }

                        // Interpolate with scope.
                        var interpolated = $interpolate(translated)($scope);
                        if (prev === interpolated) {
                            return; // Skip DOM change.
                        }

                        return clone.html(interpolated);
                    });
                });
            };
        }
    };
});
<commit_msg>translated strings are compiled<commit_after>angular.module('gettext').directive('translate', function (gettextCatalog, $interpolate, $parse, $compile) {
    /**
     * Trim fallback for old browsers(instead of jQuery)
     * Based on AngularJS-v1.2.2 (angular.js#620)
     */
    var trim = (function () {
        if (!String.prototype.trim) {
            return function (value) {
                return (typeof value === 'string') ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
            };
        }
        return function (value) {
            return (typeof value === 'string') ? value.trim() : value;
        };
    })();

    return {
        transclude: 'element',
        priority: 499,
        compile: function (element, attrs, transclude) {
            return function ($scope, $element) {
                // Validate attributes
                var assert = function (condition, missing, found) {
                    if (!condition) {
                        throw new Error("You should add a " + missing + " attribute whenever you add a " + found + " attribute.");
                    }
                };

                assert(!attrs.translatePlural || attrs.translateN, 'translate-n', 'translate-plural');
                assert(!attrs.translateN || attrs.translatePlural, 'translate-plural', 'translate-n');
                assert(!attrs.ngIf, 'ng-if', 'translate');
                assert(!attrs.ngSwitchWhen, 'ng-switch-when', 'translate');

                var countFn = $parse(attrs.translateN);

                transclude($scope, function (clone) {
                    var input = trim(clone.html());
                    clone.removeAttr('translate');
                    $element.replaceWith(clone);

                    return $scope.$watch(function () {
                        var prev = clone.html();

                        // Fetch correct translated string.
                        var translated;
                        if (attrs.translatePlural) {
                            translated = gettextCatalog.getPlural(countFn($scope), input, attrs.translatePlural);
                        } else {
                            translated = gettextCatalog.getString(input);
                        }

                        // Interpolate with scope.
                        var interpolated = $interpolate(translated)($scope);
                        if (prev === interpolated) {
                            return; // Skip DOM change.
                        }
                        clone.html(interpolated);
                        $compile(clone.contents())($scope);
                        return clone;

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


<commit_before>Template.search.events({
	'input #searchBox > input': function(e, templateInstance) {
		e.preventDefault();
		var searchString = templateInstance.find("#searchInput").value;
		Session.set('searchResults', Meteor.users.find({
			username: new RegExp('^' + searchString + '.*$')
		}).fetch());
	}
})<commit_msg>Improving search logic.<commit_after>Template.search.events({
	'input #searchBox > input': function(e, templateInstance) {
		e.preventDefault();
		var searchString = templateInstance.find("#searchInput").value;

		if (searchString) {
			Session.set('searchResults', Meteor.users.find({
				username: new RegExp("^" + searchString + '.*$')
			}).fetch());
		} else {
			Session.set('searchResults', []);
		}
	}
})<|endoftext|>


<commit_before>/* Javascript for PollBlock. */

function PollUtil (runtime, element, pollType) {
    var self = this;

    this.init = function() {
        console.log("this init");
        // Initialization function used for both Poll Types
        this.voteUrl = runtime.handlerUrl(element, 'vote');
        console.log("1");
        this.tallyURL = runtime.handlerUrl(element, 'get_results');
        console.log("2");

        this.submit = $('input[type=button]', element);
        console.log("3");

        this.checkAnswers = $('input[type=checkbox]', element); //get the array of checkboxes
        console.log("4");

        this.resultsTemplate = Handlebars.compile($("#" + pollType + "-results-template", element).html());  //modify handlebar!!
        console.log("5");
        this.viewResultsButton = $('.view-results-button', element);
        console.log("6");
        this.viewResultsButton.click(this.getResults);
        console.log("7");
        // If the submit button doesn't exist, the user has alread
        // selected a choice. Render results instead of initializing machinery.
        if (! self.submit.length) {
            self.onSubmit({'success': true});
            return false;
        }
        console.log("8");
        var max_submissions = parseInt($('.poll-max-submissions', element).text());
        console.log("9");
        var current_count = parseInt($('.poll-current-count', element).text());
        console.log("10");
        if (max_submissions > 1 && current_count > 0) {
            $('.poll-submissions-count', element).show();
        }
        console.log("11");
        return true;
    };

    this.checkPollInit = function(){
        console.log("checkpollInit");
        // Initialization function for Survey Blocks

        // If the user is unable to vote, disable input.
        if (! $('div.poll-block', element).data('can-vote')) {
            $('input', element).attr('disabled', true);
            return
        }

        console.log("verify all");
        self.checkAnswers.bind("change.enableSubmit", self.verifyAll);

        self.submit.click(function () {
            $.ajax({
                type: "POST",
                url: self.voteUrl,
                data: JSON.stringify(self.checkPollChoices()),
                success: self.onSubmit
            })
        });
        // If the user has refreshed the page, they may still have an answer
        // selected and the submit button should be enabled.
        self.verifyAll();
    };

    this.checkPollChoices = function () {
        console.log("checkpollChoices");
        var choices = [];
        self.checkAnswers.each(function(index, el) {
            if (el.checked) {
                el = $(el);
                choices.push(el.val()); //maybe element is needed
            }
        });
        return choices;
    };

    this.checkedElement = function (el) {
        console.log("checked element");
        // Given the DOM element of a radio, get the selector for the checked element
        // with the same name.
        return "input[name='" + el.prop('name') + "']:checked"
    };

    this.verifyAll = function () {
        console.log("verify all");
        // Verify that all questions have an answer selected.
        var doEnable = true;

        //seems that this function should be the same
        self.checkAnswers.each(function (index, el) {
            var temp = [];
            if (el.checked) {
                el = $(el);
                temp.push(el.val()); //maybe element is needed
            }

            if (! temp.length) {
                doEnable = false;
                return false
            }
        });

        if (doEnable){
            self.enableSubmit();
        }
    };

    this.onSubmit = function (data) {
        console.log("on submit");
        // Fetch the results from the server and render them.
        if (!data['success']) {
            alert(data['errors'].join('\n'));
        }
        var can_vote = data['can_vote'];
        $('.poll-current-count', element).text(data['submissions_count']);
        if (data['max_submissions'] > 1) {
            $('.poll-submissions-count', element).show();
        }
        if ($('div.poll-block', element).data('private')) {
            // User may be changing their vote. Give visual feedback that it was accepted.
            var thanks = $('.poll-voting-thanks', element);
            thanks.removeClass('poll-hidden');
            thanks.fadeOut(0).fadeIn('slow', 'swing');
            $('.poll-feedback-container', element).removeClass('poll-hidden');
            if (can_vote) {
                $('input[name="poll-submit"]', element).val('Resubmit');
            } else {
                $('input', element).attr('disabled', true)
            }
            return;
        }
        // Used if results are not private, to show the user how other students voted.
        self.getResults();
    };

    this.getResults = function () {
        console.log("get rsults");
        // Used if results are not private, to show the user how other students voted.
        $.ajax({
            // Semantically, this would be better as GET, but we can use helper
            // functions with POST.
            type: "POST",
            url: self.tallyURL,
            data: JSON.stringify({}),
            success: function (data) {
                $('div.poll-block', element).html(self.resultsTemplate(data));
            }
        })
    };

    this.enableSubmit = function () {
        console.log("enable submit");
        // Enable the submit button.
        self.submit.removeAttr("disabled");
        self.checkAnswers.unbind("change.enableSubmit");  //need to add checkANSWES
    };

    var run_init = this.init();
    if (run_init) {
        console.log("run init");
        var init_map = {'poll': self.pollInit, 'survey': self.surveyInit, 'checkpoll': self.checkPollInit()};
        init_map[pollType]()
    }

}

function CheckPollBlock(runtime, element) {
    new PollUtil(runtime, element, 'checkpoll');
}

function PollBlock(runtime, element) {
    new PollUtil(runtime, element, 'poll');
}

function SurveyBlock(runtime, element) {
    new PollUtil(runtime, element, 'survey');
}
<commit_msg>strange debug<commit_after>/* Javascript for PollBlock. */

function PollUtil (runtime, element, pollType) {
    var self = this;

    this.init = function() {
        console.log("this init");
        // Initialization function used for both Poll Types
        this.voteUrl = runtime.handlerUrl(element, 'vote');
        console.log("1");
        this.tallyURL = runtime.handlerUrl(element, 'get_results');
        console.log("2");

        this.submit = $('input[type=button]', element);
        console.log("3");

        this.checkAnswers = $('input[type=checkbox]', element); //get the array of checkboxes
        console.log("4");

        this.resultsTemplate = Handlebars.compile($("#" + pollType + "-results-template", element).html());  //modify handlebar!!
        console.log("5");
        this.viewResultsButton = $('.view-results-button', element);
        console.log("6");
        this.viewResultsButton.click(this.getResults);
        console.log("7");
        // If the submit button doesn't exist, the user has alread
        // selected a choice. Render results instead of initializing machinery.
        if (! self.submit.length) {
            self.onSubmit({'success': true});
            return false;
        }
        console.log("8");
        var max_submissions = parseInt($('.poll-max-submissions', element).text());
        console.log("9");
        var current_count = parseInt($('.poll-current-count', element).text());
        console.log("10");
        if (max_submissions > 1 && current_count > 0) {
            $('.poll-submissions-count', element).show();
        }
        console.log("11");
        return true;
    };

    this.checkPollInit = function(){
        console.log("checkpollInit");
        // Initialization function for Survey Blocks

        // If the user is unable to vote, disable input.
        if (! $('div.poll-block', element).data('can-vote')) {
            $('input', element).attr('disabled', true);
            return
        }

        console.log("verify all");
        self.checkAnswers.bind("change.enableSubmit", self.verifyAll);

        self.submit.click(function () {
            $.ajax({
                type: "POST",
                url: self.voteUrl,
                data: JSON.stringify(self.checkPollChoices()),
                success: self.onSubmit
            })
        });
        // If the user has refreshed the page, they may still have an answer
        // selected and the submit button should be enabled.
        self.verifyAll();
    };

    this.checkPollChoices = function () {
        console.log("checkpollChoices");
        var choices = [];
        self.checkAnswers.each(function(index, el) {
            if (el.checked) {
                el = $(el);
                choices.push(el.val()); //maybe element is needed
            }
        });
        return choices;
    };

    this.checkedElement = function (el) {
        console.log("checked element");
        // Given the DOM element of a radio, get the selector for the checked element
        // with the same name.
        return "input[name='" + el.prop('name') + "']:checked"
    };

    this.verifyAll = function () {
        console.log("verify all");
        // Verify that all questions have an answer selected.
        var doEnable = true;

        //seems that this function should be the same
        self.checkAnswers.each(function (index, el) {
            var temp = [];
            if (el.checked) {
                el = $(el);
                temp.push(el.val()); //maybe element is needed
            }

            if (! temp.length) {
                doEnable = false;
                return false
            }
        });

        if (doEnable){
            self.enableSubmit();
        }
    };

    this.onSubmit = function (data) {
        console.log("on submit");
        // Fetch the results from the server and render them.
        if (!data['success']) {
            alert(data['errors'].join('\n'));
        }
        var can_vote = data['can_vote'];
        $('.poll-current-count', element).text(data['submissions_count']);
        if (data['max_submissions'] > 1) {
            $('.poll-submissions-count', element).show();
        }
        if ($('div.poll-block', element).data('private')) {
            // User may be changing their vote. Give visual feedback that it was accepted.
            var thanks = $('.poll-voting-thanks', element);
            thanks.removeClass('poll-hidden');
            thanks.fadeOut(0).fadeIn('slow', 'swing');
            $('.poll-feedback-container', element).removeClass('poll-hidden');
            if (can_vote) {
                $('input[name="poll-submit"]', element).val('Resubmit');
            } else {
                $('input', element).attr('disabled', true)
            }
            return;
        }
        // Used if results are not private, to show the user how other students voted.
        self.getResults();
    };

    this.getResults = function () {
        console.log("get rsults");
        // Used if results are not private, to show the user how other students voted.
        $.ajax({
            // Semantically, this would be better as GET, but we can use helper
            // functions with POST.
            type: "POST",
            url: self.tallyURL,
            data: JSON.stringify({}),
            success: function (data) {
                $('div.poll-block', element).html(self.resultsTemplate(data));
            }
        })
    };

    this.enableSubmit = function () {
        console.log("enable submit");
        // Enable the submit button.
        self.submit.removeAttr("disabled");
        console.log("enable submit remove disabled");
        self.checkAnswers.unbind("change.enableSubmit");  //HERE IS THE BUGGG
    };

    var run_init = this.init();
    if (run_init) {
        console.log("run init");
        var init_map = {'poll': self.pollInit, 'survey': self.surveyInit, 'checkpoll': self.checkPollInit()};
        init_map[pollType]()
    }

}

function CheckPollBlock(runtime, element) {
    new PollUtil(runtime, element, 'checkpoll');
}

function PollBlock(runtime, element) {
    new PollUtil(runtime, element, 'poll');
}

function SurveyBlock(runtime, element) {
    new PollUtil(runtime, element, 'survey');
}
<|endoftext|>


<commit_before>import {
  FETCHING_DATA_QUESTION,
  FETCHING_DATA_QUESTION_SUCCESS,
  FETCHING_DATA_QUESTION_FAILURE,
  CHECKING_ANSWER,
  CHECKING_ANSWER_SUCCESS,
  CHECKING_ANSWER_FAIL,
  CHECKING_ANSWER_ERROR,
  TOOLS_SKIP_QUESTION,
  TOOLS_SKIP_QUESTION_SUCCESS,
  FETCHING_DATA_AWARDS,
  FETCHING_DATA_AWARDS_SUCCESS,
  FETCHING_DATA_AWARDS_ERROR,
  TOOLS_DISPLAY_CARDS,
  TOOLS_CARD_SELECTED,
  TOOLS_CARD_FILTERING,
  TOOLS_STOP_PLAYING,
  SELECT_OPTION,
} from '../actions/actionTypes'

const initialState = {
  question: { id: 0, text: '', options: [] },
  isFetching: false,
  errorMessage: '',
  mustUpdateQuestion: false,

  awards: [],
  currentAwardIndex: 0,
  currentAwardValue: { number: 0, right: 0, stop: 0, wrong: 0, level: 0 },

  skipAttemptsLeft: 3,
  gameOver: false,

  cardsWereUsed: false,
  mustDisplayCards: false,

  selectedOptionNumber: 0,
  hasASelectedOption: false,
}

export function questionReducer(state = initialState, action) {
  switch (action.type) {
    case FETCHING_DATA_QUESTION:
      return {
        ...state,
        question: { id: 0, text: '', options: [] },
        isFetching: true,
        mustUpdateQuestion: false,
        hasASelectedOption: false,
        selectedOptionNumber: 0,
      }
    case FETCHING_DATA_QUESTION_SUCCESS:
      return {
        ...state,
        isFetching: false,
        question: action.data,
        hasASelectedOption: false,
        selectedOptionNumber: 0,
      }
    case FETCHING_DATA_QUESTION_FAILURE:
      return {
        ...state,
        isFetching: false,
        errorMessage: action.error,
        question: { id: 0, text: '', options: [] },
        hasASelectedOption: false,
        selectedOptionNumber: 0,
      }
    case CHECKING_ANSWER:
      return {
        ...state,
        isFetching: true,
      }
    case CHECKING_ANSWER_SUCCESS:
      return {
        ...state,
        mustUpdateQuestion: true,
        currentAwardIndex: state.currentAwardIndex + 1,
        currentAwardValue: state.awards[state.currentAwardIndex + 1],
        isFetching: false,
        hasASelectedOption: false,
        selectedOptionNumber: 0,
      }
    case CHECKING_ANSWER_FAIL:
      return {
        ...state,
        isFetching: false,
        hasASelectedOption: false,
        selectedOptionNumber: 0,
      }
    case CHECKING_ANSWER_ERROR:
      return {
        ...state,
        isFetching: false,
        hasASelectedOption: false,
        selectedOptionNumber: 0,
      }
    case TOOLS_SKIP_QUESTION:
      return {
        ...state,
        isFetching: true,
        hasASelectedOption: false,
        selectedOptionNumber: 0,
      }
    case TOOLS_SKIP_QUESTION_SUCCESS:
      return {
        ...state,
        isFetching: false,
        skipAttemptsLeft: state.skipAttemptsLeft - 1,
        question: action.data,
      }
    case FETCHING_DATA_AWARDS:
      return {
        ...state,
        isFetching: true,
      }
    case FETCHING_DATA_AWARDS_SUCCESS:
      return {
        ...state,
        awards: action.data,
        currentAwardIndex: 0,
        currentAwardValue: action.data[0],
        isFetching: false,
      }
    case FETCHING_DATA_AWARDS_ERROR:
      return {
        ...state,
        awards: [],
        currentAwardValue: { number: 0, right: 0, stop: 0, wrong: 0, level: 0 },
        isFetching: false,
      }
    case TOOLS_DISPLAY_CARDS:
      return {
        ...state,
        mustDisplayCards: !state.cardsWereUsed,
        cardsWereUsed: true,
      }
    case TOOLS_CARD_SELECTED:
      return {
        ...state,
        question: action.data,
        mustDisplayCards: !state.cardsWereUsed,
        isFetching: false,
      }
    case TOOLS_CARD_FILTERING:
      return {
        ...state,
        isFetching: true,
      }
    case TOOLS_STOP_PLAYING:
      return {
        ...state,
        gameOver: true,
      }
    case SELECT_OPTION:
      return {
        ...state,
        selectedOptionNumber: action.data,
        hasASelectedOption: true,
      }
    default:
      return state
  }
}

export default questionReducer
<commit_msg>display cards only when there is a question<commit_after>import {
  FETCHING_DATA_QUESTION,
  FETCHING_DATA_QUESTION_SUCCESS,
  FETCHING_DATA_QUESTION_FAILURE,
  CHECKING_ANSWER,
  CHECKING_ANSWER_SUCCESS,
  CHECKING_ANSWER_FAIL,
  CHECKING_ANSWER_ERROR,
  TOOLS_SKIP_QUESTION,
  TOOLS_SKIP_QUESTION_SUCCESS,
  FETCHING_DATA_AWARDS,
  FETCHING_DATA_AWARDS_SUCCESS,
  FETCHING_DATA_AWARDS_ERROR,
  TOOLS_DISPLAY_CARDS,
  TOOLS_CARD_SELECTED,
  TOOLS_CARD_FILTERING,
  TOOLS_STOP_PLAYING,
  SELECT_OPTION,
} from '../actions/actionTypes'

const initialState = {
  question: { id: 0, text: '', options: [] },
  isFetching: false,
  errorMessage: '',
  mustUpdateQuestion: false,

  awards: [],
  currentAwardIndex: 0,
  currentAwardValue: { number: 0, right: 0, stop: 0, wrong: 0, level: 0 },

  skipAttemptsLeft: 3,
  gameOver: false,

  cardsWereUsed: false,
  mustDisplayCards: false,

  selectedOptionNumber: 0,
  hasASelectedOption: false,
}

export function questionReducer(state = initialState, action) {
  switch (action.type) {
    case FETCHING_DATA_QUESTION:
      return {
        ...state,
        question: { id: 0, text: '', options: [] },
        isFetching: true,
        mustUpdateQuestion: false,
        hasASelectedOption: false,
        selectedOptionNumber: 0,
      }
    case FETCHING_DATA_QUESTION_SUCCESS:
      return {
        ...state,
        isFetching: false,
        question: action.data,
        hasASelectedOption: false,
        selectedOptionNumber: 0,
      }
    case FETCHING_DATA_QUESTION_FAILURE:
      return {
        ...state,
        isFetching: false,
        errorMessage: action.error,
        question: { id: 0, text: '', options: [] },
        hasASelectedOption: false,
        selectedOptionNumber: 0,
      }
    case CHECKING_ANSWER:
      return {
        ...state,
        isFetching: true,
      }
    case CHECKING_ANSWER_SUCCESS:
      return {
        ...state,
        mustUpdateQuestion: true,
        currentAwardIndex: state.currentAwardIndex + 1,
        currentAwardValue: state.awards[state.currentAwardIndex + 1],
        isFetching: false,
        hasASelectedOption: false,
        selectedOptionNumber: 0,
      }
    case CHECKING_ANSWER_FAIL:
      return {
        ...state,
        isFetching: false,
        hasASelectedOption: false,
        selectedOptionNumber: 0,
      }
    case CHECKING_ANSWER_ERROR:
      return {
        ...state,
        isFetching: false,
        hasASelectedOption: false,
        selectedOptionNumber: 0,
      }
    case TOOLS_SKIP_QUESTION:
      return {
        ...state,
        isFetching: true,
        hasASelectedOption: false,
        selectedOptionNumber: 0,
      }
    case TOOLS_SKIP_QUESTION_SUCCESS:
      return {
        ...state,
        isFetching: false,
        skipAttemptsLeft: state.skipAttemptsLeft - 1,
        question: action.data,
      }
    case FETCHING_DATA_AWARDS:
      return {
        ...state,
        isFetching: true,
      }
    case FETCHING_DATA_AWARDS_SUCCESS:
      return {
        ...state,
        awards: action.data,
        currentAwardIndex: 0,
        currentAwardValue: action.data[0],
        isFetching: false,
      }
    case FETCHING_DATA_AWARDS_ERROR:
      return {
        ...state,
        awards: [],
        currentAwardValue: { number: 0, right: 0, stop: 0, wrong: 0, level: 0 },
        isFetching: false,
      }
    case TOOLS_DISPLAY_CARDS:
      return {
        ...state,
        mustDisplayCards: (state.question.id > 0 && !state.cardsWereUsed),
        cardsWereUsed: true,
      }
    case TOOLS_CARD_SELECTED:
      return {
        ...state,
        question: action.data,
        mustDisplayCards: !state.cardsWereUsed,
        isFetching: false,
      }
    case TOOLS_CARD_FILTERING:
      return {
        ...state,
        isFetching: true,
      }
    case TOOLS_STOP_PLAYING:
      return {
        ...state,
        gameOver: true,
      }
    case SELECT_OPTION:
      return {
        ...state,
        selectedOptionNumber: action.data,
        hasASelectedOption: true,
      }
    default:
      return state
  }
}

export default questionReducer
<|endoftext|>